Example #1
0
GPtrArray *
spl_load(const char *utf8path, GError **error_r)
{
	FILE *file;
	GPtrArray *list;
	char *path_fs;

	if (spl_map(error_r) == NULL)
		return NULL;

	path_fs = spl_map_to_fs(utf8path, error_r);
	if (path_fs == NULL)
		return NULL;

	file = fopen(path_fs, "r");
	g_free(path_fs);
	if (file == NULL) {
		playlist_errno(error_r);
		return NULL;
	}

	list = g_ptr_array_new();

	GString *buffer = g_string_sized_new(1024);
	char *s;
	while ((s = read_text_line(file, buffer)) != NULL) {
		if (*s == 0 || *s == PLAYLIST_COMMENT)
			continue;

		if (g_path_is_absolute(s)) {
			char *t = fs_charset_to_utf8(s);
			if (t == NULL)
				continue;

			s = g_strconcat("file://", t, NULL);
			g_free(t);
		} else if (!uri_has_scheme(s)) {
			char *path_utf8;

			path_utf8 = map_fs_to_utf8(s);
			if (path_utf8 == NULL)
				continue;

			s = path_utf8;
		} else {
			s = fs_charset_to_utf8(s);
			if (s == NULL)
				continue;
		}

		g_ptr_array_add(list, s);

		if (list->len >= playlist_max_length)
			break;
	}

	fclose(file);
	return list;
}
Example #2
0
static struct stored_playlist_info *
load_playlist_info(const char *parent_path_fs, const char *name_fs)
{
    size_t name_length = strlen(name_fs);
    char *path_fs, *name, *name_utf8;
    int ret;
    struct stat st;
    struct stored_playlist_info *playlist;

    if (name_length < sizeof(PLAYLIST_FILE_SUFFIX) ||
            memchr(name_fs, '\n', name_length) != NULL)
        return NULL;

    if (!g_str_has_suffix(name_fs, PLAYLIST_FILE_SUFFIX))
        return NULL;

    path_fs = g_build_filename(parent_path_fs, name_fs, NULL);
    ret = stat(path_fs, &st);
    g_free(path_fs);
    if (ret < 0 || !S_ISREG(st.st_mode))
        return NULL;

    name = g_strndup(name_fs,
                     name_length + 1 - sizeof(PLAYLIST_FILE_SUFFIX));
    name_utf8 = fs_charset_to_utf8(name);
    g_free(name);
    if (name_utf8 == NULL)
        return NULL;

    playlist = g_new(struct stored_playlist_info, 1);
    playlist->name = name_utf8;
    playlist->mtime = st.st_mtime;
    return playlist;
}
Example #3
0
static void
mpd_inotify_callback(int wd, unsigned mask,
		     G_GNUC_UNUSED const char *name, G_GNUC_UNUSED void *ctx)
{
	struct watch_directory *directory;
	char *uri_fs;

	/*g_debug("wd=%d mask=0x%x name='%s'", wd, mask, name);*/

	directory = tree_find_watch_directory(wd);
	if (directory == NULL)
		return;

	uri_fs = watch_directory_get_uri_fs(directory);

	if ((mask & (IN_DELETE_SELF|IN_MOVE_SELF)) != 0) {
		g_free(uri_fs);
		remove_watch_directory(directory);
		return;
	}

	if ((mask & (IN_ATTRIB|IN_CREATE|IN_MOVE)) != 0 &&
	    (mask & IN_ISDIR) != 0) {
		/* a sub directory was changed: register those in
		   inotify */
		const char *root = mapper_get_music_directory_fs();
		const char *path_fs;
		char *allocated = NULL;

		if (uri_fs != NULL)
			path_fs = allocated =
				g_strconcat(root, "/", uri_fs, NULL);
		else
			path_fs = root;

		recursive_watch_subdirectories(directory, path_fs,
					       watch_directory_depth(directory));
		g_free(allocated);
	}

	if ((mask & (IN_CLOSE_WRITE|IN_MOVE|IN_DELETE)) != 0 ||
	    /* at the maximum depth, we watch out for newly created
	       directories */
	    (watch_directory_depth(directory) == inotify_max_depth &&
	     (mask & (IN_CREATE|IN_ISDIR)) == (IN_CREATE|IN_ISDIR))) {
		/* a file was changed, or a directory was
		   moved/deleted: queue a database update */
		char *uri_utf8 = uri_fs != NULL
			? fs_charset_to_utf8(uri_fs)
			: g_strdup("");

		if (uri_utf8 != NULL)
			/* this function will take care of freeing
			   uri_utf8 */
			mpd_inotify_enqueue(uri_utf8);
	}

	g_free(uri_fs);
}
Example #4
0
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]))
		/* remove musicDir prefix */
		path_fs += music_dir_length + 1;
	else if (G_IS_DIR_SEPARATOR(path_fs[0]))
		/* not within musicDir */
		return NULL;

	while (path_fs[0] == G_DIR_SEPARATOR)
		++path_fs;

	return fs_charset_to_utf8(path_fs);
}
Example #5
0
static struct song *
apply_song_metadata(struct song *dest, const struct song *src)
{
	struct song *tmp;

	assert(dest != NULL);
	assert(src != NULL);

	if (src->tag == NULL && src->start_ms == 0 && src->end_ms == 0)
		return dest;

	if (song_in_database(dest)) {
		char *path_fs = map_song_fs(dest);
		if (path_fs == NULL)
			return dest;

		char *path_utf8 = fs_charset_to_utf8(path_fs);
		if (path_utf8 != NULL)
			g_free(path_fs);
		else
			path_utf8 = path_fs;

		tmp = song_file_new(path_utf8, NULL);
		g_free(path_utf8);

		merge_song_metadata(tmp, dest, src);
	} else {
		tmp = song_file_new(dest->uri, NULL);
		merge_song_metadata(tmp, dest, src);
	}

	if (dest->tag != NULL && dest->tag->time > 0 &&
	    src->start_ms > 0 && src->end_ms == 0 &&
	    src->start_ms / 1000 < (unsigned)dest->tag->time)
		/* the range is open-ended, and the playlist plugin
		   did not know the total length of the song file
		   (e.g. last track on a CUE file); fix it up here */
		tmp->tag->time = dest->tag->time - src->start_ms / 1000;

	song_free(dest);
	return tmp;
}
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;
}