diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/command.c | 2 | ||||
-rw-r--r-- | src/inotify_update.c | 4 | ||||
-rw-r--r-- | src/input_stream.h | 4 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/mapper.c | 89 | ||||
-rw-r--r-- | src/mapper.h | 15 | ||||
-rw-r--r-- | src/playlist/lastfm_playlist_plugin.c | 2 | ||||
-rw-r--r-- | src/playlist_song.c | 61 |
9 files changed, 104 insertions, 76 deletions
@@ -4,6 +4,7 @@ ver 0.18 (2012/??/??) ver 0.17.2 (2012/??/??) * protocol: - fix crash in local file check +* mapper: fix non-UTF8 music directory name ver 0.17.1 (2012/07/31) diff --git a/src/command.c b/src/command.c index 7bb49447d..5bc6934c5 100644 --- a/src/command.c +++ b/src/command.c @@ -1183,7 +1183,7 @@ handle_config(struct client *client, return COMMAND_RETURN_ERROR; } - const char *path = mapper_get_music_directory(); + const char *path = mapper_get_music_directory_utf8(); if (path != NULL) client_printf(client, "music_directory: %s\n", path); diff --git a/src/inotify_update.c b/src/inotify_update.c index 02e55ee0b..3f4a8c0c4 100644 --- a/src/inotify_update.c +++ b/src/inotify_update.c @@ -266,7 +266,7 @@ mpd_inotify_callback(int wd, unsigned mask, (mask & IN_ISDIR) != 0) { /* a sub directory was changed: register those in inotify */ - const char *root = mapper_get_music_directory(); + const char *root = mapper_get_music_directory_fs(); const char *path_fs; char *allocated = NULL; @@ -308,7 +308,7 @@ mpd_inotify_init(unsigned max_depth) g_debug("initializing inotify"); - const char *path = mapper_get_music_directory(); + const char *path = mapper_get_music_directory_fs(); if (path == NULL) { g_debug("no music directory configured"); return; diff --git a/src/input_stream.h b/src/input_stream.h index 6a10831d2..10ad97161 100644 --- a/src/input_stream.h +++ b/src/input_stream.h @@ -29,10 +29,6 @@ #include <stdbool.h> #include <sys/types.h> -#if !GLIB_CHECK_VERSION(2,14,0) -typedef gint64 goffset; -#endif - struct input_stream { /** * the plugin which implements this input stream diff --git a/src/main.c b/src/main.c index b8823d7ef..a54ca9f3d 100644 --- a/src/main.c +++ b/src/main.c @@ -133,10 +133,8 @@ glue_mapper_init(GError **error_r) return false; } -#if GLIB_CHECK_VERSION(2,14,0) if (music_dir == NULL) music_dir = g_strdup(g_get_user_special_dir(G_USER_DIRECTORY_MUSIC)); -#endif mapper_init(music_dir, playlist_dir); diff --git a/src/mapper.c b/src/mapper.c index d230f5d92..6a968e32d 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -36,10 +36,24 @@ #include <errno.h> #include <dirent.h> -static char *music_dir; -static size_t music_dir_length; +/** + * The absolute path of the music directory encoded in UTF-8. + */ +static char *music_dir_utf8; +static size_t music_dir_utf8_length; -static char *playlist_dir; +/** + * The absolute path of the music directory encoded in the filesystem + * character set. + */ +static char *music_dir_fs; +static size_t music_dir_fs_length; + +/** + * The absolute path of the playlist directory encoded in the + * filesystem character set. + */ +static char *playlist_dir_fs; /** * Duplicate a string, chop all trailing slashes. @@ -86,20 +100,21 @@ check_directory(const char *path) } static void -mapper_set_music_dir(const char *path) +mapper_set_music_dir(const char *path_utf8) { - check_directory(path); + music_dir_utf8 = strdup_chop_slash(path_utf8); + music_dir_utf8_length = strlen(music_dir_utf8); - music_dir = strdup_chop_slash(path); - music_dir_length = strlen(music_dir); + music_dir_fs = utf8_to_fs_charset(music_dir_utf8); + check_directory(music_dir_fs); + music_dir_fs_length = strlen(music_dir_fs); } static void -mapper_set_playlist_dir(const char *path) +mapper_set_playlist_dir(const char *path_utf8) { - check_directory(path); - - playlist_dir = g_strdup(path); + playlist_dir_fs = utf8_to_fs_charset(path_utf8); + check_directory(playlist_dir_fs); } void mapper_init(const char *_music_dir, const char *_playlist_dir) @@ -113,23 +128,31 @@ void mapper_init(const char *_music_dir, const char *_playlist_dir) void mapper_finish(void) { - g_free(music_dir); - g_free(playlist_dir); + g_free(music_dir_utf8); + g_free(music_dir_fs); + g_free(playlist_dir_fs); } const char * -mapper_get_music_directory(void) +mapper_get_music_directory_utf8(void) { - return music_dir; + return music_dir_utf8; +} + +const char * +mapper_get_music_directory_fs(void) +{ + return music_dir_fs; } const char * map_to_relative_path(const char *path_utf8) { - return music_dir != NULL && - memcmp(path_utf8, music_dir, music_dir_length) == 0 && - G_IS_DIR_SEPARATOR(path_utf8[music_dir_length]) - ? path_utf8 + music_dir_length + 1 + return music_dir_utf8 != NULL && + memcmp(path_utf8, music_dir_utf8, + music_dir_utf8_length) == 0 && + G_IS_DIR_SEPARATOR(path_utf8[music_dir_utf8_length]) + ? path_utf8 + music_dir_utf8_length + 1 : path_utf8; } @@ -141,14 +164,14 @@ map_uri_fs(const char *uri) assert(uri != NULL); assert(*uri != '/'); - if (music_dir == NULL) + if (music_dir_fs == NULL) return NULL; uri_fs = utf8_to_fs_charset(uri); if (uri_fs == NULL) return NULL; - path_fs = g_build_filename(music_dir, uri_fs, NULL); + path_fs = g_build_filename(music_dir_fs, uri_fs, NULL); g_free(uri_fs); return path_fs; @@ -157,10 +180,11 @@ map_uri_fs(const char *uri) char * map_directory_fs(const struct directory *directory) { - assert(music_dir != NULL); + assert(music_dir_utf8 != NULL); + assert(music_dir_fs != NULL); if (directory_is_root(directory)) - return g_strdup(music_dir); + return g_strdup(music_dir_fs); return map_uri_fs(directory_get_path(directory)); } @@ -168,9 +192,10 @@ map_directory_fs(const struct directory *directory) char * map_directory_child_fs(const struct directory *directory, const char *name) { - char *name_fs, *parent_fs, *path; + assert(music_dir_utf8 != NULL); + assert(music_dir_fs != NULL); - assert(music_dir != NULL); + char *name_fs, *parent_fs, *path; /* check for invalid or unauthorized base names */ if (*name == 0 || strchr(name, '/') != NULL || @@ -208,11 +233,11 @@ map_song_fs(const struct song *song) char * map_fs_to_utf8(const char *path_fs) { - if (music_dir != NULL && - strncmp(path_fs, music_dir, music_dir_length) == 0 && - G_IS_DIR_SEPARATOR(path_fs[music_dir_length])) + if (music_dir_fs != NULL && + strncmp(path_fs, music_dir_fs, music_dir_fs_length) == 0 && + G_IS_DIR_SEPARATOR(path_fs[music_dir_fs_length])) /* remove musicDir prefix */ - path_fs += music_dir_length + 1; + path_fs += music_dir_fs_length + 1; else if (G_IS_DIR_SEPARATOR(path_fs[0])) /* not within musicDir */ return NULL; @@ -226,7 +251,7 @@ map_fs_to_utf8(const char *path_fs) const char * map_spl_path(void) { - return playlist_dir; + return playlist_dir_fs; } char * @@ -234,7 +259,7 @@ map_spl_utf8_to_fs(const char *name) { char *filename_utf8, *filename_fs, *path; - if (playlist_dir == NULL) + if (playlist_dir_fs == NULL) return NULL; filename_utf8 = g_strconcat(name, PLAYLIST_FILE_SUFFIX, NULL); @@ -243,7 +268,7 @@ map_spl_utf8_to_fs(const char *name) if (filename_fs == NULL) return NULL; - path = g_build_filename(playlist_dir, filename_fs, NULL); + path = g_build_filename(playlist_dir_fs, filename_fs, NULL); g_free(filename_fs); return path; diff --git a/src/mapper.h b/src/mapper.h index f57e3c9a8..b4e314569 100644 --- a/src/mapper.h +++ b/src/mapper.h @@ -39,9 +39,20 @@ void mapper_init(const char *_music_dir, const char *_playlist_dir); void mapper_finish(void); +/** + * Return the absolute path of the music directory encoded in UTF-8. + */ +gcc_const +const char * +mapper_get_music_directory_utf8(void); + +/** + * Return the absolute path of the music directory encoded in the + * filesystem character set. + */ gcc_const const char * -mapper_get_music_directory(void); +mapper_get_music_directory_fs(void); /** * Returns true if a music directory was configured. @@ -50,7 +61,7 @@ gcc_const static inline bool mapper_has_music_directory(void) { - return mapper_get_music_directory() != NULL; + return mapper_get_music_directory_utf8() != NULL; } /** diff --git a/src/playlist/lastfm_playlist_plugin.c b/src/playlist/lastfm_playlist_plugin.c index 93768660c..ead14deaa 100644 --- a/src/playlist/lastfm_playlist_plugin.c +++ b/src/playlist/lastfm_playlist_plugin.c @@ -58,12 +58,10 @@ lastfm_init(const struct config_param *param) lastfm_config.user = g_uri_escape_string(user, NULL, false); -#if GLIB_CHECK_VERSION(2,16,0) if (strlen(passwd) != 32) lastfm_config.md5 = g_compute_checksum_for_string(G_CHECKSUM_MD5, passwd, strlen(passwd)); else -#endif lastfm_config.md5 = g_strdup(passwd); return true; diff --git a/src/playlist_song.c b/src/playlist_song.c index 8a3ba303e..88ef1059d 100644 --- a/src/playlist_song.c +++ b/src/playlist_song.c @@ -83,17 +83,36 @@ apply_song_metadata(struct song *dest, const struct song *src) return tmp; } +static struct song * +playlist_check_load_song(struct song *song, const char *uri, bool secure) +{ + struct song *dest; + + if (uri_has_scheme(uri)) { + dest = song_remote_new(uri); + } else if (g_path_is_absolute(uri) && secure) { + dest = song_file_load(uri, NULL); + if (dest == NULL) + return NULL; + } else { + dest = db_get_song(uri); + if (dest == NULL) + /* not found in database */ + return NULL; + } + + return apply_song_metadata(dest, song); +} + struct song * playlist_check_translate_song(struct song *song, const char *base_uri, bool secure) { - struct song *dest; - if (song_in_database(song)) /* already ok */ return song; - char *uri = song->uri; + const char *uri = song->uri; if (uri_has_scheme(uri)) { if (uri_supported_scheme(uri)) @@ -115,11 +134,11 @@ playlist_check_translate_song(struct song *song, const char *base_uri, if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ - const char *prefix = mapper_get_music_directory(); + const char *suffix = map_to_relative_path(uri); + assert(suffix != NULL); - if (prefix != NULL && g_str_has_prefix(uri, prefix) && - uri[strlen(prefix)] == '/') - uri += strlen(prefix) + 1; + if (suffix != uri) + uri = suffix; else if (!secure) { /* local files must be relative to the music directory when "secure" is enabled */ @@ -130,32 +149,12 @@ playlist_check_translate_song(struct song *song, const char *base_uri, base_uri = NULL; } + char *allocated = NULL; if (base_uri != NULL) - uri = g_build_filename(base_uri, uri, NULL); - else - uri = g_strdup(uri); + uri = allocated = g_build_filename(base_uri, uri, NULL); - if (uri_has_scheme(uri)) { - dest = song_remote_new(uri); - g_free(uri); - } else if (g_path_is_absolute(uri) && secure) { - dest = song_file_load(uri, NULL); - if (dest == NULL) { - song_free(song); - return NULL; - } - } else { - dest = db_get_song(uri); - g_free(uri); - if (dest == NULL) { - /* not found in database */ - song_free(song); - return dest; - } - } - - dest = apply_song_metadata(dest, song); + struct song *dest = playlist_check_load_song(song, uri, secure); song_free(song); - + g_free(allocated); return dest; } |