diff options
-rw-r--r-- | src/playlist.c | 58 | ||||
-rw-r--r-- | src/playlist.h | 2 | ||||
-rw-r--r-- | src/storedPlaylist.c | 23 |
3 files changed, 54 insertions, 29 deletions
diff --git a/src/playlist.c b/src/playlist.c index 6d47bdb8f..77e94b76b 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -1418,17 +1418,38 @@ int deletePlaylist(int fd, char *utf8file) int savePlaylist(int fd, char *utf8file) { - StoredPlaylist *sp = newStoredPlaylist(utf8file, fd, 0); - if (!sp) + FILE *fp; + int i; + struct stat sb; + char path_max_tmp[MPD_PATH_MAX]; + + if (!valid_playlist_name(fd, utf8file)) return -1; - appendPlaylistToStoredPlaylist(sp, &playlist); - if (writeStoredPlaylist(sp) != 0) { - freeStoredPlaylist(sp); + utf8_to_fs_playlist_path(path_max_tmp, utf8file); + if (!stat(path_max_tmp, &sb)) { + commandError(fd, ACK_ERROR_EXIST, "a file or directory already " + "exists with the name \"%s\"", utf8file); return -1; } - freeStoredPlaylist(sp); + while (!(fp = fopen(path_max_tmp, "w")) && errno == EINTR); + + for (i = 0; i < playlist.length; i++) { + char tmp[MPD_PATH_MAX]; + + get_song_url(path_max_tmp, playlist.songs[i]); + utf8_to_fs_charset(tmp, path_max_tmp); + + if (playlist_saveAbsolutePaths && + playlist.songs[i]->type == SONG_TYPE_FILE) + fprintf(fp, "%s\n", rmp2amp_r(tmp, tmp)); + else + fprintf(fp, "%s\n", tmp); + } + + while (fclose(fp) && errno == EINTR) ; + return 0; } @@ -1679,3 +1700,28 @@ int playlistQueueInfo(int fd) } return 0; } + +/* + * Not supporting '/' was done out of laziness, and we should really + * strive to support it in the future. + * + * Not supporting '\r' and '\n' is done out of protocol limitations (and + * arguably laziness), but bending over head over heels to modify the + * protocol (and compatibility with all clients) to support idiots who + * put '\r' and '\n' in filenames isn't going to happen, either. + */ +int valid_playlist_name(int err_fd, const char *utf8path) +{ + if (strchr(utf8path, '/') || + strchr(utf8path, '\n') || + strchr(utf8path, '\r')) { + commandError(err_fd, ACK_ERROR_ARG, "playlist name \"%s\" is " + "invalid: playlist names may not contain slashes," + " newlines or carriage returns", + utf8path); + return 0; + } + return 1; +} + + diff --git a/src/playlist.h b/src/playlist.h index 6576ff27b..c725e8612 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -156,4 +156,6 @@ int deleteFromPlaylistQueueInternal(int song); int playlistQueueInfo(int fd); +int valid_playlist_name(int err_fd, const char *utf8path); + #endif diff --git a/src/storedPlaylist.c b/src/storedPlaylist.c index 062a0ad1f..68122b5b4 100644 --- a/src/storedPlaylist.c +++ b/src/storedPlaylist.c @@ -29,29 +29,6 @@ #include <string.h> #include <errno.h> -/* - * Not supporting '/' was done out of laziness, and we should really - * strive to support it in the future. - * - * Not supporting '\r' and '\n' is done out of protocol limitations (and - * arguably laziness), but bending over head over heels to modify the - * protocol (and compatibility with all clients) to support idiots who - * put '\r' and '\n' in filenames isn't going to happen, either. - */ -static int valid_playlist_name(int err_fd, const char *utf8path) -{ - if (strchr(utf8path, '/') || - strchr(utf8path, '\n') || - strchr(utf8path, '\r')) { - commandError(err_fd, ACK_ERROR_ARG, "playlist name \"%s\" is " - "invalid: playlist names may not contain slashes," - " newlines or carriage returns", - utf8path); - return 0; - } - return 1; -} - static unsigned int lengthOfStoredPlaylist(StoredPlaylist *sp) { return sp->list->numberOfNodes; |