From: Andre Date: Fri, 10 Mar 2006 20:01:50 +0000 (+0100) Subject: rename plm_dbtool.c to playlist_selector.c X-Git-Tag: v0.2.11~17 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=019a4caa2bf9232c7efd84ffe7424994de6358fb;p=paraslash.git rename plm_dbtool.c to playlist_selector.c --- diff --git a/FEATURES b/FEATURES index fbc84290..bad8110d 100644 --- a/FEATURES +++ b/FEATURES @@ -26,7 +26,7 @@ configurable audio file selectors: There are three audio file selectors available: - random - - plm (playlist manager) + - playlist - mysql The first two of these are rather simple, and they are always diff --git a/INSTALL b/INSTALL index 41a45c45..04bf53fd 100644 --- a/INSTALL +++ b/INSTALL @@ -79,7 +79,7 @@ to retrieve the list of available commands and some server info. Choose an audio file selector ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ paraslash has three different audio file selectors: random (default), -plm (the playlist manager) and mysql. +playlist and mysql. The random selector chooses files randomly from the given directory. diff --git a/NEWS b/NEWS index ddaca554..5e7dfa88 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ NEWS o the new ipc subsystem - o new audio file selector: plm, the playlist manager + o new audio file selector: playlist o para_server: the dopey selector is now called "random", and is the default selector. Use the --selector option to diff --git a/README b/README index 95410014..374fcf6e 100644 --- a/README +++ b/README @@ -24,15 +24,15 @@ It contains the following programs: All senders have the same set of commands that allow to control the access permissions of the stream. - para_server needs an "audio file selector" to work, mainly to - determine which song to stream next. There are three selectors - available: random, plm and mysql. The former chooses audio - files randomly and plm, the playlist manager, can handle + para_server needs an "audio file selector" to work, mainly + to determine which song to stream next. There are three + selectors available: random, playlist and mysql. The former + chooses audio files randomly and playlist can handle, well, playlists. Both are always supported. - The (optional) mysql selector connects to a mysql server - which holds information on your audio files. It has several - unusual features, see README.mysql for details. + The optional mysql selector connects to a mysql server which + holds information on your audio files. It has several unusual + features, see README.mysql for details. - para_client (obligatory): diff --git a/configure.ac b/configure.ac index fac1ab57..587e22f8 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,7 @@ audiod_ldflags="" server_cmdline_objs="server.cmdline" server_errlist_objs="server mp3 afs command net string signal random_dbtool time daemon stat - crypt http_send db close_on_fork plm_dbtool ipc" + crypt http_send db close_on_fork playlist_selector ipc" server_ldflags="" ########################################################################### ssl diff --git a/db.h b/db.h index 80c0de89..578e4fd9 100644 --- a/db.h +++ b/db.h @@ -119,6 +119,6 @@ void *private_data; }; int mysql_selector_init(struct audio_file_selector*); -int plm_selector_init(struct audio_file_selector*); +int playlist_selector_init(struct audio_file_selector*); int random_selector_init(struct audio_file_selector*); diff --git a/error.h b/error.h index 98ca4ec6..a753bc45 100644 --- a/error.h +++ b/error.h @@ -23,7 +23,8 @@ enum para_subsystem {SS_RECV, SS_NET, SS_ORTP_RECV, SS_AUDIOD, SS_EXEC, SS_CLOSE_ON_FORK, SS_SIGNAL, SS_STRING, SS_DAEMON, SS_STAT, SS_TIME, SS_GRAB_CLIENT, SS_HTTP_RECV, SS_RECV_COMMON, SS_FILTER_CHAIN, SS_WAV, SS_COMPRESS, SS_OGGDEC, SS_FILTER, - SS_COMMAND, SS_RANDOM_DBTOOL, SS_PLM_DBTOOL, SS_CRYPT, SS_HTTP_SEND, SS_ORTP_SEND, SS_DB, SS_OGG, + SS_COMMAND, SS_RANDOM_DBTOOL, SS_PLAYLIST_SELECTOR, SS_CRYPT, + SS_HTTP_SEND, SS_ORTP_SEND, SS_DB, SS_OGG, SS_MP3, SS_MP3DEC, SS_SERVER, SS_AFS, SS_MYSQL, SS_IPC, SS_RINGBUFFER}; #define NUM_SS (SS_RINGBUFFER + 1) extern const char **para_errlist[]; @@ -224,7 +225,7 @@ extern const char **para_errlist[]; PARA_ERROR(LOCK, "lock error"), \ PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \ -#define PLM_DBTOOL_ERRORS \ +#define PLAYLIST_SELECTOR_ERRORS \ PARA_ERROR(LOAD_PLAYLIST, "failed to load playlist"), \ @@ -343,7 +344,7 @@ SS_ENUM(SERVER); SS_ENUM(AFS); SS_ENUM(COMMAND); SS_ENUM(RANDOM_DBTOOL); -SS_ENUM(PLM_DBTOOL); +SS_ENUM(PLAYLIST_SELECTOR); SS_ENUM(CRYPT); SS_ENUM(HTTP_SEND); SS_ENUM(ORTP_SEND); diff --git a/playlist_selector.c b/playlist_selector.c new file mode 100644 index 00000000..47fb2699 --- /dev/null +++ b/playlist_selector.c @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2006 Andre Noll + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + */ + +/** \file playlist_selector.c The playlist audio file selector of paraslash */ + +#include "server.h" +#include "db.h" +#include "error.h" +#include "net.h" +#include "string.h" +#include "ipc.h" + +/** + * structure used for transmission of the playlist + * + * There's one such struct which gets initialized during startup. It lives in + * shared memory and is used by com_lpl(). + */ +struct pls_client_data { +/** allocated and set by com_lpl() (child) */ + int shm_id; +/** the size of the shared memory area identified by \a shm_id */ + size_t size; +/** initially locked, gets unlocked by parent when it is done */ + int mutex; +/** return value, set by parent */ + int retval; +}; + +/** data specific to the playlist selector */ +struct private_pls_data { +/** guards against concurrent client access */ + int client_mutex; +/** guards against concurrent parent-child access */ + int server_mutex; +/** pointer to the client data */ + struct pls_client_data *client_data; +/** id of the shm corresponding to \a client_data */ + int client_data_shm_id; +}; + +/** we refuse to load playlists bigger than that */ +#define MAX_PLAYLIST_BYTES (1024 * 1024) + +static unsigned playlist_len, playlist_size, current_playlist_entry; +static char **playlist; +static struct audio_file_selector *self; + +static int com_ppl(int, int, char **); +static int com_lpl(int, int, char **); +extern struct misc_meta_data *mmd; + +/* array of commands that are supported by this database tool */ +static struct server_command cmds[] = { +{ +.name = "ppl", +.handler = com_ppl, +.perms = DB_READ, +.description = "print playlist", +.synopsis = "ppl", +.help = +"Print out the current playlist" +}, { +.name = "lpl", +.handler = com_lpl, +.perms = DB_WRITE, +.description = "load playlist", +.synopsis = "lpl", +.help = +"Read a new playlist from stdin. Example:\n" +"\tfind /audio -name '*.mp3' | para_client lpl" +}, { +.name = NULL, +} +}; + +static void playlist_add(char *path) +{ + if (playlist_len >= playlist_size) { + playlist_size = 2 * playlist_size + 1; + playlist = para_realloc(playlist, playlist_size * sizeof(char *)); + } + PARA_DEBUG_LOG("adding #%d/%d: %s\n", playlist_len, playlist_size, path); + playlist[playlist_len++] = para_strdup(path); +} + +static int send_playlist_to_server(const char *buf, size_t size) +{ + struct private_pls_data *ppd = self->private_data; + int ret, shm_mutex = -1, shm_id = -1; + void *shm = NULL; + + PARA_DEBUG_LOG("new playlist (%d bytes)\n", size); + + ret = mutex_new(); + if (ret < 0) + return ret; + shm_mutex = ret; + + ret = shm_new(size); + if (ret < 0) + goto out; + shm_id = ret; + + ret = shm_attach(shm_id, ATTACH_RW, &shm); + if (ret < 0) + goto out; + mutex_lock(shm_mutex); + memcpy(shm, buf, size); + mutex_lock(ppd->client_mutex); + mutex_lock(ppd->server_mutex); + ppd->client_data->size = size; + ppd->client_data->shm_id = shm_id; + ppd->client_data->mutex = shm_mutex; + kill(getppid(), SIGUSR1); /* wake up the server */ + mutex_unlock(ppd->server_mutex); + mutex_lock(shm_mutex); /* wait until server is done */ + mutex_unlock(shm_mutex); + ret = ppd->client_data->retval; + mutex_unlock(ppd->client_mutex); + shm_detach(shm); +out: + if (shm_id >= 0) + shm_destroy(shm_id); + mutex_destroy(shm_mutex); + PARA_DEBUG_LOG("returning %d\n", ret); + return ret; +} + +static int com_lpl(int fd, __unused int argc, __unused char *argv[]) +{ + unsigned loaded = 0; + size_t bufsize = 4096; /* guess that's enough */ + char *buf = para_malloc(bufsize); + ssize_t ret; + ret = send_buffer(fd, AWAITING_DATA_MSG); + if (ret < 0) + goto out; +again: + ret = recv_bin_buffer(fd, buf + loaded, bufsize - loaded); + if (ret < 0) + goto out; + if (!ret) { + ret = send_playlist_to_server(buf, loaded); + goto out; + } + loaded += ret; + ret = -E_LOAD_PLAYLIST; + if (loaded >= MAX_PLAYLIST_BYTES) + goto out; + if (loaded >= bufsize) { + bufsize *= 2; + buf = para_realloc(buf, bufsize); + } + goto again; +out: + free(buf); + return ret; +} + +static int com_ppl(int fd, __unused int argc, __unused char *argv[]) +{ + unsigned i; + + PARA_DEBUG_LOG("sending playlist to client (%d entries)\n", playlist_len); + for (i = 0; i < playlist_len; i++) { + int ret = send_va_buffer(fd, "%s\n", playlist[ + (i + current_playlist_entry) % playlist_len]); + if (ret < 0) + return ret; + } + return 1; +} + +static char **pls_get_audio_file_list(unsigned int num) +{ + char **file_list; + unsigned i; + + num = MIN(num, playlist_len); + if (!num) + return NULL; + file_list = para_malloc((num + 1) * sizeof(char *)); + for (i = 0; i < num; i++) { + unsigned j = (current_playlist_entry + i) % playlist_len; + file_list[i] = para_strdup(playlist[j]); + } + file_list[i] = NULL; + return file_list; +} + +static void free_playlist_contents(void) +{ + int i; + + PARA_DEBUG_LOG("freeing playlist (%d entries)\n", playlist_len); + for (i = 0; i < playlist_len; i++) + free(playlist[i]); + current_playlist_entry = 0; + playlist_len = 0; +} + +static void pls_shutdown(void) +{ + struct private_pls_data *ppd = self->private_data; + + shm_detach(ppd->client_data); + shm_destroy(ppd->client_data_shm_id); + mutex_destroy(ppd->server_mutex); + mutex_destroy(ppd->client_mutex); + free(ppd); + free_playlist_contents(); + free(playlist); + playlist = NULL; + playlist_len = 0; + playlist_size = 0; +} + +static void pls_post_select(__unused fd_set *rfds, __unused fd_set *wfds) +{ + struct private_pls_data *ppd = self->private_data; + struct pls_client_data *pcd = ppd->client_data; + int ret; + void *shm; + + mutex_lock(ppd->server_mutex); + if (!pcd->size) + goto out; + free_playlist_contents(); + ret = shm_attach(pcd->shm_id, ATTACH_RW, &shm); + if (ret < 0) { + PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); + goto out; + } + PARA_DEBUG_LOG("loading new playlist (%d bytes)\n", pcd->size); + ret = for_each_line((char *)shm, pcd->size, &playlist_add); + shm_detach(shm); + PARA_NOTICE_LOG("new playlist (%d entries)\n", playlist_len); + pcd->retval = 1; + pcd->size = 0; + mutex_unlock(pcd->mutex); +out: + mutex_unlock(ppd->server_mutex); +} + +void pls_update_audio_file(char *audio_file) +{ + unsigned i; + + for (i = 0; i < playlist_len; i++) { + unsigned j = (current_playlist_entry + i) % playlist_len; + if (strcmp(playlist[j], audio_file)) + continue; + current_playlist_entry = (j + 1) % playlist_len; + } +} + +/** + * the init function for the playlist selector + * + * Init all function pointers of \a db + * + * \sa struct audio_file_selector, misc_meta_data::dbinfo, mysql.c random_dbtool.c + */ +int playlist_selector_init(struct audio_file_selector *db) +{ + int ret; + struct private_pls_data *ppd = NULL; + void *shm = NULL; + + self = db; + db->cmd_list = cmds; + db->get_audio_file_list = pls_get_audio_file_list; + db->shutdown = pls_shutdown; + db->post_select = pls_post_select; + db->update_audio_file = pls_update_audio_file; + ppd = para_calloc(sizeof(struct private_pls_data)); + db->private_data = ppd; + + ppd->client_mutex = -1; + ppd->server_mutex = -1; + ppd->client_data_shm_id = -1; + ppd->client_data = NULL; + + ret = mutex_new(); + if (ret < 0) + goto err_out; + ppd->client_mutex = ret; + + ret = mutex_new(); + if (ret < 0) + goto err_out; + ppd->server_mutex = ret; + + ret = shm_new(sizeof(struct pls_client_data)); + if (ret < 0) + goto err_out; + ppd->client_data_shm_id = ret; + + ret = shm_attach(ppd->client_data_shm_id, ATTACH_RW, &shm); + if (ret < 0) + goto err_out; + ppd->client_data = shm; + ppd->client_data->size = 0; + sprintf(mmd->dbinfo, "playlist selector initialized"); + return 1; +err_out: + if (ppd->client_data_shm_id >= 0) + shm_destroy(ppd->client_data_shm_id); + if (ppd->client_mutex >= 0) + mutex_destroy(ppd->client_mutex); + if (ppd->server_mutex >= 0) + mutex_destroy(ppd->server_mutex); + free(ppd); + return ret; +} diff --git a/plm_dbtool.c b/plm_dbtool.c deleted file mode 100644 index d17ac3af..00000000 --- a/plm_dbtool.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2006 Andre Noll - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. - */ - -/** \file plm_dbtool.c Playlist manager for paraslash */ - -#include "server.h" -#include "db.h" -#include "error.h" -#include "net.h" -#include "string.h" -#include "ipc.h" - -/** - * structure used for transmission of the playlist - * - * There's one such struct which gets initialized during startup. It lives in - * shared memory and is used by com_lpl(). - */ -struct plm_client_data { -/** allocated and set by com_lpl() (child) */ - int shm_id; -/** the size of the shared memory area identified by \a shm_id */ - size_t size; -/** initially locked, gets unlocked by parent when it is done */ - int mutex; -/** return value, set by parent */ - int retval; -}; - -/** data specific to the plm database tool */ -struct private_plm_data { -/** guards against concurrent client access */ - int client_mutex; -/** guards against concurrent parent-child access */ - int server_mutex; -/** pointer to the client data */ - struct plm_client_data *client_data; -/** id of the shm corresponding to \a client_data */ - int client_data_shm_id; -}; - -/** we refuse to load playlists bigger than that */ -#define MAX_PLAYLIST_BYTES (1024 * 1024) - -static unsigned playlist_len, playlist_size, current_playlist_entry; -static char **playlist; -static struct audio_file_selector *self; - -static int com_ppl(int, int, char **); -static int com_lpl(int, int, char **); -extern struct misc_meta_data *mmd; - -/* array of commands that are supported by this database tool */ -static struct server_command cmds[] = { -{ -.name = "ppl", -.handler = com_ppl, -.perms = DB_READ, -.description = "print playlist", -.synopsis = "ppl", -.help = -"Print out the current playlist" -}, { -.name = "lpl", -.handler = com_lpl, -.perms = DB_WRITE, -.description = "load playlist", -.synopsis = "lpl", -.help = -"Read a new playlist from stdin. Example:\n" -"\tfind /audio -name '*.mp3' | para_client lpl" -}, { -.name = NULL, -} -}; - -static void playlist_add(char *path) -{ - if (playlist_len >= playlist_size) { - playlist_size = 2 * playlist_size + 1; - playlist = para_realloc(playlist, playlist_size * sizeof(char *)); - } - PARA_DEBUG_LOG("adding #%d/%d: %s\n", playlist_len, playlist_size, path); - playlist[playlist_len++] = para_strdup(path); -} - -static int send_playlist_to_server(const char *buf, size_t size) -{ - struct private_plm_data *ppd = self->private_data; - int ret, shm_mutex = -1, shm_id = -1; - void *shm = NULL; - - PARA_DEBUG_LOG("new playlist (%d bytes)\n", size); - - ret = mutex_new(); - if (ret < 0) - return ret; - shm_mutex = ret; - - ret = shm_new(size); - if (ret < 0) - goto out; - shm_id = ret; - - ret = shm_attach(shm_id, ATTACH_RW, &shm); - if (ret < 0) - goto out; - mutex_lock(shm_mutex); - memcpy(shm, buf, size); - mutex_lock(ppd->client_mutex); - mutex_lock(ppd->server_mutex); - ppd->client_data->size = size; - ppd->client_data->shm_id = shm_id; - ppd->client_data->mutex = shm_mutex; - kill(getppid(), SIGUSR1); /* wake up the server */ - mutex_unlock(ppd->server_mutex); - mutex_lock(shm_mutex); /* wait until server is done */ - mutex_unlock(shm_mutex); - ret = ppd->client_data->retval; - mutex_unlock(ppd->client_mutex); - shm_detach(shm); -out: - if (shm_id >= 0) - shm_destroy(shm_id); - mutex_destroy(shm_mutex); - PARA_DEBUG_LOG("returning %d\n", ret); - return ret; -} - -static int com_lpl(int fd, __unused int argc, __unused char *argv[]) -{ - unsigned loaded = 0; - size_t bufsize = 4096; /* guess that's enough */ - char *buf = para_malloc(bufsize); - ssize_t ret; - ret = send_buffer(fd, AWAITING_DATA_MSG); - if (ret < 0) - goto out; -again: - ret = recv_bin_buffer(fd, buf + loaded, bufsize - loaded); - if (ret < 0) - goto out; - if (!ret) { - ret = send_playlist_to_server(buf, loaded); - goto out; - } - loaded += ret; - ret = -E_LOAD_PLAYLIST; - if (loaded >= MAX_PLAYLIST_BYTES) - goto out; - if (loaded >= bufsize) { - bufsize *= 2; - buf = para_realloc(buf, bufsize); - } - goto again; -out: - free(buf); - return ret; -} - -static int com_ppl(int fd, __unused int argc, __unused char *argv[]) -{ - unsigned i; - - PARA_DEBUG_LOG("sending playlist to client (%d entries)\n", playlist_len); - for (i = 0; i < playlist_len; i++) { - int ret = send_va_buffer(fd, "%s\n", playlist[ - (i + current_playlist_entry) % playlist_len]); - if (ret < 0) - return ret; - } - return 1; -} - -static char **plm_get_audio_file_list(unsigned int num) -{ - char **file_list; - unsigned i; - - num = MIN(num, playlist_len); - if (!num) - return NULL; - file_list = para_malloc((num + 1) * sizeof(char *)); - for (i = 0; i < num; i++) { - unsigned j = (current_playlist_entry + i) % playlist_len; - file_list[i] = para_strdup(playlist[j]); - } - file_list[i] = NULL; - return file_list; -} - -static void free_playlist_contents(void) -{ - int i; - - PARA_DEBUG_LOG("freeing playlist (%d entries)\n", playlist_len); - for (i = 0; i < playlist_len; i++) - free(playlist[i]); - current_playlist_entry = 0; - playlist_len = 0; -} - -static void plm_shutdown(void) -{ - struct private_plm_data *ppd = self->private_data; - - shm_detach(ppd->client_data); - shm_destroy(ppd->client_data_shm_id); - mutex_destroy(ppd->server_mutex); - mutex_destroy(ppd->client_mutex); - free(ppd); - free_playlist_contents(); - free(playlist); - playlist = NULL; - playlist_len = 0; - playlist_size = 0; -} - -static void plm_post_select(__unused fd_set *rfds, __unused fd_set *wfds) -{ - struct private_plm_data *ppd = self->private_data; - struct plm_client_data *pcd = ppd->client_data; - int ret; - void *shm; - - mutex_lock(ppd->server_mutex); - if (!pcd->size) - goto out; - free_playlist_contents(); - ret = shm_attach(pcd->shm_id, ATTACH_RW, &shm); - if (ret < 0) { - PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); - goto out; - } - PARA_DEBUG_LOG("loading new playlist (%d bytes)\n", pcd->size); - ret = for_each_line((char *)shm, pcd->size, &playlist_add); - shm_detach(shm); - PARA_NOTICE_LOG("new playlist (%d entries)\n", playlist_len); - pcd->retval = 1; - pcd->size = 0; - mutex_unlock(pcd->mutex); -out: - mutex_unlock(ppd->server_mutex); -} - -void plm_update_audio_file(char *audio_file) -{ - unsigned i; - - for (i = 0; i < playlist_len; i++) { - unsigned j = (current_playlist_entry + i) % playlist_len; - if (strcmp(playlist[j], audio_file)) - continue; - current_playlist_entry = (j + 1) % playlist_len; - } -} - -/** - * the init function for the plm database tool - * - * Init all function pointers of \a db - * - * \sa struct audio_file_selector, misc_meta_data::dbinfo, mysql.c random_dbtool.c - */ -int plm_selector_init(struct audio_file_selector *db) -{ - int ret; - struct private_plm_data *ppd = NULL; - void *shm = NULL; - - self = db; - db->cmd_list = cmds; - db->get_audio_file_list = plm_get_audio_file_list; - db->shutdown = plm_shutdown; - db->post_select = plm_post_select; - db->update_audio_file = plm_update_audio_file; - ppd = para_calloc(sizeof(struct private_plm_data)); - db->private_data = ppd; - - ppd->client_mutex = -1; - ppd->server_mutex = -1; - ppd->client_data_shm_id = -1; - ppd->client_data = NULL; - - ret = mutex_new(); - if (ret < 0) - goto err_out; - ppd->client_mutex = ret; - - ret = mutex_new(); - if (ret < 0) - goto err_out; - ppd->server_mutex = ret; - - ret = shm_new(sizeof(struct plm_client_data)); - if (ret < 0) - goto err_out; - ppd->client_data_shm_id = ret; - - ret = shm_attach(ppd->client_data_shm_id, ATTACH_RW, &shm); - if (ret < 0) - goto err_out; - ppd->client_data = shm; - ppd->client_data->size = 0; - sprintf(mmd->dbinfo, "plm initialized"); - return 1; -err_out: - if (ppd->client_data_shm_id >= 0) - shm_destroy(ppd->client_data_shm_id); - if (ppd->client_mutex >= 0) - mutex_destroy(ppd->client_mutex); - if (ppd->server_mutex >= 0) - mutex_destroy(ppd->server_mutex); - free(ppd); - return ret; -} diff --git a/server.c b/server.c index 3f5570dd..d881868c 100644 --- a/server.c +++ b/server.c @@ -69,8 +69,8 @@ struct audio_file_selector dblist[] = { .update_audio_file = NULL, }, { - .name = "plm", - .init = plm_selector_init, + .name = "playlist", + .init = playlist_selector_init, .update_audio_file = NULL, .pre_select = NULL, .post_select = NULL,