char * map_directory_child_fs(const struct directory *directory, const char *name) { char *name_fs, *parent_fs, *path; assert(music_dir != NULL); /* check for invalid or unauthorized base names */ if (*name == 0 || strchr(name, '/') != NULL || strcmp(name, ".") == 0 || strcmp(name, "..") == 0) return NULL; parent_fs = map_directory_fs(directory); if (parent_fs == NULL) return NULL; name_fs = utf8_to_fs_charset(name); if (name_fs == NULL) { g_free(parent_fs); return NULL; } path = g_build_filename(parent_fs, name_fs, NULL); g_free(parent_fs); g_free(name_fs); return path; }
static int stat_directory(const struct directory *directory, struct stat *st) { char *path_fs; int ret; path_fs = map_directory_fs(directory); if (path_fs == NULL) return -1; ret = stat(path_fs, st); g_free(path_fs); return ret; }
static int stat_directory(const struct directory *directory, struct stat *st) { char *path_fs; int ret; path_fs = map_directory_fs(directory); if (path_fs == NULL) return -1; ret = stat(path_fs, st); if (ret < 0) g_warning("Failed to stat %s: %s", path_fs, g_strerror(errno)); g_free(path_fs); return ret; }
static bool directory_exists(const struct directory *directory) { char *path_fs; GFileTest test; bool exists; path_fs = map_directory_fs(directory); if (path_fs == NULL) /* invalid path: cannot exist */ return false; test = directory->device == DEVICE_INARCHIVE || directory->device == DEVICE_CONTAINER ? G_FILE_TEST_IS_REGULAR : G_FILE_TEST_IS_DIR; exists = g_file_test(path_fs, test); g_free(path_fs); return exists; }
static bool updateDirectory(struct directory *directory, const struct stat *st) { DIR *dir; struct dirent *ent; char *path_fs, *exclude_path_fs; GSList *exclude_list; assert(S_ISDIR(st->st_mode)); directory_set_stat(directory, st); path_fs = map_directory_fs(directory); if (path_fs == NULL) return false; dir = opendir(path_fs); if (!dir) { g_warning("Failed to open directory %s: %s", path_fs, g_strerror(errno)); g_free(path_fs); return false; } exclude_path_fs = g_build_filename(path_fs, ".mpdignore", NULL); exclude_list = exclude_list_load(exclude_path_fs); g_free(exclude_path_fs); g_free(path_fs); if (exclude_list != NULL) remove_excluded_from_directory(directory, exclude_list); removeDeletedFromDirectory(directory); while ((ent = readdir(dir))) { char *utf8; struct stat st2; if (skip_path(ent->d_name) || exclude_list_check(exclude_list, ent->d_name)) continue; utf8 = fs_charset_to_utf8(ent->d_name); if (utf8 == NULL) continue; if (skip_symlink(directory, utf8)) { delete_name_in(directory, utf8); g_free(utf8); continue; } if (stat_directory_child(directory, utf8, &st2) == 0) updateInDirectory(directory, utf8, &st2); else delete_name_in(directory, utf8); g_free(utf8); } exclude_list_free(exclude_list); closedir(dir); directory->mtime = st->st_mtime; return true; }
struct song * playlist_check_translate_song(struct song *song, const char *base_uri) { struct song *dest; if (song_in_database(song)) /* already ok */ return song; char *uri = song->uri; if (uri_has_scheme(uri)) { if (uri_supported_scheme(uri)) /* valid remote song */ return song; else { /* unsupported remote song */ song_free(song); return NULL; } } if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ char *prefix = base_uri != NULL ? map_uri_fs(base_uri) : map_directory_fs(db_get_root()); if (prefix == NULL || !g_str_has_prefix(uri, prefix) || uri[strlen(prefix)] != '/') { /* local files must be relative to the music directory */ g_free(prefix); song_free(song); return NULL; } uri += strlen(prefix) + 1; g_free(prefix); } if (base_uri != NULL) uri = g_build_filename(base_uri, uri, NULL); else uri = g_strdup(uri); if (uri_has_scheme(base_uri)) { dest = song_remote_new(uri); g_free(uri); } 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); song_free(song); return dest; }