From: Andre Date: Tue, 21 Feb 2006 08:22:36 +0000 (+0100) Subject: Merge branch 'dbtool_preselect' X-Git-Tag: v0.2.11~67 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=c141cc6915a32fb92766dc27f0df222d13f27d8b;hp=f6dc51ad7914b60fe71a4fc53460925bdc513a9d Merge branch 'dbtool_preselect' --- diff --git a/Doxyfile b/Doxyfile index 090e1206..37c9cec1 100644 --- a/Doxyfile +++ b/Doxyfile @@ -452,8 +452,6 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -#INPUT = net.c signal.c db.h db.c ringbuffer.c ringbuffer.h stat.c afs.c afs.h string.c net.h filter.h filter_chain.c error.h recv.h http_recv.c ortp_recv.c recv_common.c http.h mp3dec.c oggdec.c ortp.h wav.c compress.c daemon.c daemon.h grab_client.c grab_client.h close_on_fork.c close_on_fork.h audiod.c audiod.h time.c mysql.c server.h command.c server.c send.h http_send.c ortp_send.c http.h ortp.h mp3.c ogg.c dopey.c string.h exec.c - INPUT = . # If the value of the INPUT tag contains directories, you can use the diff --git a/FEATURES b/FEATURES index 3dde8e97..b567f113 100644 --- a/FEATURES +++ b/FEATURES @@ -32,7 +32,7 @@ mysql-based audio file selector: small memory footprint: ~~~~~~~~~~~~~~~~~~~~~~~ paraslash is lightweight. The stripped binary of para_server - with all its features compiled in (mysql/dopey dbtool, + with all its features compiled in (mysql/random dbtool, mp3/ogg support, http/ortp support) is about 100K on i386 under Linux. para_audiod is even smaller. @@ -53,7 +53,7 @@ authentication/encryption via openssl: various user interfaces and utilities: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ o para_gui. Curses based interface, displays information in a - curses window and can be used to easily control para_server + curses window and can be used to easily control para_server and para_audiod. o para_sdl_gui. Shows pictures (on a per song basis) and diff --git a/INSTALL b/INSTALL index 3b373181..9d82c9bf 100644 --- a/INSTALL +++ b/INSTALL @@ -78,24 +78,19 @@ to retrieve the list of available commands and some server info. Choose your database tool (dbtool) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You have three options: +You have two options: 1. Use the mysql dbtool which comes with paraslash and requires - mysql. This is recommended. + mysql. - 2. Use your own database tool. If you have that already, - skip this step. - - 3. If you can not use the mysql dbtool and you just want - to quickly make paraslash working, use the dopey dbtool. + 2. If you can not use the mysql dbtool and you just want + to quickly make paraslash working, use the random dbtool. The directory which is searched for audio files can be given - via the server option --dopey_dir. - - Note, however, that dopey is _really_ dopey. It scans - $dopey_dir on every audio file change and chooses one - randomly. You get the idea. Have a look at its source code - and feel free to modify. + via the server option --random_dbtool_dir. + Note, however, that this database tool is really dopey. It + scans the given directory on every audio file change and + chooses one randomly. There is no further functionality. The current database tool can be changed at runtime via diff --git a/README b/README index 967655fc..2c0dc76d 100644 --- a/README +++ b/README @@ -27,9 +27,10 @@ It contains the following programs: para_server needs a database tool to work, mainly to determine which song to stream next. There are two database tools - available: mysql and dopey. The former is recommended as dopey - is only meant as a fallback and as a starting point for people - that want to write their own database tool for paraslash. + available: mysql and random. The former is recommended as + the random database tool is only meant as a fallback and + as a starting point for people that want to write their own + database tool for paraslash. The mysql database tool connects to a mysql server which holds information on your audio files. It has several unusual diff --git a/README.mysql b/README.mysql index d2a27e72..7af82807 100644 --- a/README.mysql +++ b/README.mysql @@ -50,8 +50,8 @@ indeed activated, type para_client cdt -which prints the name of the current database tool. If the dopey -dbtool is still selected, try +which prints the name of the current database tool. If the mysql +dbtool is not selected, try para_client cdt mysql diff --git a/configure.ac b/configure.ac index da353502..0e93aa21 100644 --- a/configure.ac +++ b/configure.ac @@ -72,8 +72,8 @@ audiod_errlist_objs="audiod exec close_on_fork signal string daemon stat net audiod_ldflags="" server_cmdline_objs="server.cmdline" -server_errlist_objs="server mp3 afs command net string signal dopey time daemon stat - crypt http_send db close_on_fork" +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" server_ldflags="" ########################################################################### ssl diff --git a/db.h b/db.h index 328f7de8..69d4d9ed 100644 --- a/db.h +++ b/db.h @@ -115,5 +115,6 @@ void (*post_select)(fd_set *rfds, fd_set *wfds); }; int mysql_dbtool_init(struct dbtool*); -int dopey_dbtool_init(struct dbtool*); +int plm_dbtool_init(struct dbtool*); +int random_dbtool_init(struct dbtool*); diff --git a/dopey.c b/dopey.c deleted file mode 100644 index 91e13685..00000000 --- a/dopey.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2004-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 dopey.c Simple database tool implementation. Feel free to modify. */ - -#include /* gettimeofday */ -#include "server.cmdline.h" -#include "server.h" -#include "db.h" -#include "error.h" -#include "net.h" -#include "string.h" - -static int com_dopey(int, int, char **); -extern struct gengetopt_args_info conf; -extern struct misc_meta_data *mmd; - -static unsigned int num_audio_files, audio_file_count; -static char **audio_file_list; - -static int count_audio_files(__unused const char *dir, __unused const char *name) -{ - num_audio_files++; - return 1; -} - -static int remember_file(const char *dir, const char *name) -{ - if (audio_file_count >= num_audio_files) - return -E_FILE_COUNT; - audio_file_list[audio_file_count] = make_message("%s/%s", dir, name); - audio_file_count++; - return 1; -} - -/* array of commands that are supported by this database tool */ -static struct server_command cmds[] = { -{ -.name = "dopey", -.handler = com_dopey, -.perms = 0, -.description = "about the dopey database tool", -.synopsis = "dopey", -.help = - -"It's so dumb. It hurts. Don't use it; switch to the mysql database\n" -"tool instead. OTOH: You typed 'help dopey', so if you serious about\n" -"that and you really intend to help the dopey database tool, look at\n" -"my source code, dopey.c, and modify it to make it something useful.\n" - -}, { -.name = NULL, -} -}; - -static int com_dopey(int fd, __unused int argc, __unused char *argv[]) -{ - return send_buffer(fd, "Please do not use me. I'm too sick to do " - "anything for you. Switch me off. Now!\n"); -} - -/* - * Load a list of all audio files into memory and chose num of them randomly. - * Called by server to determine next audio file to be streamed. - */ -static char **dopey_get_audio_file_list(unsigned int num) -{ - int i, ret; - unsigned int len; - char **ret_list = NULL; /* what we are going to return */ - - audio_file_list = NULL; - num_audio_files = 0; - /* first run, just count all audio files. dopey */ - ret = find_audio_files(conf.dopey_dir_arg, count_audio_files); - if (ret < 0) - goto out; - ret = -E_NOTHING_FOUND; - if (!num_audio_files) - goto out; - /* yeah, that doesn't scale, also dopey */ - audio_file_list = para_malloc(num_audio_files * sizeof(char *)); - audio_file_count = 0; - /* second run (hot dentry cache, hopefully), fill audio_file_list */ - ret = find_audio_files(conf.dopey_dir_arg, remember_file); - if (ret < 0) - goto out; - /* careful, files might got deleted underneath */ - num_audio_files = audio_file_count; /* can only decrease */ - len = MIN(num, num_audio_files); - ret = -E_NOTHING_FOUND; - if (!len) /* nothing found, return NULL */ - goto out; - /* success, return NULL-terminated list */ - ret_list = para_calloc((len + 1) * sizeof(char *)); - for (i = 0; i < len; i++) { /* choose randomly */ - int r = (int) ((num_audio_files + 0.0) * (rand() - / (RAND_MAX + 1.0))); - ret_list[i] = para_strdup(audio_file_list[r]); - } -out: - if (audio_file_list) { - for (i = 0; i < num_audio_files; i++) - free(audio_file_list[i]); - free(audio_file_list); - } -// if (ret < 0) -// PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); - return ret_list; -} - -static void dopey_shutdown(void) -{ - PARA_DEBUG_LOG("%s", "thanks for using another dbtool.\n"); -} - -/** dopey's (constant) database info text */ -#define DBINFO "dbinfo1:database info? You're kidding. I'm dopey!\ndbinfo2:\ndbinfo3:\n" - -/** the dopey init function - * - * Init all function pointers of \a db, init the dbinfo text and seed the - * PRNG. - * - * \sa struct dbtool, misc_meta_data::dbinfo, mysql.c - */ -int dopey_dbtool_init(struct dbtool *db) -{ - struct timeval now; - - PARA_INFO_LOG("%s", "registering dopey handlers\n"); - sprintf(mmd->dbinfo, DBINFO); - gettimeofday(&now, NULL); - srand(now.tv_usec); - db->cmd_list = cmds; - db->get_audio_file_list = dopey_get_audio_file_list; - db->shutdown = dopey_shutdown; - return 1; -} diff --git a/error.h b/error.h index bc8475e0..0c4a05f4 100644 --- a/error.h +++ b/error.h @@ -23,8 +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_DOPEY, SS_CRYPT, SS_HTTP_SEND, SS_ORTP_SEND, SS_DB, SS_OGG, - SS_MP3, SS_MP3DEC, SS_SERVER, SS_AFS, SS_MYSQL, SS_RINGBUFFER}; + SS_COMMAND, SS_RANDOM_DBTOOL, SS_PLM_DBTOOL, 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[]; /** \endcond */ @@ -185,7 +185,7 @@ extern const char **para_errlist[]; PARA_ERROR(WRITE_OK, "can not check whether fd is writable"), \ -#define DOPEY_ERRORS \ +#define RANDOM_DBTOOL_ERRORS \ PARA_ERROR(FILE_COUNT, "audio file count exceeded"), \ PARA_ERROR(NOTHING_FOUND, "no audio files found"), \ @@ -224,6 +224,16 @@ extern const char **para_errlist[]; PARA_ERROR(LOCK, "lock error"), \ PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \ +#define PLM_DBTOOL_ERRORS \ + PARA_ERROR(LOAD_PLAYLIST, "failed to load playlist"), \ + + +#define IPC_ERRORS \ + PARA_ERROR(SEM_GET, "failed to create semaphore"), \ + PARA_ERROR(SEM_REMOVE, "can not remove semaphore"), \ + PARA_ERROR(SHM_GET, "failed to allocate shared memory area"), \ + PARA_ERROR(SHM_DESTROY, "failed to destroy shared memory area"), \ + PARA_ERROR(SHM_DETACH, "can not detach shared memory area"), \ /* these do not need error handling (yet) */ #define SERVER_ERRORS @@ -331,12 +341,14 @@ SS_ENUM(OGG); SS_ENUM(SERVER); SS_ENUM(AFS); SS_ENUM(COMMAND); -SS_ENUM(DOPEY); +SS_ENUM(RANDOM_DBTOOL); +SS_ENUM(PLM_DBTOOL); SS_ENUM(CRYPT); SS_ENUM(HTTP_SEND); SS_ENUM(ORTP_SEND); SS_ENUM(DB); SS_ENUM(MYSQL); +SS_ENUM(IPC); SS_ENUM(RINGBUFFER); /** \endcond */ #undef PARA_ERROR diff --git a/ipc.c b/ipc.c new file mode 100644 index 00000000..9ae2b3a0 --- /dev/null +++ b/ipc.c @@ -0,0 +1,105 @@ +#include "para.h" +#include "error.h" +#include "ipc.h" +#include +#include + + +int mutex_new(void) +{ + int ret = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); + return ret < 0? -E_SEM_GET : ret; +} + +int mutex_remove(int id) +{ + int ret = semctl(id, 0, IPC_RMID); + return ret < 0? -E_SEM_REMOVE : 1; +} + +static void para_semop(int id, struct sembuf *sops, int num) +{ + if (semop(id, sops, num) >= 0) + return; + PARA_WARNING_LOG("semop failed (%s), retrying\n", strerror(errno)); + while (semop(id, sops, num) < 0) + ; /* nothing */ +} + +/** + * lock the given mutex + * + * \sa semop(2), struct misc_meta_data + */ +void mutex_lock(int id) +{ + struct sembuf sops[2] = { + { + .sem_num = 0, + .sem_op = 0, + .sem_flg = SEM_UNDO + }, + { + .sem_num = 0, + .sem_op = 1, + .sem_flg = SEM_UNDO + } + }; + para_semop(id, sops, 2); +} + +/** + * unlock a mutex + * + * \sa semop(2), struct misc_meta_data + */ +void mutex_unlock(int id) +{ + struct sembuf sops[1] = { + { + .sem_num = 0, + .sem_op = -1, + .sem_flg = SEM_UNDO + }, + }; + para_semop(id, sops, 1); +} + +/** + * create a new shared memory area of given size + * + * \sa shmget(2) + */ +int shm_new(size_t size) +{ + int ret = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | 0600); + return ret < 0 ? -E_SHM_GET : ret; +} + +/** + * destroy the given shared memory area + * \sa shmctl(2) + **/ +int shm_destroy(int id) +{ + struct shmid_ds shm_desc; + int ret = shmctl(id, IPC_RMID, &shm_desc); + return ret < 0? -E_SHM_DESTROY : ret; +} + +/** + * attach a shared memory area + * + * \sa semop(2) + */ +void *shm_attach(int id, enum shm_attach_mode mode) +{ + if (mode == ATTACH_RW) + return shmat(id, NULL, 0); + return shmat(id, NULL, SHM_RDONLY); +} +int shm_detach(void *addr) +{ + int ret = shmdt(addr); + return ret < 0? -E_SHM_DETACH : 1; +} diff --git a/ipc.h b/ipc.h new file mode 100644 index 00000000..25c56d26 --- /dev/null +++ b/ipc.h @@ -0,0 +1,7 @@ +/** \file ipc.h inter process communication and shared memory routines */ + +enum shm_attach_mode {ATTACH_RO, ATTACH_RW}; + +int mutex_new(void); +void mutex_lock(int id); +void mutex_unlock(int id); diff --git a/mysql.c b/mysql.c index b8fa02dc..9760f086 100644 --- a/mysql.c +++ b/mysql.c @@ -2514,7 +2514,7 @@ static void shutdown_connection(void) * Check the command line options and initialize all function pointers of \a db. * Connect to the mysql server and initialize the dbinfo string. * - * \sa struct dbtool, misc_meta_data::dbinfo, dopey.c + * \sa struct dbtool, misc_meta_data::dbinfo, random_dbtool.c */ int mysql_dbtool_init(struct dbtool *db) { diff --git a/plm_dbtool.c b/plm_dbtool.c new file mode 100644 index 00000000..fd18f254 --- /dev/null +++ b/plm_dbtool.c @@ -0,0 +1,159 @@ +/* + * 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 Simple playlist manager for paraslash */ + +#include /* gettimeofday */ +#include "server.cmdline.h" +#include "server.h" +#include "db.h" +#include "error.h" +#include "net.h" +#include "string.h" + +#define MAX_PLAYLIST_LEN 10000 +#define MAX_PLAYLIST_BYTES (1024 * 1024) + +static unsigned playlist_len, playlist_size, current_playlist_entry; +static char **playlist; + +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" + +}, { +.name = NULL, +} +}; + +static void playlist_add(char *path) +{ + if (playlist_len >= playlist_size) { + if (playlist_size >= MAX_PLAYLIST_LEN) + return; + playlist_size *= 2; + playlist = para_realloc(playlist, playlist_size * sizeof(char *)); + } + PARA_DEBUG_LOG("adding #%d: %s\n", playlist_len, path); + playlist[playlist_len] = para_strdup(path); + playlist_len++; +} + +static int com_lpl(int fd, __unused int argc, __unused char *argv[]) +{ + unsigned i, loaded = 0; + char buf[_POSIX_PATH_MAX]; + ssize_t ret; + + 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; + ret = send_buffer(fd, AWAITING_DATA_MSG); + if (ret < 0) + return ret; +again: + ret = recv_bin_buffer(fd, buf + loaded, sizeof(buf) - loaded); + if (ret < 0) + goto err_out; + if (!ret) { + PARA_DEBUG_LOG("loaded playlist (%d entries)\n", playlist_len); + return playlist_len; + } + loaded += ret; + loaded = for_each_line(buf, loaded, &playlist_add, 0); + if (loaded >= sizeof(buf)) + goto err_out; + goto again; +err_out: + return -E_LOAD_PLAYLIST; +} + +static int com_ppl(int fd, __unused int argc, __unused char *argv[]) +{ + unsigned i; + + PARA_DEBUG_LOG("sending playlist (%d entries)\n", playlist_len); + for (i = 0; i < playlist_len; i++) { + int ret = send_buffer(fd, playlist[i]); + if (ret < 0) + return ret; + } + return 1; +} + +static char **plm_get_audio_file_list(unsigned int num) +{ + char **file_list; + unsigned i; + + return NULL; + 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 plm_shutdown(void) +{ + /* free the playlist */ +} + +/** + * the init function for the plm database tool + * + * Init all function pointers of \a db + * + * \sa struct dbtool, misc_meta_data::dbinfo, mysql.c random_dbtool.c + */ +int plm_dbtool_init(struct dbtool *db) +{ + playlist = para_calloc(100 * sizeof(char *)); /* guess 100 is enough */ + playlist_size = 100; + sprintf(mmd->dbinfo, "plm initialized"); + db->cmd_list = cmds; + db->get_audio_file_list = plm_get_audio_file_list; + db->shutdown = plm_shutdown; + return 1; +} diff --git a/random_dbtool.c b/random_dbtool.c new file mode 100644 index 00000000..d970bd7f --- /dev/null +++ b/random_dbtool.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2004-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 random_dbtool. Simple database tool implementation. Feel free to modify. */ + +#include /* gettimeofday */ +#include "server.cmdline.h" +#include "server.h" +#include "db.h" +#include "error.h" +#include "net.h" +#include "string.h" + +static int com_random_info(int, int, char **); +extern struct gengetopt_args_info conf; +extern struct misc_meta_data *mmd; + +static unsigned int num_audio_files, audio_file_count; +static char **audio_file_list; + +static int count_audio_files(__unused const char *dir, __unused const char *name) +{ + num_audio_files++; + return 1; +} + +static int remember_file(const char *dir, const char *name) +{ + if (audio_file_count >= num_audio_files) + return -E_FILE_COUNT; + audio_file_list[audio_file_count] = make_message("%s/%s", dir, name); + audio_file_count++; + return 1; +} + +/* array of commands that are supported by this database tool */ +static struct server_command cmds[] = { +{ +.name = "random_info", +.handler = com_random_info, +.perms = 0, +.description = "about the random database tool", +.synopsis = "random_info", +.help = + +"Select a random file under the given directory" +}, { +.name = NULL, +} +}; + +static int com_random_info(int fd, __unused int argc, __unused char *argv[]) +{ + return send_buffer(fd, "Don't use for huge directories as it is " + "very inefficient in this case.\n"); +} + +/* + * Load a list of all audio files into memory and chose num of them randomly. + * Called by server to determine next audio file to be streamed. + */ +static char **random_get_audio_file_list(unsigned int num) +{ + int i, ret; + unsigned int len; + char **ret_list = NULL; /* what we are going to return */ + + audio_file_list = NULL; + num_audio_files = 0; + /* first run, just count all audio files. dopey */ + ret = find_audio_files(conf.random_dbtool_dir_arg, count_audio_files); + if (ret < 0) + goto out; + ret = -E_NOTHING_FOUND; + if (!num_audio_files) + goto out; + /* yeah, that doesn't scale, also dopey */ + audio_file_list = para_malloc(num_audio_files * sizeof(char *)); + audio_file_count = 0; + /* second run (hot dentry cache, hopefully), fill audio_file_list */ + ret = find_audio_files(conf.random_dbtool_dir_arg, remember_file); + if (ret < 0) + goto out; + /* careful, files might got deleted underneath */ + num_audio_files = audio_file_count; /* can only decrease */ + len = MIN(num, num_audio_files); + ret = -E_NOTHING_FOUND; + if (!len) /* nothing found, return NULL */ + goto out; + /* success, return NULL-terminated list */ + ret_list = para_calloc((len + 1) * sizeof(char *)); + for (i = 0; i < len; i++) { /* choose randomly */ + int r = (int) ((num_audio_files + 0.0) * (rand() + / (RAND_MAX + 1.0))); + ret_list[i] = para_strdup(audio_file_list[r]); + } +out: + if (audio_file_list) { + for (i = 0; i < num_audio_files; i++) + free(audio_file_list[i]); + free(audio_file_list); + } +// if (ret < 0) +// PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret)); + return ret_list; +} + +static void random_shutdown(void) +{ + PARA_DEBUG_LOG("%s", "thanks for using another dbtool.\n"); +} + +/** random's (constant) database info text */ +#define DBINFO "dbinfo1:database info? You're kidding. I'm still dopey!\ndbinfo2:\ndbinfo3:\n" + +/** + * the init function for the random database tool + * + * Init all function pointers of \a db, init the dbinfo text and seed the + * PRNG. + * + * \sa struct dbtool, misc_meta_data::dbinfo, mysql.c + */ +int random_dbtool_init(struct dbtool *db) +{ + struct timeval now; + + PARA_INFO_LOG("%s", "registering random handlers ;)\n"); + sprintf(mmd->dbinfo, DBINFO); + gettimeofday(&now, NULL); + srand(now.tv_usec); + db->cmd_list = cmds; + db->get_audio_file_list = random_get_audio_file_list; + db->shutdown = random_shutdown; + return 1; +} diff --git a/server.c b/server.c index 8d943533..c185b3e1 100644 --- a/server.c +++ b/server.c @@ -63,8 +63,13 @@ extern struct audio_format afl[]; /** the list of supported database tools */ struct dbtool dblist[] = { { - .name = "dopey", - .init = dopey_dbtool_init, + .name = "random", + .init = random_dbtool_init, + .update_audio_file = NULL, + }, + { + .name = "plm", + .init = plm_dbtool_init, .update_audio_file = NULL, .pre_select = NULL, .post_select = NULL, @@ -306,7 +311,7 @@ static void init_dbtool(void) mmd->dbt_change = -1; /* no change nec., set to new dbt num by com_cdt */ if (!dblist[1].name) - goto dopey; + goto random; if (conf.dbtool_given) { for (i = 0; dblist[i].name; i++) { if (strcmp(dblist[i].name, conf.dbtool_arg)) @@ -316,16 +321,16 @@ static void init_dbtool(void) if (dblist[i].init(&dblist[i]) < 0) { PARA_WARNING_LOG("init %s failed", dblist[i].name); - goto dopey; + goto random; } mmd->dbt_num = i; return; } - PARA_WARNING_LOG("%s", "no such dbtool, switching to dopey\n"); - goto dopey; + PARA_WARNING_LOG("%s", "no such dbtool, switching to random\n"); + goto random; } /* use the first dbtool that works - * (assuming that dopey always works) + * (assuming that random always works) */ for (i = 1; dblist[i].name; i++) { int ret = dblist[i].init(&dblist[i]); @@ -337,7 +342,7 @@ static void init_dbtool(void) PARA_CRIT_LOG("%s init failed: %s\n", dblist[i].name, PARA_STRERROR(-ret)); } -dopey: +random: mmd->dbt_num = 0; dblist[0].init(&dblist[0]); /* always successful */ } @@ -421,7 +426,7 @@ static void handle_dbt_change(void) return; } /* init failed */ - PARA_ERROR_LOG("%s -- switching to dopey\n", PARA_STRERROR(-ret)); + PARA_ERROR_LOG("%s -- switching to the random dbtool\n", PARA_STRERROR(-ret)); dblist[0].init(&dblist[0]); mmd->dbt_num = 0; } diff --git a/server.ggo b/server.ggo index 52dc90b6..a7db080a 100644 --- a/server.ggo +++ b/server.ggo @@ -25,8 +25,8 @@ option "mysql_default_score" - "scoring rule to use if stream definition does no -section "Dopey database tool options" -option "dopey_dir" - "dir to search for files to be streamed" string default="/home/music" no +section "Random database tool options" +option "random_dbtool_dir" - "dir to search for files to be streamed" string default="/home/music" no section "Http sender options" option "http_port" - "tcp port for http streaming" int typestr="portnumber" default="8000" no @@ -40,4 +40,3 @@ option "ortp_target" - "Add given host/port to the list of targets. This option option "ortp_no_autostart" - "do not start to send automatically" flag off option "ortp_default_port" - "default udp port if not specified" int typestr="portnumber" default="1500" no option "ortp_header_interval" H "time between extra header sends" int typestr="milliseconds" default="2000" no -