configure.ac: Move OpenAL to Audio Output Plugins (nonstreaming), add header.
[mpd-mk.git] / src / mapper.c
blob03822ca9e0ce0b529ce517927c1f8e387c0198c9
1 /*
2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Maps directory and song objects to file system paths.
24 #include "config.h"
25 #include "mapper.h"
26 #include "directory.h"
27 #include "song.h"
28 #include "path.h"
30 #include <glib.h>
32 #include <assert.h>
33 #include <string.h>
35 static char *music_dir;
36 static size_t music_dir_length;
38 static char *playlist_dir;
40 /**
41 * Duplicate a string, chop all trailing slashes.
43 static char *
44 strdup_chop_slash(const char *path_fs)
46 size_t length = strlen(path_fs);
48 while (length > 0 && path_fs[length - 1] == G_DIR_SEPARATOR)
49 --length;
51 return g_strndup(path_fs, length);
54 static void
55 mapper_set_music_dir(const char *path)
57 music_dir = strdup_chop_slash(path);
58 music_dir_length = strlen(music_dir);
60 if (!g_file_test(music_dir, G_FILE_TEST_IS_DIR))
61 g_warning("music directory is not a directory: \"%s\"",
62 music_dir);
65 static void
66 mapper_set_playlist_dir(const char *path)
68 playlist_dir = g_strdup(path);
70 if (!g_file_test(playlist_dir, G_FILE_TEST_IS_DIR))
71 g_warning("playlist directory is not a directory: \"%s\"",
72 playlist_dir);
75 void mapper_init(const char *_music_dir, const char *_playlist_dir)
77 if (_music_dir != NULL)
78 mapper_set_music_dir(_music_dir);
80 if (_playlist_dir != NULL)
81 mapper_set_playlist_dir(_playlist_dir);
84 void mapper_finish(void)
86 g_free(music_dir);
87 g_free(playlist_dir);
90 bool
91 mapper_has_music_directory(void)
93 return music_dir != NULL;
96 char *
97 map_uri_fs(const char *uri)
99 char *uri_fs, *path_fs;
101 assert(uri != NULL);
102 assert(*uri != '/');
104 if (music_dir == NULL)
105 return NULL;
107 uri_fs = utf8_to_fs_charset(uri);
108 if (uri_fs == NULL)
109 return NULL;
111 path_fs = g_build_filename(music_dir, uri_fs, NULL);
112 g_free(uri_fs);
114 return path_fs;
117 char *
118 map_directory_fs(const struct directory *directory)
120 assert(music_dir != NULL);
122 if (directory_is_root(directory))
123 return g_strdup(music_dir);
125 return map_uri_fs(directory_get_path(directory));
128 char *
129 map_directory_child_fs(const struct directory *directory, const char *name)
131 char *name_fs, *parent_fs, *path;
133 assert(music_dir != NULL);
135 /* check for invalid or unauthorized base names */
136 if (*name == 0 || strchr(name, '/') != NULL ||
137 strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
138 return NULL;
140 parent_fs = map_directory_fs(directory);
141 if (parent_fs == NULL)
142 return NULL;
144 name_fs = utf8_to_fs_charset(name);
145 if (name_fs == NULL) {
146 g_free(parent_fs);
147 return NULL;
150 path = g_build_filename(parent_fs, name_fs, NULL);
151 g_free(parent_fs);
152 g_free(name_fs);
154 return path;
157 char *
158 map_song_fs(const struct song *song)
160 assert(song_is_file(song));
162 if (song_in_database(song))
163 return map_directory_child_fs(song->parent, song->uri);
164 else
165 return utf8_to_fs_charset(song->uri);
168 char *
169 map_fs_to_utf8(const char *path_fs)
171 if (music_dir != NULL &&
172 strncmp(path_fs, music_dir, music_dir_length) == 0 &&
173 G_IS_DIR_SEPARATOR(path_fs[music_dir_length]))
174 /* remove musicDir prefix */
175 path_fs += music_dir_length + 1;
176 else if (G_IS_DIR_SEPARATOR(path_fs[0]))
177 /* not within musicDir */
178 return NULL;
180 while (path_fs[0] == G_DIR_SEPARATOR)
181 ++path_fs;
183 return fs_charset_to_utf8(path_fs);
186 const char *
187 map_spl_path(void)
189 return playlist_dir;
192 char *
193 map_spl_utf8_to_fs(const char *name)
195 char *filename_utf8, *filename_fs, *path;
197 if (playlist_dir == NULL)
198 return NULL;
200 filename_utf8 = g_strconcat(name, PLAYLIST_FILE_SUFFIX, NULL);
201 filename_fs = utf8_to_fs_charset(filename_utf8);
202 g_free(filename_utf8);
203 if (filename_fs == NULL)
204 return NULL;
206 path = g_build_filename(playlist_dir, filename_fs, NULL);
207 g_free(filename_fs);
209 return path;