aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/playlist.c58
-rw-r--r--src/playlist.h2
-rw-r--r--src/storedPlaylist.c23
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;