playlist: avoid the use of newStoredPlaylist for saving active playlists

It was a nice way to double the memory needed to write the
playlist to a file.

git-svn-id: https://svn.musicpd.org/mpd/trunk@7116 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
Eric Wong 2008-01-01 10:09:18 +00:00
parent 47efe42321
commit 68b9f41381
3 changed files with 54 additions and 29 deletions

View File

@ -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;
}

View File

@ -156,4 +156,6 @@ int deleteFromPlaylistQueueInternal(int song);
int playlistQueueInfo(int fd);
int valid_playlist_name(int err_fd, const char *utf8path);
#endif

View File

@ -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;