rename plm_dbtool.c to playlist_selector.c
authorAndre <maan@p133.(none)>
Fri, 10 Mar 2006 20:01:50 +0000 (21:01 +0100)
committerAndre <maan@p133.(none)>
Fri, 10 Mar 2006 20:01:50 +0000 (21:01 +0100)
FEATURES
INSTALL
NEWS
README
configure.ac
db.h
error.h
playlist_selector.c [new file with mode: 0644]
plm_dbtool.c [deleted file]
server.c

index fbc8429..bad8110 100644 (file)
--- a/FEATURES
+++ b/FEATURES
@@ -26,7 +26,7 @@ configurable audio file selectors:
        There are three audio file selectors available:
 
                - random
        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
                - mysql
 
        The first two of these are rather simple, and they are always
diff --git a/INSTALL b/INSTALL
index 41a45c4..04bf53f 100644 (file)
--- 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),
 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.
 
        The random selector chooses files randomly from the given
        directory.
diff --git a/NEWS b/NEWS
index ddaca55..5e7dfa8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ NEWS
 
        o the new ipc subsystem
 
 
        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
 
        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 9541001..374fcf6 100644 (file)
--- 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.
 
        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.
 
        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):
 
 
 - para_client (obligatory):
 
index fac1ab5..587e22f 100644 (file)
@@ -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
 
 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
 server_ldflags=""
 
 ########################################################################### ssl
diff --git a/db.h b/db.h
index 80c0de8..578e4fd 100644 (file)
--- a/db.h
+++ b/db.h
@@ -119,6 +119,6 @@ void *private_data;
 };
 
 int mysql_selector_init(struct audio_file_selector*);
 };
 
 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*);
 
 int random_selector_init(struct audio_file_selector*);
 
diff --git a/error.h b/error.h
index 98ca4ec..a753bc4 100644 (file)
--- 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_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[];
        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"), \
 
        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"), \
 
 
        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(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);
 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 (file)
index 0000000..47fb269
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
+ *
+ *     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 (file)
index d17ac3a..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2006 Andre Noll <maan@systemlinux.org>
- *
- *     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;
-}
index 3f5570d..d881868 100644 (file)
--- a/server.c
+++ b/server.c
@@ -69,8 +69,8 @@ struct audio_file_selector dblist[] = {
                .update_audio_file = NULL,
        },
        {
                .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,
                .update_audio_file = NULL,
                .pre_select = NULL,
                .post_select = NULL,