playlist: don't pass "fd" to playlist.c functions
The playlist library shouldn't talk to the client if possible. Introduce the "enum playlist_result" type which the caller (i.e. command.c) may use to generate an error message.
This commit is contained in:
		
							
								
								
									
										160
									
								
								src/command.c
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								src/command.c
									
									
									
									
									
								
							| @@ -220,6 +220,53 @@ static int mpd_fprintf__ check_int(int fd, int *dst, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int print_playlist_result(int fd, enum playlist_result result) | ||||
| { | ||||
| 	switch (result) { | ||||
| 	case PLAYLIST_RESULT_SUCCESS: | ||||
| 		return 0; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_ERRNO: | ||||
| 		commandError(fd, ACK_ERROR_SYSTEM, strerror(errno)); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_NO_SUCH_SONG: | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, "No such song"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_NO_SUCH_LIST: | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, "No such playlist"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_LIST_EXISTS: | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "Playlist already exists"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_BAD_NAME: | ||||
| 		commandError(fd, ACK_ERROR_ARG, | ||||
| 			     "playlist name is invalid: " | ||||
| 			     "playlist names may not contain slashes," | ||||
| 			     " newlines or carriage returns"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_BAD_RANGE: | ||||
| 		commandError(fd, ACK_ERROR_ARG, "Bad song index"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_NOT_PLAYING: | ||||
| 		commandError(fd, ACK_ERROR_PLAYER_SYNC, "Not playing"); | ||||
| 		return -1; | ||||
|  | ||||
| 	case PLAYLIST_RESULT_TOO_LARGE: | ||||
| 		commandError(fd, ACK_ERROR_PLAYLIST_MAX, | ||||
| 			     "playlist is at the max size"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	assert(0); | ||||
| } | ||||
|  | ||||
| static void addCommand(const char *name, | ||||
| 		       int reqPermission, | ||||
| 		       int minargs, | ||||
| @@ -255,21 +302,25 @@ static int handlePlay(int fd, mpd_unused int *permission, | ||||
| 		      int argc, char *argv[]) | ||||
| { | ||||
| 	int song = -1; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (argc == 2 && check_int(fd, &song, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
| 	return playPlaylist(fd, song, 0); | ||||
| 	result = playPlaylist(song, 0); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handlePlayId(int fd, mpd_unused int *permission, | ||||
| 			int argc, char *argv[]) | ||||
| { | ||||
| 	int id = -1; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (argc == 2 && check_int(fd, &id, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
|  | ||||
| 	return playPlaylistById(fd, id, 0); | ||||
| 	result = playPlaylistById(id, 0); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleStop(mpd_unused int fd, mpd_unused int *permission, | ||||
| @@ -283,11 +334,13 @@ static int handleCurrentSong(int fd, mpd_unused int *permission, | ||||
| 			     mpd_unused int argc, mpd_unused char *argv[]) | ||||
| { | ||||
| 	int song = getPlaylistCurrentSong(); | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (song >= 0) { | ||||
| 		return playlistInfo(fd, song); | ||||
| 	} else | ||||
| 	if (song < 0) | ||||
| 		return 0; | ||||
|  | ||||
| 	result = playlistInfo(fd, song); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handlePause(int fd, mpd_unused int *permission, | ||||
| @@ -384,54 +437,65 @@ static int handleAdd(int fd, mpd_unused int *permission, | ||||
| 		     mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	char *path = argv[1]; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (isRemoteUrl(path)) | ||||
| 		return addToPlaylist(fd, path, NULL); | ||||
| 		return addToPlaylist(path, NULL); | ||||
|  | ||||
| 	return addAllIn(fd, path); | ||||
| 	result = addAllIn(fd, path); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleAddId(int fd, mpd_unused int *permission, | ||||
| 		       int argc, char *argv[]) | ||||
| { | ||||
| 	int added_id; | ||||
| 	int ret = addToPlaylist(fd, argv[1], &added_id); | ||||
| 	enum playlist_result result = addToPlaylist(argv[1], &added_id); | ||||
|  | ||||
| 	if (!ret) { | ||||
| 		if (argc == 3) { | ||||
| 			int to; | ||||
| 			if (check_int(fd, &to, argv[2], | ||||
| 			              check_integer, argv[2]) < 0) | ||||
| 				return -1; | ||||
| 			ret = moveSongInPlaylistById(fd, added_id, to); | ||||
| 			if (ret) { /* move failed */ | ||||
| 				deleteFromPlaylistById(fd, added_id); | ||||
| 				return ret; | ||||
| 			} | ||||
| 	if (result == PLAYLIST_RESULT_SUCCESS) | ||||
| 		return result; | ||||
|  | ||||
| 	if (argc == 3) { | ||||
| 		int to; | ||||
| 		if (check_int(fd, &to, argv[2], | ||||
| 			      check_integer, argv[2]) < 0) | ||||
| 			return -1; | ||||
| 		result = moveSongInPlaylistById(added_id, to); | ||||
| 		if (result != PLAYLIST_RESULT_SUCCESS) { | ||||
| 			int ret = print_playlist_result(fd, result); | ||||
| 			deleteFromPlaylistById(added_id); | ||||
| 			return ret; | ||||
| 		} | ||||
| 		fdprintf(fd, "Id: %d\n", added_id); | ||||
| 	} | ||||
| 	return ret; | ||||
|  | ||||
| 	fdprintf(fd, "Id: %d\n", added_id); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| static int handleDelete(int fd, mpd_unused int *permission, | ||||
| 			mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int song; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &song, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
| 	return deleteFromPlaylist(fd, song); | ||||
|  | ||||
| 	result = deleteFromPlaylist(song); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleDeleteId(int fd, mpd_unused int *permission, | ||||
| 			  mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int id; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &id, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
| 	return deleteFromPlaylistById(fd, id); | ||||
|  | ||||
| 	result = deleteFromPlaylistById(id); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handlePlaylist(int fd, mpd_unused int *permission, | ||||
| @@ -441,10 +505,10 @@ static int handlePlaylist(int fd, mpd_unused int *permission, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int handleShuffle(int fd, mpd_unused int *permission, | ||||
| static int handleShuffle(mpd_unused int fd, mpd_unused int *permission, | ||||
| 			 mpd_unused int argc, mpd_unused char *argv[]) | ||||
| { | ||||
| 	shufflePlaylist(fd); | ||||
| 	shufflePlaylist(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -458,7 +522,10 @@ static int handleClear(mpd_unused int fd, mpd_unused int *permission, | ||||
| static int handleSave(int fd, mpd_unused int *permission, | ||||
| 		      mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	return savePlaylist(fd, argv[1]); | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	result = savePlaylist(argv[1]); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleLoad(int fd, mpd_unused int *permission, | ||||
| @@ -499,7 +566,10 @@ static int handleLsInfo(int fd, mpd_unused int *permission, | ||||
| static int handleRm(int fd, mpd_unused int *permission, | ||||
| 		    mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	return deletePlaylist(fd, argv[1]); | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	result = deletePlaylist(argv[1]); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleRename(int fd, mpd_unused int *permission, | ||||
| @@ -532,20 +602,26 @@ static int handlePlaylistInfo(int fd, mpd_unused int *permission, | ||||
| 			      int argc, char *argv[]) | ||||
| { | ||||
| 	int song = -1; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (argc == 2 && check_int(fd, &song, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
| 	return playlistInfo(fd, song); | ||||
|  | ||||
| 	result = playlistInfo(fd, song); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handlePlaylistId(int fd, mpd_unused int *permission, | ||||
| 			    int argc, char *argv[]) | ||||
| { | ||||
| 	int id = -1; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (argc == 2 && check_int(fd, &id, argv[1], need_positive) < 0) | ||||
| 		return -1; | ||||
| 	return playlistId(fd, id); | ||||
|  | ||||
| 	result = playlistId(fd, id); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleFind(int fd, mpd_unused int *permission, | ||||
| @@ -871,72 +947,86 @@ static int handleMove(int fd, mpd_unused int *permission, | ||||
| 		      mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int from, to; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &from, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &to, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return moveSongInPlaylist(fd, from, to); | ||||
| 	result = moveSongInPlaylist(from, to); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleMoveId(int fd, mpd_unused int *permission, | ||||
| 			mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int id, to; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &id, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &to, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return moveSongInPlaylistById(fd, id, to); | ||||
| 	result = moveSongInPlaylistById(id, to); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleSwap(int fd, mpd_unused int *permission, | ||||
| 		      mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int song1, song2; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &song1, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &song2, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return swapSongsInPlaylist(fd, song1, song2); | ||||
| 	result = swapSongsInPlaylist(song1, song2); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleSwapId(int fd, mpd_unused int *permission, | ||||
| 			mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int id1, id2; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &id1, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &id2, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return swapSongsInPlaylistById(fd, id1, id2); | ||||
| 	result = swapSongsInPlaylistById(id1, id2); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleSeek(int fd, mpd_unused int *permission, | ||||
| 		      mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int song, seek_time; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &song, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &seek_time, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return seekSongInPlaylist(fd, song, seek_time); | ||||
|  | ||||
| 	result = seekSongInPlaylist(song, seek_time); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleSeekId(int fd, mpd_unused int *permission, | ||||
| 			mpd_unused int argc, char *argv[]) | ||||
| { | ||||
| 	int id, seek_time; | ||||
| 	enum playlist_result result; | ||||
|  | ||||
| 	if (check_int(fd, &id, argv[1], check_integer, argv[1]) < 0) | ||||
| 		return -1; | ||||
| 	if (check_int(fd, &seek_time, argv[2], check_integer, argv[2]) < 0) | ||||
| 		return -1; | ||||
| 	return seekSongInPlaylistById(fd, id, seek_time); | ||||
|  | ||||
| 	result = seekSongInPlaylistById(id, seek_time); | ||||
| 	return print_playlist_result(fd, result); | ||||
| } | ||||
|  | ||||
| static int handleListAllInfo(int fd, mpd_unused int *permission, | ||||
|   | ||||
| @@ -174,10 +174,10 @@ int printAllIn(int fd, const char *name) | ||||
| 			     printDirectoryInDirectory, NULL); | ||||
| } | ||||
|  | ||||
| static int directoryAddSongToPlaylist(int fd, Song * song, | ||||
| static int directoryAddSongToPlaylist(mpd_unused int fd, Song * song, | ||||
| 				      mpd_unused void *data) | ||||
| { | ||||
| 	return addSongToPlaylist(fd, song, NULL); | ||||
| 	return addSongToPlaylist(song, NULL); | ||||
| } | ||||
|  | ||||
| static int directoryAddSongToStoredPlaylist(int fd, Song *song, void *data) | ||||
|   | ||||
							
								
								
									
										221
									
								
								src/playlist.c
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								src/playlist.c
									
									
									
									
									
								
							| @@ -274,18 +274,16 @@ static void loadPlaylistFromStateFile(FILE *fp, char *buffer, | ||||
| 		song = atoi(temp); | ||||
| 		if (!(temp = strtok(NULL, ""))) | ||||
| 			state_file_fatal(); | ||||
| 		if (!addToPlaylist(STDERR_FILENO, temp, NULL) | ||||
| 		if (addToPlaylist(temp, NULL) == PLAYLIST_RESULT_SUCCESS | ||||
| 		    && current == song) { | ||||
| 			if (state != PLAYER_STATE_STOP) { | ||||
| 				playPlaylist(STDERR_FILENO, | ||||
| 					     playlist.length - 1, 0); | ||||
| 				playPlaylist(playlist.length - 1, 0); | ||||
| 			} | ||||
| 			if (state == PLAYER_STATE_PAUSE) { | ||||
| 				playerPause(); | ||||
| 			} | ||||
| 			if (state != PLAYER_STATE_STOP) { | ||||
| 				seekSongInPlaylist(STDERR_FILENO, | ||||
| 						   playlist.length - 1, | ||||
| 				seekSongInPlaylist(playlist.length - 1, | ||||
| 						   seek_time); | ||||
| 			} | ||||
| 		} | ||||
| @@ -408,7 +406,7 @@ int playlistChangesPosId(int fd, mpd_uint32 version) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int playlistInfo(int fd, int song) | ||||
| enum playlist_result playlistInfo(int fd, int song) | ||||
| { | ||||
| 	int i; | ||||
| 	int begin = 0; | ||||
| @@ -418,36 +416,31 @@ int playlistInfo(int fd, int song) | ||||
| 		begin = song; | ||||
| 		end = song + 1; | ||||
| 	} | ||||
| 	if (song >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (song >= playlist.length) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	for (i = begin; i < end; i++) | ||||
| 		printPlaylistSongInfo(fd, i); | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| # define checkSongId(id) { \ | ||||
| 	if(id < 0 || id >= PLAYLIST_HASH_MULT*playlist_max_length || \ | ||||
| 			playlist.idToPosition[id] == -1 ) \ | ||||
| 	{ \ | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, \ | ||||
| 			"song id doesn't exist: \"%i\"", id); \ | ||||
| 		return -1; \ | ||||
| 	} \ | ||||
| static int song_id_exists(int id) | ||||
| { | ||||
| 	return id >= 0 && id < PLAYLIST_HASH_MULT*playlist_max_length && | ||||
| 		playlist.idToPosition[id] != -1; | ||||
| } | ||||
|  | ||||
| int playlistId(int fd, int id) | ||||
| enum playlist_result playlistId(int fd, int id) | ||||
| { | ||||
| 	int i; | ||||
| 	int begin = 0; | ||||
| 	int end = playlist.length; | ||||
|  | ||||
| 	if (id >= 0) { | ||||
| 		checkSongId(id); | ||||
| 		if (!song_id_exists(id)) | ||||
| 			return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 		begin = playlist.idToPosition[id]; | ||||
| 		end = begin + 1; | ||||
| 	} | ||||
| @@ -455,7 +448,7 @@ int playlistId(int fd, int id) | ||||
| 	for (i = begin; i < end; i++) | ||||
| 		printPlaylistSongInfo(fd, i); | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| static void swapSongs(int song1, int song2) | ||||
| @@ -560,7 +553,7 @@ static void clearPlayerQueue(void) | ||||
| 	playerQueueUnlock(); | ||||
| } | ||||
|  | ||||
| int addToPlaylist(int fd, const char *url, int *added_id) | ||||
| enum playlist_result addToPlaylist(const char *url, int *added_id) | ||||
| { | ||||
| 	Song *song; | ||||
|  | ||||
| @@ -569,13 +562,10 @@ int addToPlaylist(int fd, const char *url, int *added_id) | ||||
| 	if ((song = getSongFromDB(url))) { | ||||
| 	} else if (!(isValidRemoteUtf8Url(url) && | ||||
| 		     (song = newSong(url, SONG_TYPE_URL, NULL)))) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "\"%s\" is not in the music db or is " | ||||
| 			     "not a valid url", url); | ||||
| 		return -1; | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
| 	} | ||||
|  | ||||
| 	return addSongToPlaylist(fd, song, added_id); | ||||
| 	return addSongToPlaylist(song, added_id); | ||||
| } | ||||
|  | ||||
| int addToStoredPlaylist(int fd, const char *url, const char *utf8file) | ||||
| @@ -606,15 +596,12 @@ fail: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| int addSongToPlaylist(int fd, Song * song, int *added_id) | ||||
| enum playlist_result addSongToPlaylist(Song * song, int *added_id) | ||||
| { | ||||
| 	int id; | ||||
|  | ||||
| 	if (playlist.length == playlist_max_length) { | ||||
| 		commandError(fd, ACK_ERROR_PLAYLIST_MAX, | ||||
| 			     "playlist is at the max size"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (playlist.length == playlist_max_length) | ||||
| 		return PLAYLIST_RESULT_TOO_LARGE; | ||||
|  | ||||
| 	if (playlist_state == PLAYLIST_STATE_PLAY) { | ||||
| 		if (playlist.queued >= 0 | ||||
| @@ -652,24 +639,17 @@ int addSongToPlaylist(int fd, Song * song, int *added_id) | ||||
| 	if (added_id) | ||||
| 		*added_id = id; | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int swapSongsInPlaylist(int fd, int song1, int song2) | ||||
| enum playlist_result swapSongsInPlaylist(int song1, int song2) | ||||
| { | ||||
| 	int queuedSong = -1; | ||||
| 	int currentSong; | ||||
|  | ||||
| 	if (song1 < 0 || song1 >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song1); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (song2 < 0 || song2 >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song2); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (song1 < 0 || song1 >= playlist.length || | ||||
| 	    song2 < 0 || song2 >= playlist.length) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	if (playlist_state == PLAYLIST_STATE_PLAY) { | ||||
| 		if (playlist.queued >= 0) { | ||||
| @@ -705,15 +685,15 @@ int swapSongsInPlaylist(int fd, int song1, int song2) | ||||
|  | ||||
| 	incrPlaylistVersion(); | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int swapSongsInPlaylistById(int fd, int id1, int id2) | ||||
| enum playlist_result swapSongsInPlaylistById(int id1, int id2) | ||||
| { | ||||
| 	checkSongId(id1); | ||||
| 	checkSongId(id2); | ||||
| 	if (!song_id_exists(id1) || !song_id_exists(id2)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 	return swapSongsInPlaylist(fd, playlist.idToPosition[id1], | ||||
| 	return swapSongsInPlaylist(playlist.idToPosition[id1], | ||||
| 				   playlist.idToPosition[id2]); | ||||
| } | ||||
|  | ||||
| @@ -724,16 +704,13 @@ int swapSongsInPlaylistById(int fd, int id1, int id2) | ||||
| 	playlist.songMod[to] = playlist.version; \ | ||||
| } | ||||
|  | ||||
| int deleteFromPlaylist(int fd, int song) | ||||
| enum playlist_result deleteFromPlaylist(int song) | ||||
| { | ||||
| 	int i; | ||||
| 	int songOrder; | ||||
|  | ||||
| 	if (song < 0 || song >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (song < 0 || song >= playlist.length) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	if (playlist_state == PLAYLIST_STATE_PLAY) { | ||||
| 		if (playlist.queued >= 0 | ||||
| @@ -790,14 +767,15 @@ int deleteFromPlaylist(int fd, int song) | ||||
| 		playlist.queued--; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int deleteFromPlaylistById(int fd, int id) | ||||
| enum playlist_result deleteFromPlaylistById(int id) | ||||
| { | ||||
| 	checkSongId(id); | ||||
| 	if (!song_id_exists(id)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 	return deleteFromPlaylist(fd, playlist.idToPosition[id]); | ||||
| 	return deleteFromPlaylist(playlist.idToPosition[id]); | ||||
| } | ||||
|  | ||||
| void deleteASongFromPlaylist(Song * song) | ||||
| @@ -809,7 +787,7 @@ void deleteASongFromPlaylist(Song * song) | ||||
|  | ||||
| 	for (i = 0; i < playlist.length; i++) { | ||||
| 		if (song == playlist.songs[i]) { | ||||
| 			deleteFromPlaylist(STDERR_FILENO, i); | ||||
| 			deleteFromPlaylist(i); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -841,7 +819,7 @@ static void playPlaylistOrderNumber(int orderNum) | ||||
| 	playlist.current = orderNum; | ||||
| } | ||||
|  | ||||
| int playPlaylist(int fd, int song, int stopOnError) | ||||
| enum playlist_result playPlaylist(int song, int stopOnError) | ||||
| { | ||||
| 	int i = song; | ||||
|  | ||||
| @@ -849,11 +827,11 @@ int playPlaylist(int fd, int song, int stopOnError) | ||||
|  | ||||
| 	if (song == -1) { | ||||
| 		if (playlist.length == 0) | ||||
| 			return 0; | ||||
| 			return PLAYLIST_RESULT_SUCCESS; | ||||
|  | ||||
| 		if (playlist_state == PLAYLIST_STATE_PLAY) { | ||||
| 			playerSetPause(0); | ||||
| 			return 0; | ||||
| 			return PLAYLIST_RESULT_SUCCESS; | ||||
| 		} | ||||
| 		if (playlist.current >= 0 && playlist.current < playlist.length) { | ||||
| 			i = playlist.current; | ||||
| @@ -861,9 +839,7 @@ int playPlaylist(int fd, int song, int stopOnError) | ||||
| 			i = 0; | ||||
| 		} | ||||
| 	} else if (song < 0 || song >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song); | ||||
| 		return -1; | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
| 	} | ||||
|  | ||||
| 	if (playlist.random) { | ||||
| @@ -884,18 +860,19 @@ int playPlaylist(int fd, int song, int stopOnError) | ||||
| 	playlist_errorCount = 0; | ||||
|  | ||||
| 	playPlaylistOrderNumber(i); | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int playPlaylistById(int fd, int id, int stopOnError) | ||||
| enum playlist_result playPlaylistById(int id, int stopOnError) | ||||
| { | ||||
| 	if (id == -1) { | ||||
| 		return playPlaylist(fd, id, stopOnError); | ||||
| 		return playPlaylist(id, stopOnError); | ||||
| 	} | ||||
|  | ||||
| 	checkSongId(id); | ||||
| 	if (!song_id_exists(id)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 	return playPlaylist(fd, playlist.idToPosition[id], stopOnError); | ||||
| 	return playPlaylist(playlist.idToPosition[id], stopOnError); | ||||
| } | ||||
|  | ||||
| static void syncCurrentPlayerDecodeMetadata(void) | ||||
| @@ -1020,28 +997,22 @@ void setPlaylistRepeatStatus(int status) | ||||
| 	playlist.repeat = status; | ||||
| } | ||||
|  | ||||
| int moveSongInPlaylist(int fd, int from, int to) | ||||
| enum playlist_result moveSongInPlaylist(int from, int to) | ||||
| { | ||||
| 	int i; | ||||
| 	Song *tmpSong; | ||||
| 	int tmpId; | ||||
| 	int currentSong; | ||||
|  | ||||
| 	if (from < 0 || from >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", from); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (from < 0 || from >= playlist.length) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	if ((to >= 0 && to >= playlist.length) || | ||||
| 	    (to < 0 && abs(to) > playlist.length)) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", to); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	    (to < 0 && abs(to) > playlist.length)) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	if (from == to) /* no-op */ | ||||
| 		return 0; | ||||
| 		return PLAYLIST_RESULT_SUCCESS; | ||||
|  | ||||
| 	/* | ||||
| 	 * (to < 0) => move to offset from current song | ||||
| @@ -1051,7 +1022,7 @@ int moveSongInPlaylist(int fd, int from, int to) | ||||
| 	if (to < 0 && playlist.current >= 0) { | ||||
| 		if (currentSong == from) | ||||
| 			/* no-op, can't be moved to offset of itself */ | ||||
| 			return 0; | ||||
| 			return PLAYLIST_RESULT_SUCCESS; | ||||
| 		to = (currentSong + abs(to)) % playlist.length; | ||||
| 	} | ||||
|  | ||||
| @@ -1116,14 +1087,15 @@ int moveSongInPlaylist(int fd, int from, int to) | ||||
|  | ||||
| 	incrPlaylistVersion(); | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int moveSongInPlaylistById(int fd, int id1, int to) | ||||
| enum playlist_result moveSongInPlaylistById(int id1, int to) | ||||
| { | ||||
| 	checkSongId(id1); | ||||
| 	if (!song_id_exists(id1)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 	return moveSongInPlaylist(fd, playlist.idToPosition[id1], to); | ||||
| 	return moveSongInPlaylist(playlist.idToPosition[id1], to); | ||||
| } | ||||
|  | ||||
| static void orderPlaylist(void) | ||||
| @@ -1222,7 +1194,7 @@ void previousSongInPlaylist(void) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void shufflePlaylist(mpd_unused int fd) | ||||
| void shufflePlaylist(void) | ||||
| { | ||||
| 	int i; | ||||
| 	int ri; | ||||
| @@ -1253,50 +1225,39 @@ void shufflePlaylist(mpd_unused int fd) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int deletePlaylist(int fd, const char *utf8file) | ||||
| enum playlist_result deletePlaylist(const char *utf8file) | ||||
| { | ||||
| 	char path_max_tmp[MPD_PATH_MAX]; | ||||
|  | ||||
| 	utf8_to_fs_playlist_path(path_max_tmp, utf8file); | ||||
|  | ||||
| 	if (!isPlaylist(path_max_tmp)) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "playlist \"%s\" not found", utf8file); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (!isPlaylist(path_max_tmp)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_LIST; | ||||
|  | ||||
| 	if (unlink(path_max_tmp) < 0) { | ||||
| 		commandError(fd, ACK_ERROR_SYSTEM, | ||||
| 			     "problems deleting file"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (unlink(path_max_tmp) < 0) | ||||
| 		return PLAYLIST_RESULT_ERRNO; | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int savePlaylist(int fd, const char *utf8file) | ||||
| enum playlist_result savePlaylist(const char *utf8file) | ||||
| { | ||||
| 	FILE *fp; | ||||
| 	int i; | ||||
| 	struct stat sb; | ||||
| 	char path_max_tmp[MPD_PATH_MAX]; | ||||
|  | ||||
| 	if (!valid_playlist_name(fd, utf8file)) | ||||
| 		return -1; | ||||
| 	if (!is_valid_playlist_name(utf8file)) | ||||
| 		return PLAYLIST_RESULT_BAD_NAME; | ||||
|  | ||||
| 	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; | ||||
| 	} | ||||
| 	if (!stat(path_max_tmp, &sb)) | ||||
| 		return PLAYLIST_RESULT_LIST_EXISTS; | ||||
|  | ||||
| 	while (!(fp = fopen(path_max_tmp, "w")) && errno == EINTR); | ||||
|  | ||||
| 	if (fp == NULL) { | ||||
| 		commandError(fd, ACK_ERROR_SYSTEM, "failed to create file"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (fp == NULL) | ||||
| 		return PLAYLIST_RESULT_ERRNO; | ||||
|  | ||||
| 	for (i = 0; i < playlist.length; i++) { | ||||
| 		char tmp[MPD_PATH_MAX]; | ||||
| @@ -1313,7 +1274,7 @@ int savePlaylist(int fd, const char *utf8file) | ||||
|  | ||||
| 	while (fclose(fp) && errno == EINTR) ; | ||||
|  | ||||
| 	return 0; | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int getPlaylistCurrentSong(void) | ||||
| @@ -1335,15 +1296,12 @@ int getPlaylistLength(void) | ||||
| 	return playlist.length; | ||||
| } | ||||
|  | ||||
| int seekSongInPlaylist(int fd, int song, float seek_time) | ||||
| enum playlist_result seekSongInPlaylist(int song, float seek_time) | ||||
| { | ||||
| 	int i, ret; | ||||
|  | ||||
| 	if (song < 0 || song >= playlist.length) { | ||||
| 		commandError(fd, ACK_ERROR_NO_EXIST, | ||||
| 			     "song doesn't exist: \"%i\"", song); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (song < 0 || song >= playlist.length) | ||||
| 		return PLAYLIST_RESULT_BAD_RANGE; | ||||
|  | ||||
| 	if (playlist.random) | ||||
| 		for (i = 0; song != playlist.order[i]; i++) ; | ||||
| @@ -1366,16 +1324,17 @@ int seekSongInPlaylist(int fd, int song, float seek_time) | ||||
|  | ||||
| 	ret = playerSeek(playlist.songs[playlist.order[i]], seek_time); | ||||
| 	if (ret < 0) | ||||
| 		commandError(fd, ACK_ERROR_PLAYER_SYNC, | ||||
| 			     "player not currently playing"); | ||||
| 	return ret; | ||||
| 		return PLAYLIST_RESULT_NOT_PLAYING; | ||||
|  | ||||
| 	return PLAYLIST_RESULT_SUCCESS; | ||||
| } | ||||
|  | ||||
| int seekSongInPlaylistById(int fd, int id, float seek_time) | ||||
| enum playlist_result seekSongInPlaylistById(int id, float seek_time) | ||||
| { | ||||
| 	checkSongId(id); | ||||
| 	if (!song_id_exists(id)) | ||||
| 		return PLAYLIST_RESULT_NO_SUCH_SONG; | ||||
|  | ||||
| 	return seekSongInPlaylist(fd, playlist.idToPosition[id], seek_time); | ||||
| 	return seekSongInPlaylist(playlist.idToPosition[id], seek_time); | ||||
| } | ||||
|  | ||||
| int getPlaylistSongId(int song) | ||||
| @@ -1426,7 +1385,7 @@ int loadPlaylist(int fd, const char *utf8file) | ||||
| 	node = list->firstNode; | ||||
| 	while (node != NULL) { | ||||
| 		char *temp = node->data; | ||||
| 		if ((addToPlaylist(STDERR_FILENO, temp, NULL)) < 0) { | ||||
| 		if ((addToPlaylist(temp, NULL)) != PLAYLIST_RESULT_SUCCESS) { | ||||
| 			/* for windows compatibility, convert slashes */ | ||||
| 			char *temp2 = xstrdup(temp); | ||||
| 			char *p = temp2; | ||||
| @@ -1435,7 +1394,7 @@ int loadPlaylist(int fd, const char *utf8file) | ||||
| 					*p = '/'; | ||||
| 				p++; | ||||
| 			} | ||||
| 			if ((addToPlaylist(STDERR_FILENO, temp2, NULL)) < 0) { | ||||
| 			if ((addToPlaylist(temp, NULL)) != PLAYLIST_RESULT_SUCCESS) { | ||||
| 				commandError(fd, ACK_ERROR_PLAYLIST_LOAD, | ||||
| 							"can't add file \"%s\"", temp2); | ||||
| 			} | ||||
|   | ||||
| @@ -24,6 +24,18 @@ | ||||
| #define PLAYLIST_FILE_SUFFIX 	"m3u" | ||||
| #define PLAYLIST_COMMENT	'#' | ||||
|  | ||||
| enum playlist_result { | ||||
| 	PLAYLIST_RESULT_SUCCESS, | ||||
| 	PLAYLIST_RESULT_ERRNO, | ||||
| 	PLAYLIST_RESULT_NO_SUCH_SONG, | ||||
| 	PLAYLIST_RESULT_NO_SUCH_LIST, | ||||
| 	PLAYLIST_RESULT_LIST_EXISTS, | ||||
| 	PLAYLIST_RESULT_BAD_NAME, | ||||
| 	PLAYLIST_RESULT_BAD_RANGE, | ||||
| 	PLAYLIST_RESULT_NOT_PLAYING, | ||||
| 	PLAYLIST_RESULT_TOO_LARGE | ||||
| }; | ||||
|  | ||||
| typedef struct _Playlist { | ||||
| 	Song **songs; | ||||
| 	/* holds version a song was modified on */ | ||||
| @@ -55,27 +67,27 @@ void clearPlaylist(void); | ||||
|  | ||||
| int clearStoredPlaylist(int fd, const char *utf8file); | ||||
|  | ||||
| int addToPlaylist(int fd, const char *file, int *added_id); | ||||
| enum playlist_result addToPlaylist(const char *file, int *added_id); | ||||
|  | ||||
| int addToStoredPlaylist(int fd, const char *file, const char *utf8file); | ||||
|  | ||||
| int addSongToPlaylist(int fd, Song * song, int *added_id); | ||||
| enum playlist_result addSongToPlaylist(Song * song, int *added_id); | ||||
|  | ||||
| void showPlaylist(int fd); | ||||
|  | ||||
| int deleteFromPlaylist(int fd, int song); | ||||
| enum playlist_result deleteFromPlaylist(int song); | ||||
|  | ||||
| int deleteFromPlaylistById(int fd, int song); | ||||
| enum playlist_result deleteFromPlaylistById(int song); | ||||
|  | ||||
| int playlistInfo(int fd, int song); | ||||
| enum playlist_result playlistInfo(int fd, int song); | ||||
|  | ||||
| int playlistId(int fd, int song); | ||||
| enum playlist_result playlistId(int fd, int song); | ||||
|  | ||||
| void stopPlaylist(void); | ||||
|  | ||||
| int playPlaylist(int fd, int song, int stopOnError); | ||||
| enum playlist_result playPlaylist(int song, int stopOnError); | ||||
|  | ||||
| int playPlaylistById(int fd, int song, int stopOnError); | ||||
| enum playlist_result playPlaylistById(int song, int stopOnError); | ||||
|  | ||||
| void nextSongInPlaylist(void); | ||||
|  | ||||
| @@ -83,23 +95,21 @@ void syncPlayerAndPlaylist(void); | ||||
|  | ||||
| void previousSongInPlaylist(void); | ||||
|  | ||||
| void shufflePlaylist(int fd); | ||||
| void shufflePlaylist(void); | ||||
|  | ||||
| int savePlaylist(int fd, const char *utf8file); | ||||
| enum playlist_result savePlaylist(const char *utf8file); | ||||
|  | ||||
| int deletePlaylist(int fd, const char *utf8file); | ||||
|  | ||||
| int deletePlaylistById(int fd, const char *utf8file); | ||||
| enum playlist_result deletePlaylist(const char *utf8file); | ||||
|  | ||||
| void deleteASongFromPlaylist(Song * song); | ||||
|  | ||||
| int moveSongInPlaylist(int fd, int from, int to); | ||||
| enum playlist_result moveSongInPlaylist(int from, int to); | ||||
|  | ||||
| int moveSongInPlaylistById(int fd, int id, int to); | ||||
| enum playlist_result moveSongInPlaylistById(int id, int to); | ||||
|  | ||||
| int swapSongsInPlaylist(int fd, int song1, int song2); | ||||
| enum playlist_result swapSongsInPlaylist(int song1, int song2); | ||||
|  | ||||
| int swapSongsInPlaylistById(int fd, int id1, int id2); | ||||
| enum playlist_result swapSongsInPlaylistById(int id1, int id2); | ||||
|  | ||||
| int loadPlaylist(int fd, const char *utf8file); | ||||
|  | ||||
| @@ -121,9 +131,9 @@ unsigned long getPlaylistVersion(void); | ||||
|  | ||||
| void playPlaylistIfPlayerStopped(void); | ||||
|  | ||||
| int seekSongInPlaylist(int fd, int song, float seek_time); | ||||
| enum playlist_result seekSongInPlaylist(int song, float seek_time); | ||||
|  | ||||
| int seekSongInPlaylistById(int fd, int id, float seek_time); | ||||
| enum playlist_result seekSongInPlaylistById(int id, float seek_time); | ||||
|  | ||||
| void playlistVersionChange(void); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann