X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=plm_dbtool.c;fp=plm_dbtool.c;h=0000000000000000000000000000000000000000;hb=019a4caa2bf9232c7efd84ffe7424994de6358fb;hp=d17ac3afb35319be12a038cdeba533a5a75951f3;hpb=dfaa2c1b2505dc2e192bd6e8baa80a5d02ed78b7;p=paraslash.git 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; -}