X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=random_dbtool.c;fp=random_dbtool.c;h=d970bd7f9226ad25d3bcc048bc7192e179639738;hb=c589157169366fa47f2041cfe52e7019fbc19b35;hp=0000000000000000000000000000000000000000;hpb=2ed89c59f0efcd0a2763f47c7d3455663241e623;p=paraslash.git 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; +}