Commit 1f0dfb44 authored by Max Kellermann's avatar Max Kellermann

mapper: make the music_directory optional

Without a music_directory, MPD is an excellent streaming client.
parent 9933144d
...@@ -12,7 +12,7 @@ ver 0.15 - (200?/??/??) ...@@ -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)
......
...@@ -29,9 +29,6 @@ See \fBdocs/mpdconf.example\fP in the source tarball for an example ...@@ -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. ...@@ -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.
......
...@@ -49,13 +49,17 @@ db_init(const char *path) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) {
......
...@@ -42,6 +42,10 @@ db_finish(void); ...@@ -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);
......
...@@ -128,7 +128,16 @@ static void openDB(Options * options, char *argv0) ...@@ -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()) {
......
...@@ -41,6 +41,24 @@ static size_t music_dir_length; ...@@ -41,6 +41,24 @@ static size_t music_dir_length;
static char *playlist_dir; static char *playlist_dir;
static void 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
mapper_set_playlist_dir(const char *path, int line) mapper_set_playlist_dir(const char *path, int line)
{ {
int ret; int ret;
...@@ -59,34 +77,19 @@ 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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -23,6 +23,8 @@ ...@@ -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;
...@@ -33,6 +35,12 @@ void mapper_init(void); ...@@ -33,6 +35,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
* and prepending the music directory. * and prepending the music directory.
......
...@@ -680,6 +680,9 @@ directory_update_init(char *path) ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment