mapper: make the music_directory optional

Without a music_directory, MPD is an excellent streaming client.
This commit is contained in:
Max Kellermann 2009-01-18 16:56:07 +01:00
parent 9933144de7
commit 1f0dfb4407
8 changed files with 95 additions and 35 deletions

2
NEWS
View File

@ -12,7 +12,7 @@ ver 0.15 - (200?/??/??)
* failure to read the state file is non-fatal * failure to read the state file is non-fatal
* added Icy-Metadata support * added Icy-Metadata support
* --create-db starts the MPD daemon instead of exiting * --create-db starts the MPD daemon instead of exiting
* playlist_directory is optional * playlist_directory and music_directory are optional
ver 0.14.1 (2009/01/17) ver 0.14.1 (2009/01/17)

View File

@ -29,9 +29,6 @@ See \fBdocs/mpdconf.example\fP in the source tarball for an example
configuration file. configuration file.
.SH REQUIRED PARAMETERS .SH REQUIRED PARAMETERS
.TP .TP
.B music_directory <directory>
This specifies the directory where music is located.
.TP
.B follow_outside_symlinks <yes or no> .B follow_outside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir. Control if MPD will follow symbolic links pointing outside the music dir.
You must recreate the database after changing this option. You must recreate the database after changing this option.
@ -54,6 +51,10 @@ The special value "syslog" makes MPD use the local syslog daemon.
.B pid_file <file> .B pid_file <file>
This specifies the file to save mpd's process ID in. This specifies the file to save mpd's process ID in.
.TP .TP
.B music_directory <directory>
This specifies the directory where music is located.
If you do not configure this, you can only play streams.
.TP
.B playlist_directory <directory> .B playlist_directory <directory>
This specifies the directory where saved playlists are stored. This specifies the directory where saved playlists are stored.
If you do not configure this, you cannot save playlists. If you do not configure this, you cannot save playlists.

View File

@ -49,13 +49,17 @@ db_init(const char *path)
{ {
database_path = g_strdup(path); database_path = g_strdup(path);
music_root = directory_new("", NULL); if (path != NULL)
music_root = directory_new("", NULL);
} }
void void
db_finish(void) db_finish(void)
{ {
directory_free(music_root); assert((database_path == NULL) == (music_root == NULL));
if (music_root != NULL)
directory_free(music_root);
g_free(database_path); g_free(database_path);
} }
@ -63,6 +67,8 @@ db_finish(void)
void void
db_clear(void) db_clear(void)
{ {
assert(music_root != NULL);
directory_free(music_root); directory_free(music_root);
music_root = directory_new("", NULL); music_root = directory_new("", NULL);
} }
@ -78,6 +84,9 @@ db_get_root(void)
struct directory * struct directory *
db_get_directory(const char *name) db_get_directory(const char *name)
{ {
if (music_root == NULL)
return NULL;
if (name == NULL) if (name == NULL)
return music_root; return music_root;
@ -89,14 +98,20 @@ db_get_song(const char *file)
{ {
struct song *song = NULL; struct song *song = NULL;
struct directory *directory; struct directory *directory;
char *dir = NULL; char *duplicated, *shortname, *dir;
char *duplicated = g_strdup(file);
char *shortname = strrchr(duplicated, '/'); assert(file != NULL);
g_debug("get song: %s", file); g_debug("get song: %s", file);
if (music_root == NULL)
return NULL;
duplicated = g_strdup(file);
shortname = strrchr(duplicated, '/');
if (!shortname) { if (!shortname) {
shortname = duplicated; shortname = duplicated;
dir = NULL;
} else { } else {
*shortname = '\0'; *shortname = '\0';
++shortname; ++shortname;
@ -121,6 +136,9 @@ db_walk(const char *name,
{ {
struct directory *directory; struct directory *directory;
if (music_root == NULL)
return -1;
if ((directory = db_get_directory(name)) == NULL) { if ((directory = db_get_directory(name)) == NULL) {
struct song *song; struct song *song;
if ((song = db_get_song(name)) && forEachSong) { if ((song = db_get_song(name)) && forEachSong) {

View File

@ -42,6 +42,10 @@ db_finish(void);
void void
db_clear(void); db_clear(void);
/**
* Returns the root directory object. Returns NULL if there is no
* configured music directory.
*/
struct directory * struct directory *
db_get_root(void); db_get_root(void);

View File

@ -128,7 +128,16 @@ static void openDB(Options * options, char *argv0)
{ {
struct config_param *param; struct config_param *param;
param = parseConfigFilePath(CONF_DB_FILE, true); param = parseConfigFilePath(CONF_DB_FILE,
mapper_has_music_directory());
if (!mapper_has_music_directory()) {
if (param != NULL)
g_message("Found " CONF_DB_FILE " setting without "
CONF_MUSIC_DIR " - disabling database");
db_init(NULL);
return;
}
db_init(param->value); db_init(param->value);
if (options->createDB > 0 || !db_load()) { if (options->createDB > 0 || !db_load()) {

View File

@ -40,6 +40,24 @@ static size_t music_dir_length;
static char *playlist_dir; static char *playlist_dir;
static void
mapper_set_music_dir(const char *path, int line)
{
int ret;
struct stat st;
music_dir = g_strdup(path);
music_dir_length = strlen(music_dir);
ret = stat(music_dir, &st);
if (ret < 0)
g_warning("failed to stat music directory \"%s\" (config line %i): %s\n",
music_dir, line, g_strerror(errno));
else if (!S_ISDIR(st.st_mode))
g_warning("music directory is not a directory: \"%s\" (config line %i)\n",
music_dir, line);
}
static void static void
mapper_set_playlist_dir(const char *path, int line) mapper_set_playlist_dir(const char *path, int line)
{ {
@ -59,34 +77,19 @@ mapper_set_playlist_dir(const char *path, int line)
void mapper_init(void) void mapper_init(void)
{ {
struct config_param *music_dir_param =
parseConfigFilePath(CONF_MUSIC_DIR, false);
struct config_param *param; struct config_param *param;
int ret;
struct stat st;
if (music_dir_param != NULL) { param = parseConfigFilePath(CONF_MUSIC_DIR, false);
music_dir = g_strdup(music_dir_param->value); if (param != NULL)
} else { mapper_set_music_dir(param->value, param->line);
#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 14) #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 14)
music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC)); else {
if (music_dir == NULL) const char *path =
/* GLib failed to determine the XDG music g_get_user_special_dir(G_USER_DIRECTORY_MUSIC);
directory - abort */ if (path != NULL)
#endif mapper_set_music_dir(path, -1);
g_error("config parameter \"%s\" not found\n", CONF_MUSIC_DIR);
} }
#endif
music_dir_length = strlen(music_dir);
ret = stat(music_dir, &st);
if (ret < 0)
g_warning("failed to stat music directory \"%s\" (config line %i): %s\n",
music_dir_param->value, music_dir_param->line,
strerror(errno));
else if (!S_ISDIR(st.st_mode))
g_warning("music directory is not a directory: \"%s\" (config line %i)\n",
music_dir_param->value, music_dir_param->line);
param = parseConfigFilePath(CONF_PLAYLIST_DIR, false); param = parseConfigFilePath(CONF_PLAYLIST_DIR, false);
if (param != NULL) if (param != NULL)
@ -99,6 +102,12 @@ void mapper_finish(void)
g_free(playlist_dir); g_free(playlist_dir);
} }
bool
mapper_has_music_directory(void)
{
return music_dir != NULL;
}
char * char *
map_uri_fs(const char *uri) map_uri_fs(const char *uri)
{ {
@ -107,6 +116,9 @@ map_uri_fs(const char *uri)
assert(uri != NULL); assert(uri != NULL);
assert(*uri != '/'); assert(*uri != '/');
if (music_dir == NULL)
return NULL;
uri_fs = utf8_to_fs_charset(uri); uri_fs = utf8_to_fs_charset(uri);
if (uri_fs == NULL) if (uri_fs == NULL)
return NULL; return NULL;
@ -120,6 +132,8 @@ map_uri_fs(const char *uri)
char * char *
map_directory_fs(const struct directory *directory) map_directory_fs(const struct directory *directory)
{ {
assert(music_dir != NULL);
if (directory_is_root(directory)) if (directory_is_root(directory))
return g_strdup(music_dir); return g_strdup(music_dir);
@ -131,6 +145,8 @@ map_directory_child_fs(const struct directory *directory, const char *name)
{ {
char *name_fs, *parent_fs, *path; char *name_fs, *parent_fs, *path;
assert(music_dir != NULL);
/* check for invalid or unauthorized base names */ /* check for invalid or unauthorized base names */
if (*name == 0 || strchr(name, '/') != NULL || if (*name == 0 || strchr(name, '/') != NULL ||
strcmp(name, ".") == 0 || strcmp(name, "..") == 0) strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
@ -167,7 +183,8 @@ map_song_fs(const struct song *song)
char * char *
map_fs_to_utf8(const char *path_fs) map_fs_to_utf8(const char *path_fs)
{ {
if (strncmp(path_fs, music_dir, music_dir_length) == 0 && if (music_dir != NULL &&
strncmp(path_fs, music_dir, music_dir_length) == 0 &&
path_fs[music_dir_length] == '/') path_fs[music_dir_length] == '/')
/* remove musicDir prefix */ /* remove musicDir prefix */
path_fs += music_dir_length + 1; path_fs += music_dir_length + 1;

View File

@ -23,6 +23,8 @@
#ifndef MPD_MAPPER_H #ifndef MPD_MAPPER_H
#define MPD_MAPPER_H #define MPD_MAPPER_H
#include <stdbool.h>
#define PLAYLIST_FILE_SUFFIX "m3u" #define PLAYLIST_FILE_SUFFIX "m3u"
struct directory; struct directory;
@ -32,6 +34,12 @@ void mapper_init(void);
void mapper_finish(void); void mapper_finish(void);
/**
* Returns true if a music directory was configured.
*/
bool
mapper_has_music_directory(void);
/** /**
* Determines the absolute file system path of a relative URI. This * Determines the absolute file system path of a relative URI. This
* is basically done by converting the URI to the file system charset * is basically done by converting the URI to the file system charset

View File

@ -680,6 +680,9 @@ directory_update_init(char *path)
{ {
assert(g_thread_self() == main_task); assert(g_thread_self() == main_task);
if (!mapper_has_music_directory())
return 0;
if (progress != UPDATE_PROGRESS_IDLE) { if (progress != UPDATE_PROGRESS_IDLE) {
unsigned next_task_id; unsigned next_task_id;