diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/audio.c | 19 | ||||
-rw-r--r-- | src/audio.h | 6 | ||||
-rw-r--r-- | src/command.c | 518 | ||||
-rw-r--r-- | src/command.h | 21 | ||||
-rw-r--r-- | src/dbUtils.c | 76 | ||||
-rw-r--r-- | src/dbUtils.h | 16 | ||||
-rw-r--r-- | src/directory.c | 54 | ||||
-rw-r--r-- | src/directory.h | 10 | ||||
-rw-r--r-- | src/gcc.h | 50 | ||||
-rw-r--r-- | src/interface.c | 445 | ||||
-rw-r--r-- | src/ls.c | 8 | ||||
-rw-r--r-- | src/ls.h | 4 | ||||
-rw-r--r-- | src/myfprintf.c | 76 | ||||
-rw-r--r-- | src/myfprintf.h | 10 | ||||
-rw-r--r-- | src/player.c | 23 | ||||
-rw-r--r-- | src/player.h | 10 | ||||
-rw-r--r-- | src/playlist.c | 249 | ||||
-rw-r--r-- | src/playlist.h | 58 | ||||
-rw-r--r-- | src/sllist.c | 71 | ||||
-rw-r--r-- | src/sllist.h | 34 | ||||
-rw-r--r-- | src/song.c | 18 | ||||
-rw-r--r-- | src/song.h | 6 | ||||
-rw-r--r-- | src/stats.c | 16 | ||||
-rw-r--r-- | src/stats.h | 2 | ||||
-rw-r--r-- | src/tag.c | 6 | ||||
-rw-r--r-- | src/tag.h | 2 | ||||
-rw-r--r-- | src/tagTracker.c | 6 | ||||
-rw-r--r-- | src/tagTracker.h | 2 | ||||
-rw-r--r-- | src/utils.h | 41 | ||||
-rw-r--r-- | src/volume.c | 20 | ||||
-rw-r--r-- | src/volume.h | 2 |
32 files changed, 1081 insertions, 801 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e86c73eab..3c5d46990 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,6 +35,7 @@ mpd_headers = \ dbUtils.h \ decode.h \ directory.h \ + gcc.h \ inputPlugin.h \ inputPlugins/_flac_common.h \ inputPlugins/_ogg_common.h \ @@ -61,6 +62,7 @@ mpd_headers = \ replayGain.h \ signal_check.h \ sig_handlers.h \ + sllist.h \ song.h \ stats.h \ tag.h \ @@ -107,6 +109,7 @@ mpd_SOURCES = \ replayGain.c \ sig_handlers.c \ signal_check.c \ + sllist.c \ song.c \ stats.c \ tag.c \ diff --git a/src/audio.c b/src/audio.c index 2e8645882..03e706d68 100644 --- a/src/audio.c +++ b/src/audio.c @@ -423,10 +423,10 @@ void sendMetadataToAudioDevice(MpdTag * tag) } } -int enableAudioDevice(FILE * fp, int device) +int enableAudioDevice(int fd, int device) { if (device < 0 || device >= audioOutputArraySize) { - commandError(fp, ACK_ERROR_ARG, "audio output device id %i " + commandError(fd, ACK_ERROR_ARG, "audio output device id %i " "doesn't exist\n", device); return -1; } @@ -436,10 +436,10 @@ int enableAudioDevice(FILE * fp, int device) return 0; } -int disableAudioDevice(FILE * fp, int device) +int disableAudioDevice(int fd, int device) { if (device < 0 || device >= audioOutputArraySize) { - commandError(fp, ACK_ERROR_ARG, "audio output device id %i " + commandError(fd, ACK_ERROR_ARG, "audio output device id %i " "doesn't exist\n", device); return -1; } @@ -449,15 +449,16 @@ int disableAudioDevice(FILE * fp, int device) return 0; } -void printAudioDevices(FILE * fp) +void printAudioDevices(int fd) { int i; for (i = 0; i < audioOutputArraySize; i++) { - myfprintf(fp, "outputid: %i\n", i); - myfprintf(fp, "outputname: %s\n", audioOutputArray[i]->name); - myfprintf(fp, "outputenabled: %i\n", - (int)pdAudioDevicesEnabled[i]); + fdprintf(fd, + "outputid: %i\noutputname: %s\noutputenabled: %i\n", + i, + audioOutputArray[i]->name, + (int)pdAudioDevicesEnabled[i]); } } diff --git a/src/audio.h b/src/audio.h index 5f62bd97c..29309b9ce 100644 --- a/src/audio.h +++ b/src/audio.h @@ -69,11 +69,11 @@ void sendMetadataToAudioDevice(MpdTag * tag); /* these functions are called in the main parent process while the child process is busy playing to the audio */ -int enableAudioDevice(FILE * fp, int device); +int enableAudioDevice(int fd, int device); -int disableAudioDevice(FILE * fp, int device); +int disableAudioDevice(int fd, int device); -void printAudioDevices(FILE * fp); +void printAudioDevices(int fd); void readAudioDevicesState(); diff --git a/src/command.c b/src/command.c index cf4a37ae7..53ed8de90 100644 --- a/src/command.c +++ b/src/command.c @@ -111,9 +111,9 @@ typedef struct _CommandEntry CommandEntry; -typedef int (*CommandHandlerFunction) (FILE *, int *, int, char **); +typedef int (*CommandHandlerFunction) (int, int *, int, char **); typedef int (*CommandListHandlerFunction) - (FILE *, int *, int, char **, ListNode *, CommandEntry *); + (int, int *, int, char **, struct strnode *, CommandEntry *); /* if min: -1 don't check args * * if max: -1 no max args */ @@ -131,7 +131,7 @@ int command_listNum = 0; static CommandEntry *getCommandEntryFromString(char *string, int *permission); -List *commandList; +static List *commandList; CommandEntry *newCommandEntry(void) { @@ -163,14 +163,14 @@ static void addCommand(char *name, insertInList(commandList, cmd->cmd, cmd); } -static int handleUrlHandlers(FILE * fp, int *permission, int argc, - char **argv) +static int handleUrlHandlers(int fd, int *permission, int argc, + char *argv[]) { - return printRemoteUrlHandlers(fp); + return printRemoteUrlHandlers(fd); } -static int handlePlay(FILE * fp, int *permission, int argc, - char **argv) +static int handlePlay(int fd, int *permission, int argc, + char *argv[]) { int song = -1; char *test; @@ -178,16 +178,16 @@ static int handlePlay(FILE * fp, int *permission, int argc, if (argc == 2) { song = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } } - return playPlaylist(fp, song, 0); + return playPlaylist(fd, song, 0); } -static int handlePlayId(FILE * fp, int *permission, int argc, - char **argv) +static int handlePlayId(int fd, int *permission, int argc, + char *argv[]) { int id = -1; char *test; @@ -195,49 +195,49 @@ static int handlePlayId(FILE * fp, int *permission, int argc, if (argc == 2) { id = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } } - return playPlaylistById(fp, id, 0); + return playPlaylistById(fd, id, 0); } -static int handleStop(FILE * fp, int *permission, int argc, - char **argv) +static int handleStop(int fd, int *permission, int argc, + char *argv[]) { - return stopPlaylist(fp); + return stopPlaylist(fd); } -static int handleCurrentSong(FILE * fp, int *permission, int argc, - char **argv) +static int handleCurrentSong(int fd, int *permission, int argc, + char *argv[]) { int song = getPlaylistCurrentSong(); if (song >= 0) { - return playlistInfo(fp, song); + return playlistInfo(fd, song); } else return 0; } -static int handlePause(FILE * fp, int *permission, - int argc, char **argv) +static int handlePause(int fd, int *permission, + int argc, char *argv[]) { if (argc == 2) { char *test; int pause = strtol(argv[1], &test, 10); if (*test != '\0' || (pause != 0 && pause != 1)) { - commandError(fp, ACK_ERROR_ARG, "\"%s\" is not 0 or 1", + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not 0 or 1", argv[1]); return -1; } - return playerSetPause(fp, pause); + return playerSetPause(fd, pause); } - return playerPause(fp); + return playerPause(fd); } -static int commandStatus(FILE * fp, int *permission, int argc, - char **argv) +static int commandStatus(int fd, int *permission, int argc, + char *argv[]) { char *state = NULL; int updateJobId; @@ -257,204 +257,204 @@ static int commandStatus(FILE * fp, int *permission, int argc, break; } - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_VOLUME, getVolumeLevel()); - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_REPEAT, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_VOLUME, getVolumeLevel()); + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_REPEAT, getPlaylistRepeatStatus()); - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_RANDOM, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_RANDOM, getPlaylistRandomStatus()); - myfprintf(fp, "%s: %li\n", COMMAND_STATUS_PLAYLIST, + fdprintf(fd, "%s: %li\n", COMMAND_STATUS_PLAYLIST, getPlaylistVersion()); - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_PLAYLIST_LENGTH, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_PLAYLIST_LENGTH, getPlaylistLength()); - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_CROSSFADE, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_CROSSFADE, (int)(getPlayerCrossFade() + 0.5)); - myfprintf(fp, "%s: %s\n", COMMAND_STATUS_STATE, state); + fdprintf(fd, "%s: %s\n", COMMAND_STATUS_STATE, state); song = getPlaylistCurrentSong(); if (song >= 0) { - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_SONG, song); - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_SONGID, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_SONG, song); + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_SONGID, getPlaylistSongId(song)); } if (getPlayerState() != PLAYER_STATE_STOP) { - myfprintf(fp, "%s: %i:%i\n", COMMAND_STATUS_TIME, + fdprintf(fd, "%s: %i:%i\n", COMMAND_STATUS_TIME, getPlayerElapsedTime(), getPlayerTotalTime()); - myfprintf(fp, "%s: %li\n", COMMAND_STATUS_BITRATE, + fdprintf(fd, "%s: %li\n", COMMAND_STATUS_BITRATE, getPlayerBitRate(), getPlayerTotalTime()); - myfprintf(fp, "%s: %u:%i:%i\n", COMMAND_STATUS_AUDIO, + fdprintf(fd, "%s: %u:%i:%i\n", COMMAND_STATUS_AUDIO, getPlayerSampleRate(), getPlayerBits(), getPlayerChannels()); } if ((updateJobId = isUpdatingDB())) { - myfprintf(fp, "%s: %i\n", COMMAND_STATUS_UPDATING_DB, + fdprintf(fd, "%s: %i\n", COMMAND_STATUS_UPDATING_DB, updateJobId); } if (getPlayerError() != PLAYER_ERROR_NOERROR) { - myfprintf(fp, "%s: %s\n", COMMAND_STATUS_ERROR, + fdprintf(fd, "%s: %s\n", COMMAND_STATUS_ERROR, getPlayerErrorStr()); } return 0; } -static int handleKill(FILE * fp, int *permission, int argc, - char **argv) +static int handleKill(int fd, int *permission, int argc, + char *argv[]) { return COMMAND_RETURN_KILL; } -static int handleClose(FILE * fp, int *permission, int argc, - char **argv) +static int handleClose(int fd, int *permission, int argc, + char *argv[]) { return COMMAND_RETURN_CLOSE; } -static int handleAdd(FILE * fp, int *permission, int argc, - char **argv) +static int handleAdd(int fd, int *permission, int argc, + char *argv[]) { char *path = argv[1]; if (isRemoteUrl(path)) - return addToPlaylist(fp, path, 0); + return addToPlaylist(fd, path, 0); - return addAllIn(fp, path); + return addAllIn(fd, path); } -static int handleAddId(FILE * fp, int *permission, int argc, - char **argv) +static int handleAddId(int fd, int *permission, int argc, + char *argv[]) { - return addToPlaylist(fp, argv[1], 1); + return addToPlaylist(fd, argv[1], 1); } -static int handleDelete(FILE * fp, int *permission, int argc, - char **argv) +static int handleDelete(int fd, int *permission, int argc, + char *argv[]) { int song; char *test; song = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } - return deleteFromPlaylist(fp, song); + return deleteFromPlaylist(fd, song); } -static int handleDeleteId(FILE * fp, int *permission, int argc, - char **argv) +static int handleDeleteId(int fd, int *permission, int argc, + char *argv[]) { int id; char *test; id = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } - return deleteFromPlaylistById(fp, id); + return deleteFromPlaylistById(fd, id); } -static int handlePlaylist(FILE * fp, int *permission, int argc, - char **argv) +static int handlePlaylist(int fd, int *permission, int argc, + char *argv[]) { - return showPlaylist(fp); + return showPlaylist(fd); } -static int handleShuffle(FILE * fp, int *permission, int argc, - char **argv) +static int handleShuffle(int fd, int *permission, int argc, + char *argv[]) { - return shufflePlaylist(fp); + return shufflePlaylist(fd); } -static int handleClear(FILE * fp, int *permission, int argc, - char **argv) +static int handleClear(int fd, int *permission, int argc, + char *argv[]) { - return clearPlaylist(fp); + return clearPlaylist(fd); } -static int handleSave(FILE * fp, int *permission, int argc, - char **argv) +static int handleSave(int fd, int *permission, int argc, + char *argv[]) { - return savePlaylist(fp, argv[1]); + return savePlaylist(fd, argv[1]); } -static int handleLoad(FILE * fp, int *permission, int argc, - char **argv) +static int handleLoad(int fd, int *permission, int argc, + char *argv[]) { - return loadPlaylist(fp, argv[1]); + return loadPlaylist(fd, argv[1]); } -static int handleListPlaylist(FILE * fp, int *permission, int argc, - char **argv) +static int handleListPlaylist(int fd, int *permission, int argc, + char *argv[]) { - return PlaylistInfo(fp, argv[1], 0); + return PlaylistInfo(fd, argv[1], 0); } -static int handleListPlaylistInfo(FILE * fp, int *permission, - int argc, char **argv) +static int handleListPlaylistInfo(int fd, int *permission, + int argc, char *argv[]) { - return PlaylistInfo(fp, argv[1], 1); + return PlaylistInfo(fd, argv[1], 1); } -static int handleLsInfo(FILE * fp, int *permission, int argc, - char **argv) +static int handleLsInfo(int fd, int *permission, int argc, + char *argv[]) { if (argc == 1) { - if (printDirectoryInfo(fp, NULL) < 0) + if (printDirectoryInfo(fd, NULL) < 0) return -1; else - return lsPlaylists(fp, ""); + return lsPlaylists(fd, ""); } else { - if (printDirectoryInfo(fp, argv[1]) < 0) + if (printDirectoryInfo(fd, argv[1]) < 0) return -1; else - return lsPlaylists(fp, argv[1]); + return lsPlaylists(fd, argv[1]); } } -static int handleRm(FILE * fp, int *permission, int argc, - char **argv) +static int handleRm(int fd, int *permission, int argc, + char *argv[]) { - return deletePlaylist(fp, argv[1]); + return deletePlaylist(fd, argv[1]); } -static int handlePlaylistChanges(FILE * fp, int *permission, - int argc, char **argv) +static int handlePlaylistChanges(int fd, int *permission, + int argc, char *argv[]) { unsigned long version; char *test; version = strtoul(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need a positive integer", + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } - return playlistChanges(fp, version); + return playlistChanges(fd, version); } -static int handlePlaylistChangesPosId(FILE * fp, int *permission, - int argc, char **argv) +static int handlePlaylistChangesPosId(int fd, int *permission, + int argc, char *argv[]) { unsigned long version; char *test; version = strtoul(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need a positive integer", + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } - return playlistChangesPosId(fp, version); + return playlistChangesPosId(fd, version); } -static int handlePlaylistInfo(FILE * fp, int *permission, - int argc, char **argv) +static int handlePlaylistInfo(int fd, int *permission, + int argc, char *argv[]) { int song = -1; char *test; @@ -462,16 +462,16 @@ static int handlePlaylistInfo(FILE * fp, int *permission, if (argc == 2) { song = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } } - return playlistInfo(fp, song); + return playlistInfo(fd, song); } -static int handlePlaylistId(FILE * fp, int *permission, - int argc, char **argv) +static int handlePlaylistId(int fd, int *permission, + int argc, char *argv[]) { int id = -1; char *test; @@ -479,16 +479,16 @@ static int handlePlaylistId(FILE * fp, int *permission, if (argc == 2) { id = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "need a positive integer", NULL); return -1; } } - return playlistId(fp, id); + return playlistId(fd, id); } -static int handleFind(FILE * fp, int *permission, int argc, - char **argv) +static int handleFind(int fd, int *permission, int argc, + char *argv[]) { int ret; @@ -498,19 +498,19 @@ static int handleFind(FILE * fp, int *permission, int argc, &items); if (numItems <= 0) { - commandError(fp, ACK_ERROR_ARG, "incorrect arguments", NULL); + commandError(fd, ACK_ERROR_ARG, "incorrect arguments", NULL); return -1; } - ret = findSongsIn(fp, NULL, numItems, items); + ret = findSongsIn(fd, NULL, numItems, items); freeLocateTagItemArray(numItems, items); return ret; } -static int handleSearch(FILE * fp, int *permission, int argc, - char **argv) +static int handleSearch(int fd, int *permission, int argc, + char *argv[]) { int ret; @@ -520,26 +520,26 @@ static int handleSearch(FILE * fp, int *permission, int argc, &items); if (numItems <= 0) { - commandError(fp, ACK_ERROR_ARG, "incorrect arguments", NULL); + commandError(fd, ACK_ERROR_ARG, "incorrect arguments", NULL); return -1; } - ret = searchForSongsIn(fp, NULL, numItems, items); + ret = searchForSongsIn(fd, NULL, numItems, items); freeLocateTagItemArray(numItems, items); return ret; } -static int listHandleUpdate(FILE * fp, +static int listHandleUpdate(int fd, int *permission, int argc, - char **argv, - ListNode * commandNode, CommandEntry * cmd) + char *argv[], + struct strnode *cmdnode, CommandEntry *cmd) { static List *pathList = NULL; CommandEntry *nextCmd = NULL; - ListNode *nextNode = commandNode->nextNode;; + struct strnode *next = cmdnode->next; if (!pathList) pathList = makeList(NULL, 1); @@ -549,13 +549,11 @@ static int listHandleUpdate(FILE * fp, else insertInList(pathList, "", NULL); - if (nextNode) { - nextCmd = getCommandEntryFromString((void *)nextNode->data, - permission); - } + if(next) + nextCmd = getCommandEntryFromString(next->data, permission); if (cmd != nextCmd) { - int ret = updateInit(fp, pathList); + int ret = updateInit(fd, pathList); freeList(pathList); pathList = NULL; return ret; @@ -564,113 +562,113 @@ static int listHandleUpdate(FILE * fp, return 0; } -static int handleUpdate(FILE * fp, int *permission, int argc, - char **argv) +static int handleUpdate(int fd, int *permission, int argc, + char *argv[]) { if (argc == 2) { int ret; List *pathList = makeList(NULL, 1); insertInList(pathList, argv[1], NULL); - ret = updateInit(fp, pathList); + ret = updateInit(fd, pathList); freeList(pathList); return ret; } - return updateInit(fp, NULL); + return updateInit(fd, NULL); } -static int handleNext(FILE * fp, int *permission, int argc, - char **argv) +static int handleNext(int fd, int *permission, int argc, + char *argv[]) { - return nextSongInPlaylist(fp); + return nextSongInPlaylist(fd); } -static int handlePrevious(FILE * fp, int *permission, int argc, - char **argv) +static int handlePrevious(int fd, int *permission, int argc, + char *argv[]) { - return previousSongInPlaylist(fp); + return previousSongInPlaylist(fd); } -static int handleListAll(FILE * fp, int *permission, int argc, - char **argv) +static int handleListAll(int fd, int *permission, int argc, + char *argv[]) { char *directory = NULL; if (argc == 2) directory = argv[1]; - return printAllIn(fp, directory); + return printAllIn(fd, directory); } -static int handleVolume(FILE * fp, int *permission, int argc, - char **argv) +static int handleVolume(int fd, int *permission, int argc, + char *argv[]) { int change; char *test; change = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need an integer", NULL); + commandError(fd, ACK_ERROR_ARG, "need an integer", NULL); return -1; } - return changeVolumeLevel(fp, change, 1); + return changeVolumeLevel(fd, change, 1); } -static int handleSetVol(FILE * fp, int *permission, int argc, - char **argv) +static int handleSetVol(int fd, int *permission, int argc, + char *argv[]) { int level; char *test; level = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need an integer", NULL); + commandError(fd, ACK_ERROR_ARG, "need an integer", NULL); return -1; } - return changeVolumeLevel(fp, level, 0); + return changeVolumeLevel(fd, level, 0); } -static int handleRepeat(FILE * fp, int *permission, int argc, - char **argv) +static int handleRepeat(int fd, int *permission, int argc, + char *argv[]) { int status; char *test; status = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need an integer", NULL); + commandError(fd, ACK_ERROR_ARG, "need an integer", NULL); return -1; } - return setPlaylistRepeatStatus(fp, status); + return setPlaylistRepeatStatus(fd, status); } -static int handleRandom(FILE * fp, int *permission, int argc, - char **argv) +static int handleRandom(int fd, int *permission, int argc, + char *argv[]) { int status; char *test; status = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "need an integer", NULL); + commandError(fd, ACK_ERROR_ARG, "need an integer", NULL); return -1; } - return setPlaylistRandomStatus(fp, status); + return setPlaylistRandomStatus(fd, status); } -static int handleStats(FILE * fp, int *permission, int argc, - char **argv) +static int handleStats(int fd, int *permission, int argc, + char *argv[]) { - return printStats(fp); + return printStats(fd); } -static int handleClearError(FILE * fp, int *permission, int argc, - char **argv) +static int handleClearError(int fd, int *permission, int argc, + char *argv[]) { clearPlayerError(); return 0; } -static int handleList(FILE * fp, int *permission, int argc, - char **argv) +static int handleList(int fd, int *permission, int argc, + char *argv[]) { int numConditionals = 0; LocateTagItem *conditionals = NULL; @@ -678,7 +676,7 @@ static int handleList(FILE * fp, int *permission, int argc, int ret; if (tagType < 0) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not known", argv[1]); return -1; } @@ -686,7 +684,7 @@ static int handleList(FILE * fp, int *permission, int argc, /* for compatibility with < 0.12.0 */ if (argc == 3) { if (tagType != TAG_ITEM_ALBUM) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "should be \"%s\" for 3 arguments", mpdTagItemKeys[TAG_ITEM_ALBUM]); return -1; @@ -701,13 +699,13 @@ static int handleList(FILE * fp, int *permission, int argc, &conditionals); if (numConditionals < 0) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "not able to parse args", NULL); return -1; } } - ret = listAllUniqueTags(fp, tagType, numConditionals, conditionals); + ret = listAllUniqueTags(fd, tagType, numConditionals, conditionals); if (conditionals) freeLocateTagItemArray(numConditionals, conditionals); @@ -715,8 +713,8 @@ static int handleList(FILE * fp, int *permission, int argc, return ret; } -static int handleMove(FILE * fp, int *permission, int argc, - char **argv) +static int handleMove(int fd, int *permission, int argc, + char *argv[]) { int from; int to; @@ -724,21 +722,21 @@ static int handleMove(FILE * fp, int *permission, int argc, from = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } to = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return moveSongInPlaylist(fp, from, to); + return moveSongInPlaylist(fd, from, to); } -static int handleMoveId(FILE * fp, int *permission, int argc, - char **argv) +static int handleMoveId(int fd, int *permission, int argc, + char *argv[]) { int id; int to; @@ -746,21 +744,21 @@ static int handleMoveId(FILE * fp, int *permission, int argc, id = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } to = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return moveSongInPlaylistById(fp, id, to); + return moveSongInPlaylistById(fd, id, to); } -static int handleSwap(FILE * fp, int *permission, int argc, - char **argv) +static int handleSwap(int fd, int *permission, int argc, + char *argv[]) { int song1; int song2; @@ -768,21 +766,21 @@ static int handleSwap(FILE * fp, int *permission, int argc, song1 = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } song2 = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "\"%s\" is not a integer", + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return swapSongsInPlaylist(fp, song1, song2); + return swapSongsInPlaylist(fd, song1, song2); } -static int handleSwapId(FILE * fp, int *permission, int argc, - char **argv) +static int handleSwapId(int fd, int *permission, int argc, + char *argv[]) { int id1; int id2; @@ -790,21 +788,21 @@ static int handleSwapId(FILE * fp, int *permission, int argc, id1 = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } id2 = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, "\"%s\" is not a integer", + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return swapSongsInPlaylistById(fp, id1, id2); + return swapSongsInPlaylistById(fd, id1, id2); } -static int handleSeek(FILE * fp, int *permission, int argc, - char **argv) +static int handleSeek(int fd, int *permission, int argc, + char *argv[]) { int song; int time; @@ -812,21 +810,21 @@ static int handleSeek(FILE * fp, int *permission, int argc, song = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } time = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return seekSongInPlaylist(fp, song, time); + return seekSongInPlaylist(fd, song, time); } -static int handleSeekId(FILE * fp, int *permission, int argc, - char **argv) +static int handleSeekId(int fd, int *permission, int argc, + char *argv[]) { int id; int time; @@ -834,40 +832,40 @@ static int handleSeekId(FILE * fp, int *permission, int argc, id = strtol(argv[1], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[1]); return -1; } time = strtol(argv[2], &test, 10); if (*test != '\0') { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer", argv[2]); return -1; } - return seekSongInPlaylistById(fp, id, time); + return seekSongInPlaylistById(fd, id, time); } -static int handleListAllInfo(FILE * fp, int *permission, int argc, - char **argv) +static int handleListAllInfo(int fd, int *permission, int argc, + char *argv[]) { char *directory = NULL; if (argc == 2) directory = argv[1]; - return printInfoForAllIn(fp, directory); + return printInfoForAllIn(fd, directory); } -static int handlePing(FILE * fp, int *permission, int argc, - char **argv) +static int handlePing(int fd, int *permission, int argc, + char *argv[]) { return 0; } -static int handlePassword(FILE * fp, int *permission, int argc, - char **argv) +static int handlePassword(int fd, int *permission, int argc, + char *argv[]) { if (getPermissionFromPassword(argv[1], permission) < 0) { - commandError(fp, ACK_ERROR_PASSWORD, "incorrect password", + commandError(fd, ACK_ERROR_PASSWORD, "incorrect password", NULL); return -1; } @@ -875,15 +873,15 @@ static int handlePassword(FILE * fp, int *permission, int argc, return 0; } -static int handleCrossfade(FILE * fp, int *permission, int argc, - char **argv) +static int handleCrossfade(int fd, int *permission, int argc, + char *argv[]) { int time; char *test; time = strtol(argv[1], &test, 10); if (*test != '\0' || time < 0) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer >= 0", argv[1]); return -1; } @@ -893,49 +891,49 @@ static int handleCrossfade(FILE * fp, int *permission, int argc, return 0; } -static int handleEnableDevice(FILE * fp, int *permission, int argc, - char **argv) +static int handleEnableDevice(int fd, int *permission, int argc, + char *argv[]) { int device; char *test; device = strtol(argv[1], &test, 10); if (*test != '\0' || device < 0) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer >= 0", argv[1]); return -1; } - return enableAudioDevice(fp, device); + return enableAudioDevice(fd, device); } -static int handleDisableDevice(FILE * fp, int *permission, - int argc, char **argv) +static int handleDisableDevice(int fd, int *permission, + int argc, char *argv[]) { int device; char *test; device = strtol(argv[1], &test, 10); if (*test != '\0' || device < 0) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "\"%s\" is not a integer >= 0", argv[1]); return -1; } - return disableAudioDevice(fp, device); + return disableAudioDevice(fd, device); } -static int handleDevices(FILE * fp, int *permission, int argc, - char **argv) +static int handleDevices(int fd, int *permission, int argc, + char *argv[]) { - printAudioDevices(fp); + printAudioDevices(fd); return 0; } /* don't be fooled, this is the command handler for "commands" command */ -static int handleCommands(FILE * fp, int *permission, int argc, - char **argv) +static int handleCommands(int fd, int *permission, int argc, + char *argv[]) { ListNode *node = commandList->firstNode; CommandEntry *cmd; @@ -943,7 +941,7 @@ static int handleCommands(FILE * fp, int *permission, int argc, while (node != NULL) { cmd = (CommandEntry *) node->data; if (cmd->reqPermission == (*permission & cmd->reqPermission)) { - myfprintf(fp, "command: %s\n", cmd->cmd); + fdprintf(fd, "command: %s\n", cmd->cmd); } node = node->nextNode; @@ -952,8 +950,8 @@ static int handleCommands(FILE * fp, int *permission, int argc, return 0; } -static int handleNotcommands(FILE * fp, int *permission, int argc, - char **argv) +static int handleNotcommands(int fd, int *permission, int argc, + char *argv[]) { ListNode *node = commandList->firstNode; CommandEntry *cmd; @@ -962,7 +960,7 @@ static int handleNotcommands(FILE * fp, int *permission, int argc, cmd = (CommandEntry *) node->data; if (cmd->reqPermission != (*permission & cmd->reqPermission)) { - myfprintf(fp, "command: %s\n", cmd->cmd); + fdprintf(fd, "command: %s\n", cmd->cmd); } node = node->nextNode; @@ -1065,15 +1063,15 @@ void finishCommands(void) freeList(commandList); } -static int checkArgcAndPermission(CommandEntry * cmd, FILE * fp, - int permission, int argc, char **argv) +static int checkArgcAndPermission(CommandEntry * cmd, int fd, + int permission, int argc, char *argv[]) { int min = cmd->min + 1; int max = cmd->max + 1; if (cmd->reqPermission != (permission & cmd->reqPermission)) { - if (fp) { - commandError(fp, ACK_ERROR_PERMISSION, + if (fd) { + commandError(fd, ACK_ERROR_PERMISSION, "you don't have permission for \"%s\"", cmd->cmd); } @@ -1084,22 +1082,22 @@ static int checkArgcAndPermission(CommandEntry * cmd, FILE * fp, return 0; if (min == max && max != argc) { - if (fp) { - commandError(fp, ACK_ERROR_ARG, + if (fd) { + commandError(fd, ACK_ERROR_ARG, "wrong number of arguments for \"%s\"", argv[0]); } return -1; } else if (argc < min) { - if (fp) { - commandError(fp, ACK_ERROR_ARG, + if (fd) { + commandError(fd, ACK_ERROR_ARG, "too few arguments for \"%s\"", argv[0]); } return -1; } else if (argc > max && max /* != 0 */ ) { - if (fp) { - commandError(fp, ACK_ERROR_ARG, + if (fd) { + commandError(fd, ACK_ERROR_ARG, "too many arguments for \"%s\"", argv[0]); } @@ -1108,11 +1106,10 @@ static int checkArgcAndPermission(CommandEntry * cmd, FILE * fp, return 0; } -static CommandEntry *getCommandEntryAndCheckArgcAndPermission(FILE * fp, +static CommandEntry *getCommandEntryAndCheckArgcAndPermission(int fd, int *permission, - int - argc, - char **argv) + int argc, + char *argv[]) { static char unknown[] = ""; CommandEntry *cmd; @@ -1123,8 +1120,8 @@ static CommandEntry *getCommandEntryAndCheckArgcAndPermission(FILE * fp, return NULL; if (!findInList(commandList, argv[0], (void *)&cmd)) { - if (fp) { - commandError(fp, ACK_ERROR_UNKNOWN, + if (fd) { + commandError(fd, ACK_ERROR_UNKNOWN, "unknown command \"%s\"", argv[0]); } return NULL; @@ -1132,7 +1129,7 @@ static CommandEntry *getCommandEntryAndCheckArgcAndPermission(FILE * fp, current_command = cmd->cmd; - if (checkArgcAndPermission(cmd, fp, *permission, argc, + if (checkArgcAndPermission(cmd, fd, *permission, argc, argv) < 0) { return NULL; } @@ -1149,14 +1146,14 @@ static CommandEntry *getCommandEntryFromString(char *string, int *permission) if (0 == argc) return NULL; - cmd = getCommandEntryAndCheckArgcAndPermission(NULL, permission, + cmd = getCommandEntryAndCheckArgcAndPermission(0, permission, argc, argv); return cmd; } -static int processCommandInternal(FILE * fp, int *permission, - char *commandString, ListNode * commandNode) +static int processCommandInternal(int fd, int *permission, + char *commandString, struct strnode *cmdnode) { int argc; char *argv[COMMAND_ARGV_MAX] = { 0 }; @@ -1168,13 +1165,13 @@ static int processCommandInternal(FILE * fp, int *permission, if (argc == 0) return 0; - if ((cmd = getCommandEntryAndCheckArgcAndPermission(fp, permission, + if ((cmd = getCommandEntryAndCheckArgcAndPermission(fd, permission, argc, argv))) { - if (NULL == commandNode || NULL == cmd->listHandler) { - ret = cmd->handler(fp, permission, argc, argv); + if (!cmdnode || !cmd->listHandler) { + ret = cmd->handler(fd, permission, argc, argv); } else { - ret = cmd->listHandler(fp, permission, argc, argv, - commandNode, cmd); + ret = cmd->listHandler(fd, permission, argc, argv, + cmdnode, cmd); } } @@ -1183,37 +1180,32 @@ static int processCommandInternal(FILE * fp, int *permission, return ret; } -int processListOfCommands(FILE * fp, int *permission, int *expired, - int listOK, List * list) +int processListOfCommands(int fd, int *permission, int *expired, + int listOK, struct strnode *list) { - ListNode *node = list->firstNode; - ListNode *tempNode; + struct strnode *cur = list; int ret = 0; command_listNum = 0; - while (node != NULL) { + while (cur) { DEBUG("processListOfCommands: process command \"%s\"\n", - node->data); - ret = processCommandInternal(fp, permission, (char *)node->data, - node); + cur->data); + ret = processCommandInternal(fd, permission, cur->data, cur); DEBUG("processListOfCommands: command returned %i\n", ret); - tempNode = node->nextNode; - deleteNodeFromList(list, node); - node = tempNode; if (ret != 0 || (*expired) != 0) - node = NULL; + goto out; else if (listOK) - myfprintf(fp, "list_OK\n"); + fdprintf(fd, "list_OK\n"); command_listNum++; + cur = cur->next; } - +out: command_listNum = 0; - return ret; } -int processCommand(FILE * fp, int *permission, char *commandString) +int processCommand(int fd, int *permission, char *commandString) { - return processCommandInternal(fp, permission, commandString, NULL); + return processCommandInternal(fd, permission, commandString, NULL); } diff --git a/src/command.h b/src/command.h index 05ee2382b..cab6562db 100644 --- a/src/command.h +++ b/src/command.h @@ -25,7 +25,9 @@ #include "myfprintf.h" #include "log.h" #include "ack.h" +#include "sllist.h" +#include <unistd.h> #include <stdio.h> #define COMMAND_RETURN_KILL 10 @@ -35,30 +37,29 @@ extern char *current_command; extern int command_listNum; -int processListOfCommands(FILE * fp, int *permission, int *expired, - int listOK, List * list); +int processListOfCommands(int fd, int *permission, int *expired, + int listOK, struct strnode *list); -int processCommand(FILE * fp, int *permission, char *commandString); +int processCommand(int fd, int *permission, char *commandString); void initCommands(); void finishCommands(); -#define commandSuccess(fp) myfprintf(fp, "OK\n") +#define commandSuccess(fd) fdprintf(fd, "OK\n") -#define commandError(fp, error, format, ... ) \ +#define commandError(fd, error, format, ... ) do \ {\ - if(current_command) { \ - myfprintf(fp, "ACK [%i@%i] {%s} " format "\n", \ + if (current_command) { \ + fdprintf(fd, "ACK [%i@%i] {%s} " format "\n", \ (int)error, command_listNum, \ current_command, __VA_ARGS__); \ current_command = NULL; \ } \ else { \ - myfprintf(stderr, "ACK [%i@%i] " format "\n", \ + fdprintf(STDERR_FILENO, "ACK [%i@%i] " format "\n", \ (int)error, command_listNum, \ __VA_ARGS__); \ } \ - } - + } while (0) #endif diff --git a/src/dbUtils.c b/src/dbUtils.c index 9d2d993e2..f23d7c1b8 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -134,7 +134,7 @@ void freeLocateTagItem(LocateTagItem * item) free(item); } -static int countSongsInDirectory(FILE * fp, Directory * directory, void *data) +static int countSongsInDirectory(int fd, Directory * directory, void *data) { int *count = (int *)data; @@ -143,18 +143,18 @@ static int countSongsInDirectory(FILE * fp, Directory * directory, void *data) return 0; } -static int printDirectoryInDirectory(FILE * fp, Directory * directory, +static int printDirectoryInDirectory(int fd, Directory * directory, void *data) { if (directory->path) { - myfprintf(fp, "directory: %s\n", getDirectoryPath(directory)); + fdprintf(fd, "directory: %s\n", getDirectoryPath(directory)); } return 0; } -static int printSongInDirectory(FILE * fp, Song * song, void *data) +static int printSongInDirectory(int fd, Song * song, void *data) { - printSongUrl(fp, song); + printSongUrl(fd, song); return 0; } @@ -192,7 +192,7 @@ static int strstrSearchTag(Song * song, int type, char *str) return ret; } -static int searchInDirectory(FILE * fp, Song * song, void *data) +static int searchInDirectory(int fd, Song * song, void *data) { LocateTagItemArray *array = data; int i; @@ -204,12 +204,12 @@ static int searchInDirectory(FILE * fp, Song * song, void *data) } } - printSongInfo(fp, song); + printSongInfo(fd, song); return 0; } -int searchForSongsIn(FILE * fp, char *name, int numItems, LocateTagItem * items) +int searchForSongsIn(int fd, char *name, int numItems, LocateTagItem * items) { int ret = -1; int i; @@ -225,7 +225,7 @@ int searchForSongsIn(FILE * fp, char *name, int numItems, LocateTagItem * items) array.numItems = numItems; array.items = items; - ret = traverseAllIn(fp, name, searchInDirectory, NULL, &array); + ret = traverseAllIn(fd, name, searchInDirectory, NULL, &array); for (i = 0; i < numItems; i++) { free(items[i].needle); @@ -260,7 +260,7 @@ static int tagItemFoundAndMatches(Song * song, int type, char *str) return 0; } -static int findInDirectory(FILE * fp, Song * song, void *data) +static int findInDirectory(int fd, Song * song, void *data) { LocateTagItemArray *array = data; int i; @@ -272,43 +272,43 @@ static int findInDirectory(FILE * fp, Song * song, void *data) } } - printSongInfo(fp, song); + printSongInfo(fd, song); return 0; } -int findSongsIn(FILE * fp, char *name, int numItems, LocateTagItem * items) +int findSongsIn(int fd, char *name, int numItems, LocateTagItem * items) { LocateTagItemArray array; array.numItems = numItems; array.items = items; - return traverseAllIn(fp, name, findInDirectory, NULL, (void *)&array); + return traverseAllIn(fd, name, findInDirectory, NULL, (void *)&array); } -int printAllIn(FILE * fp, char *name) +int printAllIn(int fd, char *name) { - return traverseAllIn(fp, name, printSongInDirectory, + return traverseAllIn(fd, name, printSongInDirectory, printDirectoryInDirectory, NULL); } -static int directoryAddSongToPlaylist(FILE * fp, Song * song, void *data) +static int directoryAddSongToPlaylist(int fd, Song * song, void *data) { - return addSongToPlaylist(fp, song, 0); + return addSongToPlaylist(fd, song, 0); } -int addAllIn(FILE * fp, char *name) +int addAllIn(int fd, char *name) { - return traverseAllIn(fp, name, directoryAddSongToPlaylist, NULL, NULL); + return traverseAllIn(fd, name, directoryAddSongToPlaylist, NULL, NULL); } -static int directoryPrintSongInfo(FILE * fp, Song * song, void *data) +static int directoryPrintSongInfo(int fd, Song * song, void *data) { - return printSongInfo(fp, song); + return printSongInfo(fd, song); } -static int sumSongTime(FILE * fp, Song * song, void *data) +static int sumSongTime(int fd, Song * song, void *data) { unsigned long *time = (unsigned long *)data; @@ -318,28 +318,28 @@ static int sumSongTime(FILE * fp, Song * song, void *data) return 0; } -int printInfoForAllIn(FILE * fp, char *name) +int printInfoForAllIn(int fd, char *name) { - return traverseAllIn(fp, name, directoryPrintSongInfo, + return traverseAllIn(fd, name, directoryPrintSongInfo, printDirectoryInDirectory, NULL); } -int countSongsIn(FILE * fp, char *name) +int countSongsIn(int fd, char *name) { int count = 0; void *ptr = (void *)&count; - traverseAllIn(fp, name, NULL, countSongsInDirectory, ptr); + traverseAllIn(fd, name, NULL, countSongsInDirectory, ptr); return count; } -unsigned long sumSongTimesIn(FILE * fp, char *name) +unsigned long sumSongTimesIn(int fd, char *name) { unsigned long dbPlayTime = 0; void *ptr = (void *)&dbPlayTime; - traverseAllIn(fp, name, sumSongTime, NULL, ptr); + traverseAllIn(fd, name, sumSongTime, NULL, ptr); return dbPlayTime; } @@ -361,13 +361,13 @@ static void freeListCommandItem(ListCommandItem * item) free(item); } -static void visitTag(FILE * fp, Song * song, int tagType) +static void visitTag(int fd, Song * song, int tagType) { int i; MpdTag *tag = song->tag; if (tagType == LOCATE_TAG_FILE_TYPE) { - printSongUrl(fp, song); + printSongUrl(fd, song); return; } @@ -381,7 +381,7 @@ static void visitTag(FILE * fp, Song * song, int tagType) } } -static int listUniqueTagsInDirectory(FILE * fp, Song * song, void *data) +static int listUniqueTagsInDirectory(int fd, Song * song, void *data) { ListCommandItem *item = data; int i; @@ -393,12 +393,12 @@ static int listUniqueTagsInDirectory(FILE * fp, Song * song, void *data) } } - visitTag(fp, song, item->tagType); + visitTag(fd, song, item->tagType); return 0; } -int listAllUniqueTags(FILE * fp, int type, int numConditionals, +int listAllUniqueTags(int fd, int type, int numConditionals, LocateTagItem * conditionals) { int ret; @@ -409,11 +409,11 @@ int listAllUniqueTags(FILE * fp, int type, int numConditionals, resetVisitedFlagsInTagTracker(type); } - ret = traverseAllIn(fp, NULL, listUniqueTagsInDirectory, NULL, + ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL, (void *)item); if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) { - printVisitedInTagTracker(fp, type); + printVisitedInTagTracker(fd, type); } freeListCommandItem(item); @@ -421,7 +421,7 @@ int listAllUniqueTags(FILE * fp, int type, int numConditionals, return ret; } -static int sumSavedFilenameMemoryInDirectory(FILE * fp, Directory * dir, +static int sumSavedFilenameMemoryInDirectory(int fd, Directory * dir, void *data) { int *sum = data; @@ -435,7 +435,7 @@ static int sumSavedFilenameMemoryInDirectory(FILE * fp, Directory * dir, return 0; } -static int sumSavedFilenameMemoryInSong(FILE * fp, Song * song, void *data) +static int sumSavedFilenameMemoryInSong(int fd, Song * song, void *data) { int *sum = data; @@ -448,7 +448,7 @@ void printSavedMemoryFromFilenames(void) { int sum = 0; - traverseAllIn(stderr, NULL, sumSavedFilenameMemoryInSong, + traverseAllIn(STDERR_FILENO, NULL, sumSavedFilenameMemoryInSong, sumSavedFilenameMemoryInDirectory, (void *)&sum); DEBUG("saved memory from filenames: %i\n", sum); diff --git a/src/dbUtils.h b/src/dbUtils.h index e0d306fd0..7dd63a168 100644 --- a/src/dbUtils.h +++ b/src/dbUtils.h @@ -43,22 +43,22 @@ void freeLocateTagItemArray(int count, LocateTagItem * array); void freeLocateTagItem(LocateTagItem * item); -int printAllIn(FILE * fp, char *name); +int printAllIn(int fd, char *name); -int addAllIn(FILE * fp, char *name); +int addAllIn(int fd, char *name); -int printInfoForAllIn(FILE * fp, char *name); +int printInfoForAllIn(int fd, char *name); -int searchForSongsIn(FILE * fp, char *name, int numItems, +int searchForSongsIn(int fd, char *name, int numItems, LocateTagItem * items); -int findSongsIn(FILE * fp, char *name, int numItems, LocateTagItem * items); +int findSongsIn(int fd, char *name, int numItems, LocateTagItem * items); -int countSongsIn(FILE * fp, char *name); +int countSongsIn(int fd, char *name); -unsigned long sumSongTimesIn(FILE * fp, char *name); +unsigned long sumSongTimesIn(int fd, char *name); -int listAllUniqueTags(FILE * fp, int type, int numConditiionals, +int listAllUniqueTags(int fd, int type, int numConditiionals, LocateTagItem * conditionals); void printSavedMemoryFromFilenames(); diff --git a/src/directory.c b/src/directory.c index 85060670a..0bf2b6453 100644 --- a/src/directory.c +++ b/src/directory.c @@ -159,10 +159,10 @@ void readDirectoryDBIfUpdateIsFinished() } } -int updateInit(FILE * fp, List * pathList) +int updateInit(int fd, List * pathList) { if (directory_updatePid > 0) { - commandError(fp, ACK_ERROR_UPDATE_ALREADY, "already updating", + commandError(fd, ACK_ERROR_UPDATE_ALREADY, "already updating", NULL); return -1; } @@ -216,7 +216,7 @@ int updateInit(FILE * fp, List * pathList) } else if (directory_updatePid < 0) { unblockSignals(); ERROR("updateInit: Problems forking()'ing\n"); - commandError(fp, ACK_ERROR_SYSTEM, + commandError(fd, ACK_ERROR_SYSTEM, "problems trying to update", NULL); directory_updatePid = 0; return -1; @@ -228,7 +228,7 @@ int updateInit(FILE * fp, List * pathList) directory_updateJobId = 1; DEBUG("updateInit: fork()'d update child for update job id %i\n", (int)directory_updateJobId); - myfprintf(fp, "updating_db: %i\n", (int)directory_updateJobId); + fdprintf(fd, "updating_db: %i\n", (int)directory_updateJobId); return 0; } @@ -871,33 +871,33 @@ static Directory *getDirectory(char *name) return getSubDirectory(mp3rootDirectory, name, &shortname); } -static int printDirectoryList(FILE * fp, DirectoryList * directoryList) +static int printDirectoryList(int fd, DirectoryList * directoryList) { ListNode *node = directoryList->firstNode; Directory *directory; while (node != NULL) { directory = (Directory *) node->data; - myfprintf(fp, "%s%s\n", DIRECTORY_DIR, - getDirectoryPath(directory)); + fdprintf(fd, "%s%s\n", DIRECTORY_DIR, + getDirectoryPath(directory)); node = node->nextNode; } return 0; } -int printDirectoryInfo(FILE * fp, char *name) +int printDirectoryInfo(int fd, char *name) { Directory *directory; if ((directory = getDirectory(name)) == NULL) { - commandError(fp, ACK_ERROR_NO_EXIST, "directory not found", + commandError(fd, ACK_ERROR_NO_EXIST, "directory not found", NULL); return -1; } - printDirectoryList(fp, directory->subDirectories); - printSongInfoFromList(fp, directory->songs); + printDirectoryList(fd, directory->subDirectories); + printSongInfoFromList(fd, directory->songs); return 0; } @@ -1208,8 +1208,8 @@ int readDirectoryDB() readDirectoryInfo(fp, mp3rootDirectory); while (fclose(fp) && errno == EINTR) ; - stats.numberOfSongs = countSongsIn(stderr, NULL); - stats.dbPlayTime = sumSongTimesIn(stderr, NULL); + stats.numberOfSongs = countSongsIn(STDERR_FILENO, NULL); + stats.dbPlayTime = sumSongTimesIn(STDERR_FILENO, NULL); if (stat(dbFile, &st) == 0) directory_dbModTime = st.st_mtime; @@ -1237,10 +1237,10 @@ void updateMp3Directory() return; } -static int traverseAllInSubDirectory(FILE * fp, Directory * directory, - int (*forEachSong) (FILE *, Song *, +static int traverseAllInSubDirectory(int fd, Directory * directory, + int (*forEachSong) (int, Song *, void *), - int (*forEachDir) (FILE *, Directory *, + int (*forEachDir) (int, Directory *, void *), void *data) { ListNode *node = directory->songs->firstNode; @@ -1249,7 +1249,7 @@ static int traverseAllInSubDirectory(FILE * fp, Directory * directory, int errFlag = 0; if (forEachDir) { - errFlag = forEachDir(fp, directory, data); + errFlag = forEachDir(fd, directory, data); if (errFlag) return errFlag; } @@ -1257,7 +1257,7 @@ static int traverseAllInSubDirectory(FILE * fp, Directory * directory, if (forEachSong) { while (node != NULL && !errFlag) { song = (Song *) node->data; - errFlag = forEachSong(fp, song, data); + errFlag = forEachSong(fd, song, data); node = node->nextNode; } if (errFlag) @@ -1268,7 +1268,7 @@ static int traverseAllInSubDirectory(FILE * fp, Directory * directory, while (node != NULL && !errFlag) { dir = (Directory *) node->data; - errFlag = traverseAllInSubDirectory(fp, dir, forEachSong, + errFlag = traverseAllInSubDirectory(fd, dir, forEachSong, forEachDir, data); node = node->nextNode; } @@ -1276,23 +1276,23 @@ static int traverseAllInSubDirectory(FILE * fp, Directory * directory, return errFlag; } -int traverseAllIn(FILE * fp, char *name, - int (*forEachSong) (FILE *, Song *, void *), - int (*forEachDir) (FILE *, Directory *, void *), void *data) +int traverseAllIn(int fd, char *name, + int (*forEachSong) (int, Song *, void *), + int (*forEachDir) (int, Directory *, void *), void *data) { Directory *directory; if ((directory = getDirectory(name)) == NULL) { Song *song; if ((song = getSongFromDB(name)) && forEachSong) { - return forEachSong(fp, song, data); + return forEachSong(fd, song, data); } - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "directory or file not found", NULL); return -1; } - return traverseAllInSubDirectory(fp, directory, forEachSong, forEachDir, + return traverseAllInSubDirectory(fd, directory, forEachSong, forEachDir, data); } @@ -1315,8 +1315,8 @@ void initMp3Directory() mp3rootDirectory = newDirectory(NULL, NULL); exploreDirectory(mp3rootDirectory); freeAllDirectoryStats(mp3rootDirectory); - stats.numberOfSongs = countSongsIn(stderr, NULL); - stats.dbPlayTime = sumSongTimesIn(stderr, NULL); + stats.numberOfSongs = countSongsIn(STDERR_FILENO, NULL); + stats.dbPlayTime = sumSongTimesIn(STDERR_FILENO, NULL); if (stat(getDbFile(), &st) == 0) directory_dbModTime = st.st_mtime; diff --git a/src/directory.h b/src/directory.h index e4b7ee25c..975b32ae2 100644 --- a/src/directory.h +++ b/src/directory.h @@ -45,13 +45,13 @@ int isUpdatingDB(); void directory_sigChldHandler(int pid, int status); -int updateInit(FILE * fp, List * pathList); +int updateInit(int fd, List * pathList); void initMp3Directory(); void closeMp3Directory(); -int printDirectoryInfo(FILE * fp, char *dirname); +int printDirectoryInfo(int fd, char *dirname); int checkDirectoryDB(); @@ -65,9 +65,9 @@ Song *getSongFromDB(char *file); time_t getDbModTime(); -int traverseAllIn(FILE * fp, char *name, - int (*forEachSong) (FILE *, Song *, void *), - int (*forEachDir) (FILE *, Directory *, void *), void *data); +int traverseAllIn(int fd, char *name, + int (*forEachSong) (int, Song *, void *), + int (*forEachDir) (int, Directory *, void *), void *data); #define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") diff --git a/src/gcc.h b/src/gcc.h new file mode 100644 index 000000000..62c78e733 --- /dev/null +++ b/src/gcc.h @@ -0,0 +1,50 @@ +#ifndef MPD_GCC_H +#define MPD_GCC_H + +/* this allows us to take advantage of special gcc features while still + * allowing other compilers to compile: + * + * example taken from: http://rlove.org/log/2005102601 + */ + +/* disabled (0) until I fix all the warnings :) */ +#if (0 && __GNUC__ >= 3) +# define mpd_const __attribute__ ((const)) +# define mpd_deprecated __attribute__ ((deprecated)) +# define mpd_malloc __attribute__ ((malloc)) +# define mpd_must_check __attribute__ ((warn_unused_result)) +# define mpd_noreturn __attribute__ ((noreturn)) +# define mpd_packed __attribute__ ((packed)) +/* these are very useful for type checking */ +# define mpd_printf __attribute__ ((format(printf,1,2))) +# define mpd_fprintf __attribute__ ((format(printf,2,3))) +# define mpd_fprintf_ __attribute__ ((format(printf,3,4))) +# define mpd_pure __attribute__ ((pure)) +# define mpd_scanf __attribute__ ((format(scanf,1,2))) +# define mpd_unused __attribute__ ((unused)) +# define mpd_used __attribute__ ((used)) +/* # define inline inline __attribute__ ((always_inline)) */ +# define mpd_noinline __attribute__ ((noinline)) +# define likely(x) __builtin_expect (!!(x), 1) +# define unlikely(x) __builtin_expect (!!(x), 0) +#else +# define mpd_const +# define mpd_deprecated +# define mpd_malloc +# define mpd_must_check +# define mpd_noreturn +# define mpd_packed +# define mpd_printf +# define mpd_fprintf +# define mpd_fprintf_ +# define mpd_pure +# define mpd_scanf +# define mpd_unused +# define mpd_used +/* # define inline */ +# define mpd_noinline +# define likely(x) (x) +# define unlikely(x) (x) +#endif + +#endif /* MPD_GCC_H */ diff --git a/src/interface.c b/src/interface.c index dbec9b8a9..a75890ac4 100644 --- a/src/interface.c +++ b/src/interface.c @@ -24,7 +24,7 @@ #include "listen.h" #include "playlist.h" #include "permission.h" -#include "sig_handlers.h" +#include "sllist.h" #include <stdio.h> #include <stdlib.h> @@ -41,7 +41,7 @@ #include <errno.h> #include <signal.h> -#define GREETING "OK MPD" +#define GREETING "OK MPD " VERSION "\n" #define INTERFACE_MAX_BUFFER_LENGTH (40960) #define INTERFACE_LIST_MODE_BEGIN "command_list_begin" @@ -61,26 +61,36 @@ static size_t interface_max_command_list_size = static size_t interface_max_output_buffer_size = INTERFACE_MAX_OUTPUT_BUFFER_SIZE_DEFAULT; +/* maybe make conf option for this, or... 32 might be good enough */ +static long int interface_list_cache_size = 32; + +/* shared globally between all interfaces: */ +static struct strnode *list_cache = NULL; +static struct strnode *list_cache_head = NULL; +static struct strnode *list_cache_tail = NULL; + typedef struct _Interface { char buffer[INTERFACE_MAX_BUFFER_LENGTH]; int bufferLength; int bufferPos; int fd; /* file descriptor */ - FILE *fp; /* file pointer */ - int open; /* open/used */ int permission; time_t lastTime; - List *commandList; /* for when in list mode */ - int commandListOK; /* print OK after each command execution */ - size_t commandListSize; /* mem commandList consumes */ - List *bufferList; /* for output if client is slow */ - size_t outputBufferSize; /* mem bufferList consumes */ + struct strnode *cmd_list; /* for when in list mode */ + struct strnode *cmd_list_tail; /* for when in list mode */ + int cmd_list_OK; /* print OK after each command execution */ + int cmd_list_size; /* mem cmd_list consumes */ + int cmd_list_dup; /* has the cmd_list been copied to private space? */ + struct sllnode *deferred_send; /* for output if client is slow */ + int deferred_bytes; /* mem deferred_send consumes */ int expired; /* set whether this interface should be closed on next check of old interfaces */ int num; /* interface number */ - char *outBuffer; - int outBuflen; - int outBufSize; + + char *send_buf; + int send_buf_used; /* bytes used this instance */ + int send_buf_size; /* bytes usable this instance */ + int send_buf_alloc; /* bytes actually allocated */ } Interface; static Interface *interfaces = NULL; @@ -89,66 +99,150 @@ static void flushInterfaceBuffer(Interface * interface); static void printInterfaceOutBuffer(Interface * interface); +#ifdef SO_SNDBUF +static int get_default_snd_buf_size(Interface * interface) +{ + int new_size; + socklen_t sockOptLen = sizeof(int); + + if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF, + (char *)&new_size, &sockOptLen) < 0) { + DEBUG("problem getting sockets send buffer size\n"); + return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; + } + if (new_size > 0) + return new_size; + DEBUG("sockets send buffer size is not positive\n"); + return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; +} +#else /* !SO_SNDBUF */ +static int get_default_snd_buf_size(Interface * interface) +{ + return INTERFACE_DEFAULT_OUT_BUFFER_SIZE; +} +#endif /* !SO_SNDBUF */ + +static void set_send_buf_size(Interface * interface) +{ + int new_size = get_default_snd_buf_size(interface); + if (interface->send_buf_size != new_size) { + interface->send_buf_size = new_size; + /* don't resize to get smaller, only bigger */ + if (interface->send_buf_alloc < new_size) { + if (interface->send_buf) + free(interface->send_buf); + interface->send_buf = malloc(new_size); + interface->send_buf_alloc = new_size; + } + } +} + static void openInterface(Interface * interface, int fd) { int flags; - assert(interface->open == 0); + assert(interface->fd < 0); + interface->cmd_list_size = 0; + interface->cmd_list_dup = 0; + interface->cmd_list_OK = -1; interface->bufferLength = 0; interface->bufferPos = 0; interface->fd = fd; - /* fcntl(interface->fd,F_SETOWN,(int)getpid()); */ while ((flags = fcntl(fd, F_GETFL)) < 0 && errno == EINTR) ; - flags |= O_NONBLOCK; - while (fcntl(interface->fd, F_SETFL, flags) < 0 && errno == EINTR) ; - while ((interface->fp = fdopen(fd, "rw")) == NULL && errno == EINTR) ; - interface->open = 1; + while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0 && errno == EINTR) ; interface->lastTime = time(NULL); - interface->commandList = NULL; - interface->bufferList = NULL; + interface->cmd_list = NULL; + interface->cmd_list_tail = NULL; + interface->deferred_send = NULL; interface->expired = 0; - interface->outputBufferSize = 0; - interface->outBuflen = 0; + interface->deferred_bytes = 0; + interface->send_buf_used = 0; interface->permission = getDefaultPermissions(); + set_send_buf_size(interface); - interface->outBufSize = INTERFACE_DEFAULT_OUT_BUFFER_SIZE; -#ifdef SO_SNDBUF - { - int getSize; - unsigned int sockOptLen = sizeof(int); - - if (getsockopt(interface->fd, SOL_SOCKET, SO_SNDBUF, - (char *)&getSize, &sockOptLen) < 0) { - DEBUG("problem getting sockets send buffer size\n"); - } else if (getSize <= 0) { - DEBUG("sockets send buffer size is not positive\n"); + xwrite(fd, GREETING, strlen(GREETING)); +} + +static void free_cmd_list(struct strnode *list) +{ + struct strnode *tmp = list; + + while (tmp) { + struct strnode *next = tmp->next; + if (tmp >= list_cache_head && tmp <= list_cache_tail) { + /* inside list_cache[] array */ + tmp->data = NULL; + tmp->next = NULL; } else - interface->outBufSize = getSize; + free(tmp); + tmp = next; } -#endif - interface->outBuffer = malloc(interface->outBufSize); +} - myfprintf(interface->fp, "%s %s\n", GREETING, VERSION); - printInterfaceOutBuffer(interface); +static void cmd_list_clone(Interface * interface) +{ + struct strnode *new = dup_strlist(interface->cmd_list); + free_cmd_list(interface->cmd_list); + interface->cmd_list = new; + interface->cmd_list_dup = 1; + + /* new tail */ + while (new && new->next) + new = new->next; + interface->cmd_list_tail = new; } -static void closeInterface(Interface * interface) +static void new_cmd_list_ptr(Interface * interface, char *s, const int size) { - if (!interface->open) - return; + int i; + struct strnode *new; + + if (!interface->cmd_list_dup) { + for (i = interface_list_cache_size - 1; i >= 0; --i) { + if (list_cache[i].data) + continue; + new = &(list_cache[i]); + new->data = s; + /* implied in free_cmd_list() and init: */ + /* last->next->next = NULL; */ + goto out; + } + } - interface->open = 0; + /* allocate from the heap */ + new = interface->cmd_list_dup ? new_strnode_dup(s, size) + : new_strnode(s); +out: + if (interface->cmd_list) { + interface->cmd_list_tail->next = new; + interface->cmd_list_tail = new; + } else + interface->cmd_list = interface->cmd_list_tail = new; +} - while (fclose(interface->fp) && errno == EINTR) ; +static void closeInterface(Interface * interface) +{ + struct sllnode *buf; + if (interface->fd < 0) + return; + xclose(interface->fd); + interface->fd = -1; - if (interface->commandList) - freeList(interface->commandList); - if (interface->bufferList) - freeList(interface->bufferList); + if (interface->cmd_list) { + free_cmd_list(interface->cmd_list); + interface->cmd_list = NULL; + } - free(interface->outBuffer); + if ((buf = interface->deferred_send)) { + do { + struct sllnode *prev = buf; + buf = buf->next; + free(prev); + } while (buf); + interface->deferred_send = NULL; + } SECURE("interface %i: closed\n", interface->num); } @@ -157,11 +251,12 @@ void openAInterface(int fd, struct sockaddr *addr) { int i; - for (i = 0; i < interface_max_connections && interfaces[i].open; i++) ; + for (i = 0; i < interface_max_connections + && interfaces[i].fd >= 0; i++) /* nothing */ ; if (i == interface_max_connections) { ERROR("Max Connections Reached!\n"); - while (close(fd) && errno == EINTR) ; + xclose(fd); } else { SECURE("interface %i: opened from ", i); switch (addr->sa_family) { @@ -207,74 +302,60 @@ static int processLineOfInput(Interface * interface) int ret = 1; char *line = interface->buffer + interface->bufferPos; - if (interface->bufferLength - interface->bufferPos > 1) { - if (interface->buffer[interface->bufferLength - 2] == '\r') { - interface->buffer[interface->bufferLength - 2] = '\0'; - } - } - - if (interface->commandList) { + if (interface->cmd_list_OK >= 0) { if (strcmp(line, INTERFACE_LIST_MODE_END) == 0) { DEBUG("interface %i: process command " "list\n", interface->num); - ret = processListOfCommands(interface->fp, + ret = processListOfCommands(interface->fd, &(interface->permission), &(interface->expired), - interface->commandListOK, - interface->commandList); + interface->cmd_list_OK, + interface->cmd_list); DEBUG("interface %i: process command " "list returned %i\n", interface->num, ret); if (ret == 0) - commandSuccess(interface->fp); + commandSuccess(interface->fd); else if (ret == COMMAND_RETURN_CLOSE - || interface->expired) { - + || interface->expired) closeInterface(interface); - } - printInterfaceOutBuffer(interface); - freeList(interface->commandList); - interface->commandList = NULL; + printInterfaceOutBuffer(interface); + free_cmd_list(interface->cmd_list); + interface->cmd_list = NULL; + interface->cmd_list_OK = -1; } else { - interface->commandListSize += sizeof(ListNode); - interface->commandListSize += strlen(line) + 1; - if (interface->commandListSize > + size_t len = strlen(line) + 1; + interface->cmd_list_size += len; + if (interface->cmd_list_size > interface_max_command_list_size) { ERROR("interface %i: command " - "list size (%lli) is " + "list size (%i) is " "larger than the max " - "(%lli)\n", + "(%i)\n", interface->num, - (long long)interface-> - commandListSize, (long long) + interface->cmd_list_size, interface_max_command_list_size); closeInterface(interface); ret = COMMAND_RETURN_CLOSE; - } else { - insertInListWithoutKey(interface->commandList, - strdup(line)); - } + } else + new_cmd_list_ptr(interface, line, len); } } else { if (strcmp(line, INTERFACE_LIST_MODE_BEGIN) == 0) { - interface->commandList = makeList(free, 1); - interface->commandListSize = sizeof(List); - interface->commandListOK = 0; + interface->cmd_list_OK = 0; ret = 1; } else if (strcmp(line, INTERFACE_LIST_OK_MODE_BEGIN) == 0) { - interface->commandList = makeList(free, 1); - interface->commandListSize = sizeof(List); - interface->commandListOK = 1; + interface->cmd_list_OK = 1; ret = 1; } else { DEBUG("interface %i: process command \"%s\"\n", interface->num, line); - ret = processCommand(interface->fp, + ret = processCommand(interface->fd, &(interface->permission), line); DEBUG("interface %i: command returned %i\n", interface->num, ret); if (ret == 0) - commandSuccess(interface->fp); + commandSuccess(interface->fd); else if (ret == COMMAND_RETURN_CLOSE || interface->expired) { closeInterface(interface); @@ -289,12 +370,18 @@ static int processLineOfInput(Interface * interface) static int processBytesRead(Interface * interface, int bytesRead) { int ret = 0; + char *buf_tail = &(interface->buffer[interface->bufferLength - 1]); while (bytesRead > 0) { interface->bufferLength++; bytesRead--; - if (interface->buffer[interface->bufferLength - 1] == '\n') { - interface->buffer[interface->bufferLength - 1] = '\0'; + buf_tail++; + if (*buf_tail == '\n') { + *buf_tail = '\0'; + if (interface->bufferLength - interface->bufferPos > 1) { + if (*(buf_tail - 1) == '\r') + *(buf_tail - 1) = '\0'; + } ret = processLineOfInput(interface); interface->bufferPos = interface->bufferLength; } @@ -305,6 +392,9 @@ static int processBytesRead(Interface * interface, int bytesRead) closeInterface(interface); return 1; } + if (interface->cmd_list_OK >= 0 && + !interface->cmd_list_dup) + cmd_list_clone(interface); interface->bufferLength -= interface->bufferPos; memmove(interface->buffer, interface->buffer + interface->bufferPos, @@ -347,8 +437,8 @@ static void addInterfacesReadyToReadAndListenSocketToFdSet(fd_set * fds, addListenSocketsToFdSet(fds, fdmax); for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open && !interfaces[i].expired - && !interfaces[i].bufferList) { + if (interfaces[i].fd >= 0 && !interfaces[i].expired + && !interfaces[i].deferred_send) { FD_SET(interfaces[i].fd, fds); if (*fdmax < interfaces[i].fd) *fdmax = interfaces[i].fd; @@ -363,8 +453,8 @@ static void addInterfacesForBufferFlushToFdSet(fd_set * fds, int *fdmax) FD_ZERO(fds); for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open && !interfaces[i].expired - && interfaces[i].bufferList) { + if (interfaces[i].fd >= 0 && !interfaces[i].expired + && interfaces[i].deferred_send) { FD_SET(interfaces[i].fd, fds); if (*fdmax < interfaces[i].fd) *fdmax = interfaces[i].fd; @@ -382,7 +472,7 @@ static void closeNextErroredInterface(void) tv.tv_usec = 0; for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open) { + if (interfaces[i].fd >= 0) { FD_ZERO(&fds); FD_SET(interfaces[i].fd, &fds); if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) { @@ -424,7 +514,7 @@ int doIOForInterfaces(void) getConnections(&rfds); for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open + if (interfaces[i].fd >= 0 && FD_ISSET(interfaces[i].fd, &rfds)) { if (COMMAND_RETURN_KILL == interfaceReadInput(&(interfaces[i]))) { @@ -432,7 +522,7 @@ int doIOForInterfaces(void) } interfaces[i].lastTime = time(NULL); } - if (interfaces[i].open + if (interfaces[i].fd >= 0 && FD_ISSET(interfaces[i].fd, &wfds)) { flushInterfaceBuffer(&interfaces[i]); interfaces[i].lastTime = time(NULL); @@ -504,8 +594,15 @@ void initInterfaces(void) interfaces = malloc(sizeof(Interface) * interface_max_connections); + list_cache = calloc(interface_list_cache_size, sizeof(struct strnode)); + list_cache_head = &(list_cache[0]); + list_cache_tail = &(list_cache[interface_list_cache_size - 1]); + for (i = 0; i < interface_max_connections; i++) { - interfaces[i].open = 0; + interfaces[i].fd = -1; + interfaces[i].send_buf = NULL; + interfaces[i].send_buf_size = 0; + interfaces[i].send_buf_alloc = 0; interfaces[i].num = i; } } @@ -514,13 +611,13 @@ static void closeAllInterfaces(void) { int i; - fflush(NULL); - for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open) { + if (interfaces[i].fd > 0) closeInterface(&(interfaces[i])); - } + if (interfaces[i].send_buf) + free(interfaces[i].send_buf); } + free(list_cache); } void freeAllInterfaces(void) @@ -537,7 +634,7 @@ void closeOldInterfaces(void) int i; for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open) { + if (interfaces[i].fd > 0) { if (interfaces[i].expired) { DEBUG("interface %i: expired\n", i); closeInterface(&(interfaces[i])); @@ -552,37 +649,45 @@ void closeOldInterfaces(void) static void flushInterfaceBuffer(Interface * interface) { - ListNode *node = NULL; - char *str; + struct sllnode *buf; int ret = 0; - while ((node = interface->bufferList->firstNode)) { - str = (char *)node->data; - if ((ret = write(interface->fd, str, strlen(str))) < 0) + buf = interface->deferred_send; + while (buf) { + ret = write(interface->fd, buf->data, buf->size); + if (ret < 0) break; - else if (ret < strlen(str)) { - interface->outputBufferSize -= ret; - str = strdup(&str[ret]); - free(node->data); - node->data = str; + else if (ret < buf->size) { + interface->deferred_bytes -= ret; + buf->data += ret; + buf->size -= ret; } else { - interface->outputBufferSize -= strlen(str) + 1; - interface->outputBufferSize -= sizeof(ListNode); - deleteNodeFromList(interface->bufferList, node); + struct sllnode *tmp = buf; + interface->deferred_bytes -= (buf->size + + sizeof(struct sllnode)); + buf = buf->next; + free(tmp); + interface->deferred_send = buf; } interface->lastTime = time(NULL); } - if (!interface->bufferList->firstNode) { - DEBUG("interface %i: buffer empty\n", interface->num); - freeList(interface->bufferList); - interface->bufferList = NULL; + if (!interface->deferred_send) { + DEBUG("interface %i: buffer empty %i\n", interface->num, + interface->deferred_bytes); + assert(interface->deferred_bytes == 0); } else if (ret < 0 && errno != EAGAIN && errno != EINTR) { /* cause interface to close */ DEBUG("interface %i: problems flushing buffer\n", interface->num); - freeList(interface->bufferList); - interface->bufferList = NULL; + buf = interface->deferred_send; + do { + struct sllnode *prev = buf; + buf = buf->next; + free(prev); + } while (buf); + interface->deferred_send = NULL; + interface->deferred_bytes = 0; interface->expired = 1; } } @@ -593,10 +698,12 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen) int copylen; Interface *interface; + assert(fd > 0); + if (i >= interface_max_connections || - !interfaces[i].open || interfaces[i].fd != fd) { + interfaces[i].fd < 0 || interfaces[i].fd != fd) { for (i = 0; i < interface_max_connections; i++) { - if (interfaces[i].open && interfaces[i].fd == fd) + if (interfaces[i].fd == fd) break; } if (i == interface_max_connections) @@ -610,17 +717,15 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen) interface = interfaces + i; while (buflen > 0 && !interface->expired) { - copylen = buflen > - interface->outBufSize - interface->outBuflen ? - interface->outBufSize - interface->outBuflen : buflen; - memcpy(interface->outBuffer + interface->outBuflen, buffer, + int left = interface->send_buf_size - interface->send_buf_used; + copylen = buflen > left ? left : buflen; + memcpy(interface->send_buf + interface->send_buf_used, buffer, copylen); buflen -= copylen; - interface->outBuflen += copylen; + interface->send_buf_used += copylen; buffer += copylen; - if (interface->outBuflen >= interface->outBufSize) { + if (interface->send_buf_used >= interface->send_buf_size) printInterfaceOutBuffer(interface); - } } return 0; @@ -628,73 +733,63 @@ int interfacePrintWithFD(int fd, char *buffer, int buflen) static void printInterfaceOutBuffer(Interface * interface) { - char *buffer; int ret; + struct sllnode *buf; - if (!interface->open || interface->expired || !interface->outBuflen) { + if (interface->fd < 0 || interface->expired || + !interface->send_buf_used) return; - } - if (interface->bufferList) { - interface->outputBufferSize += sizeof(ListNode); - interface->outputBufferSize += interface->outBuflen + 1; - if (interface->outputBufferSize > + if ((buf = interface->deferred_send)) { + interface->deferred_bytes += sizeof(struct sllnode) + + interface->send_buf_used; + if (interface->deferred_bytes > interface_max_output_buffer_size) { - ERROR("interface %i: output buffer size (%lli) is " - "larger than the max (%lli)\n", + ERROR("interface %i: output buffer size (%li) is " + "larger than the max (%li)\n", interface->num, - (long long)interface->outputBufferSize, - (long long)interface_max_output_buffer_size); + (long)interface->deferred_bytes, + (long)interface_max_output_buffer_size); /* cause interface to close */ - freeList(interface->bufferList); - interface->bufferList = NULL; interface->expired = 1; + do { + struct sllnode *prev = buf; + buf = buf->next; + free(prev); + } while (buf); + interface->deferred_send = NULL; + interface->deferred_bytes = 0; } else { - buffer = malloc(interface->outBuflen + 1); - memcpy(buffer, interface->outBuffer, - interface->outBuflen); - buffer[interface->outBuflen] = '\0'; - insertInListWithoutKey(interface->bufferList, - (void *)buffer); - flushInterfaceBuffer(interface); + while (buf->next) + buf = buf->next; + buf->next = new_sllnode(interface->send_buf, + interface->send_buf_used); } } else { - if ((ret = write(interface->fd, interface->outBuffer, - interface->outBuflen)) < 0) { + if ((ret = write(interface->fd, interface->send_buf, + interface->send_buf_used)) < 0) { if (errno == EAGAIN || errno == EINTR) { - buffer = malloc(interface->outBuflen + 1); - memcpy(buffer, interface->outBuffer, - interface->outBuflen); - buffer[interface->outBuflen] = '\0'; - interface->bufferList = makeList(free, 1); - insertInListWithoutKey(interface->bufferList, - (void *)buffer); + interface->deferred_send = + new_sllnode(interface->send_buf, + interface->send_buf_used); } else { DEBUG("interface %i: problems writing\n", interface->num); interface->expired = 1; return; } - } else if (ret < interface->outBuflen) { - buffer = malloc(interface->outBuflen - ret + 1); - memcpy(buffer, interface->outBuffer + ret, - interface->outBuflen - ret); - buffer[interface->outBuflen - ret] = '\0'; - interface->bufferList = makeList(free, 1); - insertInListWithoutKey(interface->bufferList, buffer); + } else if (ret < interface->send_buf_used) { + interface->deferred_send = + new_sllnode(interface->send_buf + ret, + interface->send_buf_used - ret); } - /* if we needed to create buffer, initialize bufferSize info */ - if (interface->bufferList) { + if (interface->deferred_send) { DEBUG("interface %i: buffer created\n", interface->num); - interface->outputBufferSize = sizeof(List); - interface->outputBufferSize += sizeof(ListNode); - interface->outputBufferSize += strlen((char *) - interface-> - bufferList-> - firstNode->data) + - 1; + interface->deferred_bytes = + interface->deferred_send->size + + sizeof(struct sllnode); } } - interface->outBuflen = 0; + interface->send_buf_used = 0; } @@ -32,12 +32,12 @@ static char *remoteUrlPrefixes[] = { NULL }; -int printRemoteUrlHandlers(FILE * fp) +int printRemoteUrlHandlers(int fd) { char **prefixes = remoteUrlPrefixes; while (*prefixes) { - myfprintf(fp, "handler: %s\n", *prefixes); + fdprintf(fd, "handler: %s\n", *prefixes); prefixes++; } @@ -100,7 +100,7 @@ int isRemoteUrl(char *url) return 0; } -int lsPlaylists(FILE * fp, char *utf8path) +int lsPlaylists(int fd, char *utf8path) { DIR *dir; struct stat st; @@ -166,7 +166,7 @@ int lsPlaylists(FILE * fp, char *utf8path) node = list->firstNode; while (node != NULL) { if (!strchr(node->key, '\n')) { - myfprintf(fp, "playlist: %s%s\n", dup, + fdprintf(fd, "playlist: %s%s\n", dup, node->key); } node = node->nextNode; @@ -29,7 +29,7 @@ #include <unistd.h> #include <time.h> -int lsPlaylists(FILE * fp, char *utf8path); +int lsPlaylists(int fd, char *utf8path); char *getSuffix(char *utf8file); @@ -47,6 +47,6 @@ InputPlugin *hasMusicSuffix(char *utf8file, unsigned int next); InputPlugin *isMusic(char *utf8file, time_t * mtime, unsigned int next); -int printRemoteUrlHandlers(FILE * fp); +int printRemoteUrlHandlers(int fd); #endif diff --git a/src/myfprintf.c b/src/myfprintf.c index d9149499c..7a547f92e 100644 --- a/src/myfprintf.c +++ b/src/myfprintf.c @@ -21,6 +21,7 @@ #include "path.h" #include "log.h" #include "conf.h" +#include "utils.h" #include <stdarg.h> #include <sys/param.h> @@ -38,28 +39,41 @@ static FILE *myfprintf_err; static char *myfprintf_outFilename; static char *myfprintf_errFilename; -static void blockingWrite(int fd, char *string, int len) +static void blockingWrite(const int fd, const char *string, size_t len) { - int ret; - while (len) { - ret = write(fd, string, len); - if (ret == 0) + size_t ret = xwrite(fd, string, len); + if (ret == len) return; - if (ret < 0) { - switch (errno) { - case EAGAIN: - case EINTR: - continue; - default: - return; - } + if (ret >= 0) { + len -= ret; + string += ret; + continue; } - len -= ret; - string += ret; + return; /* error */ } } +void vfdprintf(const int fd, const char *fmt, va_list args) +{ + static char buffer[BUFFER_LENGTH + 1]; + char *buf = buffer; + size_t len; + + vsnprintf(buf, BUFFER_LENGTH, fmt, args); + len = strlen(buf); + if (interfacePrintWithFD(fd, buf, len) < 0) + blockingWrite(fd, buf, len); +} + +mpd_fprintf void fdprintf(const int fd, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfdprintf(fd, fmt, args); + va_end(args); +} + void myfprintfStdLogMode(FILE * out, FILE * err) { myfprintf_stdLogMode = 1; @@ -69,38 +83,6 @@ void myfprintfStdLogMode(FILE * out, FILE * err) myfprintf_errFilename = getConfigParamValue(CONF_ERROR_FILE); } -void myfprintf(FILE * fp, char *format, ...) -{ - static char buffer[BUFFER_LENGTH + 1]; - va_list arglist; - int fd = fileno(fp); - - va_start(arglist, format); - if (fd == 1 || fd == 2) { - if (myfprintf_stdLogMode) { - time_t t = time(NULL); - if (fd == 1) - fp = myfprintf_out; - else - fp = myfprintf_err; - strftime(buffer, 14, "%b %e %R", localtime(&t)); - blockingWrite(fd, buffer, strlen(buffer)); - blockingWrite(fd, " : ", 3); - } - vsnprintf(buffer, BUFFER_LENGTH, format, arglist); - blockingWrite(fd, buffer, strlen(buffer)); - } else { - int len; - vsnprintf(buffer, BUFFER_LENGTH, format, arglist); - len = strlen(buffer); - if (interfacePrintWithFD(fd, buffer, len) < 0) { - blockingWrite(fd, buffer, len); - } - } - - va_end(arglist); -} - int myfprintfCloseAndOpenLogFile(void) { if (myfprintf_stdLogMode) { diff --git a/src/myfprintf.h b/src/myfprintf.h index 4147e7ac0..fe918a101 100644 --- a/src/myfprintf.h +++ b/src/myfprintf.h @@ -20,12 +20,20 @@ #define MYFPRINTF_H #include "../config.h" +#include "gcc.h" +#include <stdarg.h> #include <stdio.h> void myfprintfStdLogMode(FILE * out, FILE * err); -void myfprintf(FILE * fp, char *format, ...); +mpd_fprintf void fdprintf(const int fd, const char *fmt, ...); +void vfdprintf(const int fd, const char *fmt, va_list arglist); + +#define myfprintf(fp, ...) do { \ + fprintf(fp, __VA_ARGS__); \ + fflush(fp); \ + } while (0) int myfprintfCloseAndOpenLogFile(); diff --git a/src/player.c b/src/player.c index 22c6ff88b..5ebf22f79 100644 --- a/src/player.c +++ b/src/player.c @@ -156,14 +156,11 @@ int playerInitReal() return 0; } -int playerPlay(FILE * fp, Song * song) +int playerPlay(int fd, Song * song) { PlayerControl *pc = &(getPlayerData()->playerControl); - if (fp == NULL) - fp = stderr; - - if (playerStop(fp) < 0) + if (playerStop(fd) < 0) return -1; if (song->tag) @@ -189,7 +186,7 @@ int playerPlay(FILE * fp, Song * song) return 0; } -int playerStop(FILE * fp) +int playerStop(int fd) { PlayerControl *pc = &(getPlayerData()->playerControl); @@ -219,7 +216,7 @@ void playerKill() kill(pid, SIGTERM); } -int playerPause(FILE * fp) +int playerPause(int fd) { PlayerControl *pc = &(getPlayerData()->playerControl); @@ -232,7 +229,7 @@ int playerPause(FILE * fp) return 0; } -int playerSetPause(FILE * fp, int pause) +int playerSetPause(int fd, int pause) { PlayerControl *pc = &(getPlayerData()->playerControl); @@ -242,11 +239,11 @@ int playerSetPause(FILE * fp, int pause) switch (pc->state) { case PLAYER_STATE_PLAY: if (pause) - playerPause(fp); + playerPause(fd); break; case PLAYER_STATE_PAUSE: if (!pause) - playerPause(fp); + playerPause(fd); break; } @@ -329,7 +326,7 @@ void playerCloseAudio() PlayerControl *pc = &(getPlayerData()->playerControl); if (getPlayerPid() > 0) { - if (playerStop(stderr) < 0) + if (playerStop(STDERR_FILENO) < 0) return; pc->closeAudio = 1; } @@ -393,12 +390,12 @@ void playerQueueUnlock() } } -int playerSeek(FILE * fp, Song * song, float time) +int playerSeek(int fd, Song * song, float time) { PlayerControl *pc = &(getPlayerData()->playerControl); if (pc->state == PLAYER_STATE_STOP) { - commandError(fp, ACK_ERROR_PLAYER_SYNC, + commandError(fd, ACK_ERROR_PLAYER_SYNC, "player not currently playing", NULL); return -1; } diff --git a/src/player.h b/src/player.h index b88907359..77d16174b 100644 --- a/src/player.h +++ b/src/player.h @@ -93,13 +93,13 @@ int playerInitReal(); void player_sigChldHandler(int pid, int status); -int playerPlay(FILE * fp, Song * song); +int playerPlay(int fd, Song * song); -int playerSetPause(FILE * fp, int pause); +int playerSetPause(int fd, int pause); -int playerPause(FILE * fp); +int playerPause(int fd); -int playerStop(FILE * fp); +int playerStop(int fd); void playerCloseAudio(); @@ -131,7 +131,7 @@ void playerQueueLock(); void playerQueueUnlock(); -int playerSeek(FILE * fp, Song * song, float time); +int playerSeek(int fd, Song * song, float time); void setPlayerCrossFade(float crossFadeInSeconds); diff --git a/src/playlist.c b/src/playlist.c index 2f4feee7d..288848fb0 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -89,7 +89,7 @@ static int playlist_noGoToNext = 0; static int playlist_saveAbsolutePaths = DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS; static void swapOrder(int a, int b); -static int playPlaylistOrderNumber(FILE * fp, int orderNum); +static int playPlaylistOrderNumber(int fd, int orderNum); static void randomizeOrder(int start, int end); char *getStateFile(void) @@ -223,11 +223,11 @@ void finishPlaylist(void) playlist.positionToId = NULL; } -int clearPlaylist(FILE * fp) +int clearPlaylist(int fd) { int i; - if (stopPlaylist(fp) < 0) + if (stopPlaylist(fd) < 0) return -1; for (i = 0; i < playlist.length; i++) { @@ -245,12 +245,12 @@ int clearPlaylist(FILE * fp) return 0; } -int showPlaylist(FILE * fp) +int showPlaylist(int fd) { int i; for (i = 0; i < playlist.length; i++) { - myfprintf(fp, "%i:%s\n", i, getSongUrl(playlist.songs[i])); + fdprintf(fd, "%i:%s\n", i, getSongUrl(playlist.songs[i])); } return 0; @@ -298,14 +298,14 @@ void savePlaylistState(void) myfprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE, (int)(getPlayerCrossFade())); myfprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); - showPlaylist(fp); + showPlaylist(fileno(fp)); myfprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END); while (fclose(fp) && errno == EINTR) ; } } -void loadPlaylistFromStateFile(FILE * fp, char *buffer, int state, int current, +void loadPlaylistFromStateFile(FILE *fp, char *buffer, int state, int current, int time) { char *temp; @@ -322,15 +322,17 @@ void loadPlaylistFromStateFile(FILE * fp, char *buffer, int state, int current, ERROR("error parsing state file \"%s\"\n", stateFile); exit(EXIT_FAILURE); } - if (addToPlaylist(stderr, temp, 0) == 0 && current == song) { + if (!addToPlaylist(STDERR_FILENO, temp, 0) && current == song) { if (state != PLAYER_STATE_STOP) { - playPlaylist(stderr, playlist.length - 1, 0); + playPlaylist(STDERR_FILENO, + playlist.length - 1, 0); } if (state == PLAYER_STATE_PAUSE) { - playerPause(stderr); + playerPause(STDERR_FILENO); } if (state != PLAYER_STATE_STOP) { - seekSongInPlaylist(stderr, playlist.length - 1, + seekSongInPlaylist(STDERR_FILENO, + playlist.length - 1, time); } } @@ -402,9 +404,11 @@ void readPlaylistState(void) (buffer [strlen(PLAYLIST_STATE_FILE_REPEAT)]), "1") == 0) { - setPlaylistRepeatStatus(stderr, 1); + setPlaylistRepeatStatus(STDERR_FILENO, + 1); } else - setPlaylistRepeatStatus(stderr, 0); + setPlaylistRepeatStatus(STDERR_FILENO, + 0); } else if (strncmp (buffer, PLAYLIST_STATE_FILE_CROSSFADE, @@ -423,9 +427,11 @@ void readPlaylistState(void) (buffer [strlen(PLAYLIST_STATE_FILE_RANDOM)]), "1") == 0) { - setPlaylistRandomStatus(stderr, 1); + setPlaylistRandomStatus(STDERR_FILENO, + 1); } else - setPlaylistRandomStatus(stderr, 0); + setPlaylistRandomStatus(STDERR_FILENO, + 0); } else if (strncmp(buffer, PLAYLIST_STATE_FILE_CURRENT, strlen(PLAYLIST_STATE_FILE_CURRENT)) == 0) { @@ -454,14 +460,13 @@ void readPlaylistState(void) } } -void printPlaylistSongInfo(FILE * fp, int song) +void printPlaylistSongInfo(int fd, int song) { - printSongInfo(fp, playlist.songs[song]); - myfprintf(fp, "Pos: %i\n", song); - myfprintf(fp, "Id: %i\n", playlist.positionToId[song]); + printSongInfo(fd, playlist.songs[song]); + fdprintf(fd, "Pos: %i\nId: %i\n", song, playlist.positionToId[song]); } -int playlistChanges(FILE * fp, mpd_uint32 version) +int playlistChanges(int fd, mpd_uint32 version) { int i; @@ -469,14 +474,14 @@ int playlistChanges(FILE * fp, mpd_uint32 version) if (version > playlist.version || playlist.songMod[i] >= version || playlist.songMod[i] == 0) { - printPlaylistSongInfo(fp, i); + printPlaylistSongInfo(fd, i); } } return 0; } -int playlistChangesPosId(FILE * fp, mpd_uint32 version) +int playlistChangesPosId(int fd, mpd_uint32 version) { int i; @@ -484,15 +489,15 @@ int playlistChangesPosId(FILE * fp, mpd_uint32 version) if (version > playlist.version || playlist.songMod[i] >= version || playlist.songMod[i] == 0) { - myfprintf(fp, "cpos: %i\n", i); - myfprintf(fp, "Id: %i\n", playlist.positionToId[i]); + fdprintf(fd, "cpos: %i\nId: %i\n", + i, playlist.positionToId[i]); } } return 0; } -int playlistInfo(FILE * fp, int song) +int playlistInfo(int fd, int song) { int i; int begin = 0; @@ -503,13 +508,13 @@ int playlistInfo(FILE * fp, int song) end = song + 1; } if (song >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song); return -1; } for (i = begin; i < end; i++) - printPlaylistSongInfo(fp, i); + printPlaylistSongInfo(fd, i); return 0; } @@ -518,13 +523,13 @@ int playlistInfo(FILE * fp, int song) if(id < 0 || id >= PLAYLIST_HASH_MULT*playlist_max_length || \ playlist.idToPosition[id] == -1 ) \ { \ - commandError(fp, ACK_ERROR_NO_EXIST, \ + commandError(fd, ACK_ERROR_NO_EXIST, \ "song id doesn't exist: \"%i\"", id); \ return -1; \ } \ } -int playlistId(FILE * fp, int id) +int playlistId(int fd, int id) { int i; int begin = 0; @@ -537,7 +542,7 @@ int playlistId(FILE * fp, int id) } for (i = begin; i < end; i++) - printPlaylistSongInfo(fp, i); + printPlaylistSongInfo(fd, i); return 0; } @@ -642,7 +647,7 @@ void clearPlayerQueue(void) } } -int addToPlaylist(FILE * fp, char *url, int printId) +int addToPlaylist(int fd, char *url, int printId) { Song *song; @@ -651,21 +656,21 @@ int addToPlaylist(FILE * fp, char *url, int printId) if ((song = getSongFromDB(url))) { } else if (!(isValidRemoteUtf8Url(url) && (song = newSong(url, SONG_TYPE_URL, NULL)))) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "\"%s\" is not in the music db or is " "not a valid url", url); return -1; } - return addSongToPlaylist(fp, song, printId); + return addSongToPlaylist(fd, song, printId); } -int addSongToPlaylist(FILE * fp, Song * song, int printId) +int addSongToPlaylist(int fd, Song * song, int printId) { int id; if (playlist.length == playlist_max_length) { - commandError(fp, ACK_ERROR_PLAYLIST_MAX, + commandError(fd, ACK_ERROR_PLAYLIST_MAX, "playlist is at the max size", NULL); return -1; } @@ -707,23 +712,23 @@ int addSongToPlaylist(FILE * fp, Song * song, int printId) incrPlaylistVersion(); if (printId) - myfprintf(fp, "Id: %i\n", id); + fdprintf(fd, "Id: %i\n", id); return 0; } -int swapSongsInPlaylist(FILE * fp, int song1, int song2) +int swapSongsInPlaylist(int fd, int song1, int song2) { int queuedSong = -1; int currentSong = -1; if (song1 < 0 || song1 >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song1); return -1; } if (song2 < 0 || song2 >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song2); return -1; } @@ -768,12 +773,12 @@ int swapSongsInPlaylist(FILE * fp, int song1, int song2) return 0; } -int swapSongsInPlaylistById(FILE * fp, int id1, int id2) +int swapSongsInPlaylistById(int fd, int id1, int id2) { checkSongId(id1); checkSongId(id2); - return swapSongsInPlaylist(fp, playlist.idToPosition[id1], + return swapSongsInPlaylist(fd, playlist.idToPosition[id1], playlist.idToPosition[id2]); } @@ -784,13 +789,13 @@ int swapSongsInPlaylistById(FILE * fp, int id1, int id2) playlist.songMod[to] = playlist.version; \ } -int deleteFromPlaylist(FILE * fp, int song) +int deleteFromPlaylist(int fd, int song) { int i; int songOrder; if (song < 0 || song >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song); return -1; } @@ -837,9 +842,9 @@ int deleteFromPlaylist(FILE * fp, int song) if (playlist_state != PLAYLIST_STATE_STOP && playlist.current == songOrder) { - /*if(playlist.current>=playlist.length) return playerStop(fp); - else return playPlaylistOrderNumber(fp,playlist.current); */ - playerStop(stderr); + /*if(playlist.current>=playlist.length) return playerStop(fd); + else return playPlaylistOrderNumber(fd,playlist.current); */ + playerStop(STDERR_FILENO); playlist_noGoToNext = 1; } @@ -856,11 +861,11 @@ int deleteFromPlaylist(FILE * fp, int song) return 0; } -int deleteFromPlaylistById(FILE * fp, int id) +int deleteFromPlaylistById(int fd, int id) { checkSongId(id); - return deleteFromPlaylist(fp, playlist.idToPosition[id]); + return deleteFromPlaylist(fd, playlist.idToPosition[id]); } void deleteASongFromPlaylist(Song * song) @@ -872,15 +877,15 @@ void deleteASongFromPlaylist(Song * song) for (i = 0; i < playlist.length; i++) { if (song == playlist.songs[i]) { - deleteFromPlaylist(stderr, i); + deleteFromPlaylist(STDERR_FILENO, i); } } } -int stopPlaylist(FILE * fp) +int stopPlaylist(int fd) { DEBUG("playlist: stop\n"); - if (playerStop(fp) < 0) + if (playerStop(fd) < 0) return -1; playerCloseAudio(); playlist.queued = -1; @@ -891,10 +896,10 @@ int stopPlaylist(FILE * fp) return 0; } -int playPlaylistOrderNumber(FILE * fp, int orderNum) +int playPlaylistOrderNumber(int fd, int orderNum) { - if (playerStop(fp) < 0) + if (playerStop(fd) < 0) return -1; playlist_state = PLAYLIST_STATE_PLAY; @@ -905,8 +910,8 @@ int playPlaylistOrderNumber(FILE * fp, int orderNum) DEBUG("playlist: play %i:\"%s\"\n", orderNum, getSongUrl(playlist.songs[playlist.order[orderNum]])); - if (playerPlay(fp, (playlist.songs[playlist.order[orderNum]])) < 0) { - stopPlaylist(fp); + if (playerPlay(fd, (playlist.songs[playlist.order[orderNum]])) < 0) { + stopPlaylist(fd); return -1; } else playlist.current++; @@ -916,7 +921,7 @@ int playPlaylistOrderNumber(FILE * fp, int orderNum) return 0; } -int playPlaylist(FILE * fp, int song, int stopOnError) +int playPlaylist(int fd, int song, int stopOnError) { int i = song; @@ -927,7 +932,7 @@ int playPlaylist(FILE * fp, int song, int stopOnError) return 0; if (playlist_state == PLAYLIST_STATE_PLAY) { - return playerSetPause(fp, 0); + return playerSetPause(fd, 0); } if (playlist.current >= 0 && playlist.current < playlist.length) { i = playlist.current; @@ -935,7 +940,7 @@ int playPlaylist(FILE * fp, int song, int stopOnError) i = 0; } } else if (song < 0 || song >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song); return -1; } @@ -957,18 +962,18 @@ int playPlaylist(FILE * fp, int song, int stopOnError) playlist_stopOnError = stopOnError; playlist_errorCount = 0; - return playPlaylistOrderNumber(fp, i); + return playPlaylistOrderNumber(fd, i); } -int playPlaylistById(FILE * fp, int id, int stopOnError) +int playPlaylistById(int fd, int id, int stopOnError) { if (id == -1) { - return playPlaylist(fp, id, stopOnError); + return playPlaylist(fd, id, stopOnError); } checkSongId(id); - return playPlaylist(fp, playlist.idToPosition[id], stopOnError); + return playPlaylist(fd, playlist.idToPosition[id], stopOnError); } void syncCurrentPlayerDecodeMetadata(void) @@ -1010,7 +1015,7 @@ void syncPlayerAndPlaylist(void) syncCurrentPlayerDecodeMetadata(); } -int currentSongInPlaylist(FILE * fp) +int currentSongInPlaylist(int fd) { if (playlist_state != PLAYLIST_STATE_PLAY) return 0; @@ -1020,14 +1025,14 @@ int currentSongInPlaylist(FILE * fp) syncPlaylistWithQueue(0); if (playlist.current >= 0 && playlist.current < playlist.length) { - return playPlaylistOrderNumber(fp, playlist.current); + return playPlaylistOrderNumber(fd, playlist.current); } else - return stopPlaylist(fp);; + return stopPlaylist(fd); return 0; } -int nextSongInPlaylist(FILE * fp) +int nextSongInPlaylist(int fd) { if (playlist_state != PLAYLIST_STATE_PLAY) return 0; @@ -1037,14 +1042,14 @@ int nextSongInPlaylist(FILE * fp) playlist_stopOnError = 0; if (playlist.current < playlist.length - 1) { - return playPlaylistOrderNumber(fp, playlist.current + 1); + return playPlaylistOrderNumber(fd, playlist.current + 1); } else if (playlist.length && playlist.repeat) { if (playlist.random) randomizeOrder(0, playlist.length - 1); - return playPlaylistOrderNumber(fp, 0); + return playPlaylistOrderNumber(fd, 0); } else { incrPlaylistCurrent(); - return stopPlaylist(fp);; + return stopPlaylist(fd); } return 0; @@ -1065,11 +1070,11 @@ void playPlaylistIfPlayerStopped(void) || error == PLAYER_ERROR_AUDIO || error == PLAYER_ERROR_SYSTEM || playlist_errorCount >= playlist.length)) { - stopPlaylist(stderr); + stopPlaylist(STDERR_FILENO); } else if (playlist_noGoToNext) - currentSongInPlaylist(stderr); + currentSongInPlaylist(STDERR_FILENO); else - nextSongInPlaylist(stderr); + nextSongInPlaylist(STDERR_FILENO); } } @@ -1083,10 +1088,10 @@ int getPlaylistRandomStatus(void) return playlist.random; } -int setPlaylistRepeatStatus(FILE * fp, int status) +int setPlaylistRepeatStatus(int fd, int status) { if (status != 0 && status != 1) { - commandError(fp, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status); + commandError(fd, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status); return -1; } @@ -1103,7 +1108,7 @@ int setPlaylistRepeatStatus(FILE * fp, int status) return 0; } -int moveSongInPlaylist(FILE * fp, int from, int to) +int moveSongInPlaylist(int fd, int from, int to) { int i; Song *tmpSong; @@ -1112,13 +1117,13 @@ int moveSongInPlaylist(FILE * fp, int from, int to) int currentSong = -1; if (from < 0 || from >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", from); return -1; } if (to < 0 || to >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", to); return -1; } @@ -1176,11 +1181,11 @@ int moveSongInPlaylist(FILE * fp, int from, int to) return 0; } -int moveSongInPlaylistById(FILE * fp, int id1, int to) +int moveSongInPlaylistById(int fd, int id1, int to) { checkSongId(id1); - return moveSongInPlaylist(fp, playlist.idToPosition[id1], to); + return moveSongInPlaylist(fd, playlist.idToPosition[id1], to); } static void orderPlaylist(void) @@ -1238,12 +1243,12 @@ static void randomizeOrder(int start, int end) } -int setPlaylistRandomStatus(FILE * fp, int status) +int setPlaylistRandomStatus(int fd, int status) { int statusWas = playlist.random; if (status != 0 && status != 1) { - commandError(fp, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status); + commandError(fd, ACK_ERROR_ARG, "\"%i\" is not 0 or 1", status); return -1; } @@ -1268,7 +1273,7 @@ int setPlaylistRandomStatus(FILE * fp, int status) return 0; } -int previousSongInPlaylist(FILE * fp) +int previousSongInPlaylist(int fd) { static time_t lastTime = 0; time_t diff = time(NULL) - lastTime; @@ -1281,22 +1286,22 @@ int previousSongInPlaylist(FILE * fp) syncPlaylistWithQueue(0); if (diff && getPlayerElapsedTime() > PLAYLIST_PREV_UNLESS_ELAPSED) { - return playPlaylistOrderNumber(fp, playlist.current); + return playPlaylistOrderNumber(fd, playlist.current); } else { if (playlist.current > 0) { - return playPlaylistOrderNumber(fp, + return playPlaylistOrderNumber(fd, playlist.current - 1); } else if (playlist.repeat) { - return playPlaylistOrderNumber(fp, playlist.length - 1); + return playPlaylistOrderNumber(fd, playlist.length - 1); } else { - return playPlaylistOrderNumber(fp, playlist.current); + return playPlaylistOrderNumber(fd, playlist.current); } } return 0; } -int shufflePlaylist(FILE * fp) +int shufflePlaylist(int fd) { int i; int ri; @@ -1331,7 +1336,7 @@ int shufflePlaylist(FILE * fp) return 0; } -int deletePlaylist(FILE * fp, char *utf8file) +int deletePlaylist(int fd, char *utf8file) { char *file = utf8ToFsCharset(utf8file); char *rfile = malloc(strlen(file) + strlen(".") + @@ -1348,13 +1353,13 @@ int deletePlaylist(FILE * fp, char *utf8file) free(rfile); else { free(rfile); - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "playlist \"%s\" not found", utf8file); return -1; } if (unlink(actualFile) < 0) { - commandError(fp, ACK_ERROR_SYSTEM, + commandError(fd, ACK_ERROR_SYSTEM, "problems deleting file", NULL); return -1; } @@ -1362,7 +1367,7 @@ int deletePlaylist(FILE * fp, char *utf8file) return 0; } -int savePlaylist(FILE * fp, char *utf8file) +int savePlaylist(int fd, char *utf8file) { FILE *fileP; int i; @@ -1373,7 +1378,7 @@ int savePlaylist(FILE * fp, char *utf8file) char *url; if (strstr(utf8file, "/")) { - commandError(fp, ACK_ERROR_ARG, + commandError(fd, ACK_ERROR_ARG, "cannot save \"%s\", saving playlists to " "subdirectories is not supported", utf8file); return -1; @@ -1395,14 +1400,14 @@ int savePlaylist(FILE * fp, char *utf8file) free(rfile); if (0 == stat(actualFile, &st)) { - commandError(fp, ACK_ERROR_EXIST, "a file or directory already " + commandError(fd, ACK_ERROR_EXIST, "a file or directory already " "exists with the name \"%s\"", utf8file); return -1; } while (!(fileP = fopen(actualFile, "w")) && errno == EINTR) ; if (fileP == NULL) { - commandError(fp, ACK_ERROR_SYSTEM, "problems opening file", + commandError(fd, ACK_ERROR_SYSTEM, "problems opening file", NULL); return -1; } @@ -1445,12 +1450,12 @@ int getPlaylistLength(void) return playlist.length; } -int seekSongInPlaylist(FILE * fp, int song, float time) +int seekSongInPlaylist(int fd, int song, float time) { int i = song; if (song < 0 || song >= playlist.length) { - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "song doesn't exist: \"%i\"", song); return -1; } @@ -1468,22 +1473,22 @@ int seekSongInPlaylist(FILE * fp, int song, float time) clearPlayerQueue(); unlockPlaylistInteraction(); } - } else if (playPlaylistOrderNumber(fp, i) < 0) + } else if (playPlaylistOrderNumber(fd, i) < 0) return -1; if (playlist.current != i) { - if (playPlaylistOrderNumber(fp, i) < 0) + if (playPlaylistOrderNumber(fd, i) < 0) return -1; } - return playerSeek(fp, playlist.songs[playlist.order[i]], time); + return playerSeek(fd, playlist.songs[playlist.order[i]], time); } -int seekSongInPlaylistById(FILE * fp, int id, float time) +int seekSongInPlaylistById(int fd, int id, float time) { checkSongId(id); - return seekSongInPlaylist(fp, playlist.idToPosition[id], time); + return seekSongInPlaylist(fd, playlist.idToPosition[id], time); } int getPlaylistSongId(int song) @@ -1491,8 +1496,8 @@ int getPlaylistSongId(int song) return playlist.positionToId[song]; } -static int PlaylistIterFunc(FILE * fp, char *utf8file, - void (*IterFunc) (FILE * fp, char *utf8_file, +static int PlaylistIterFunc(int fd, char *utf8file, + void (*IterFunc) (int fd, char *utf8_file, char **errored_File)) { FILE *fileP; @@ -1518,14 +1523,14 @@ static int PlaylistIterFunc(FILE * fp, char *utf8file, free(rfile); else { free(rfile); - commandError(fp, ACK_ERROR_NO_EXIST, + commandError(fd, ACK_ERROR_NO_EXIST, "playlist \"%s\" not found", utf8file); return -1; } while (!(fileP = fopen(actualFile, "r")) && errno == EINTR) ; if (fileP == NULL) { - commandError(fp, ACK_ERROR_SYSTEM, + commandError(fd, ACK_ERROR_SYSTEM, "problems opening file \"%s\"", utf8file); return -1; } @@ -1547,7 +1552,7 @@ static int PlaylistIterFunc(FILE * fp, char *utf8file, strncat(s, "/", MAXPATHLEN - parentlen); strncat(s, temp, MAXPATHLEN - parentlen - 1); if (strlen(s) >= MAXPATHLEN) { - commandError(fp, + commandError(fd, ACK_ERROR_PLAYLIST_LOAD, "\"%s\" too long", temp); free(temp); @@ -1568,12 +1573,12 @@ static int PlaylistIterFunc(FILE * fp, char *utf8file, * for our current IterFunction set * but just in case, we copy to s */ strcpy(s, temp); - IterFunc(fp, s, &erroredFile); + IterFunc(fd, s, &erroredFile); } free(temp); } else if (slength == MAXPATHLEN) { s[slength] = '\0'; - commandError(fp, ACK_ERROR_PLAYLIST_LOAD, + commandError(fd, ACK_ERROR_PLAYLIST_LOAD, "line in \"%s\" is too long", utf8file); ERROR("line \"%s\" in playlist \"%s\" is too long\n", s, utf8file); @@ -1588,7 +1593,7 @@ static int PlaylistIterFunc(FILE * fp, char *utf8file, while (fclose(fileP) && errno == EINTR) ; if (erroredFile) { - commandError(fp, ACK_ERROR_PLAYLIST_LOAD, + commandError(fd, ACK_ERROR_PLAYLIST_LOAD, "can't add file \"%s\"", erroredFile); free(erroredFile); return -1; @@ -1597,25 +1602,25 @@ static int PlaylistIterFunc(FILE * fp, char *utf8file, return 0; } -static void PlaylistInfoPrintInfo(FILE * fp, char *utf8file, char **erroredfile) +static void PlaylistInfoPrintInfo(int fd, char *utf8file, char **erroredfile) { Song *song = getSongFromDB(utf8file); if (song) { - printSongInfo(fp, song); + printSongInfo(fd, song); } else { - myfprintf(fp, "file: %s\n", utf8file); + fdprintf(fd, "file: %s\n", utf8file); } } -static void PlaylistInfoPrint(FILE * fp, char *utf8file, char **erroredfile) +static void PlaylistInfoPrint(int fd, char *utf8file, char **erroredfile) { - myfprintf(fp, "file: %s\n", utf8file); + fdprintf(fd, "file: %s\n", utf8file); } -static void PlaylistLoadIterFunc(FILE * fp, char *temp, char **erroredFile) +static void PlaylistLoadIterFunc(int fd, char *temp, char **erroredFile) { if (!getSongFromDB(temp) && !isRemoteUrl(temp)) { - } else if ((addToPlaylist(stderr, temp, 0)) < 0) { + } else if ((addToPlaylist(STDERR_FILENO, temp, 0)) < 0) { /* for windows compatibilit, convert slashes */ char *temp2 = strdup(temp); char *p = temp2; @@ -1624,7 +1629,7 @@ static void PlaylistLoadIterFunc(FILE * fp, char *temp, char **erroredFile) *p = '/'; p++; } - if ((addToPlaylist(stderr, temp2, 0)) < 0) { + if ((addToPlaylist(STDERR_FILENO, temp2, 0)) < 0) { if (!*erroredFile) { *erroredFile = strdup(temp); } @@ -1633,15 +1638,15 @@ static void PlaylistLoadIterFunc(FILE * fp, char *temp, char **erroredFile) } } -int PlaylistInfo(FILE * fp, char *utf8file, int detail) +int PlaylistInfo(int fd, char *utf8file, int detail) { if (detail) { - return PlaylistIterFunc(fp, utf8file, PlaylistInfoPrintInfo); + return PlaylistIterFunc(fd, utf8file, PlaylistInfoPrintInfo); } - return PlaylistIterFunc(fp, utf8file, PlaylistInfoPrint); + return PlaylistIterFunc(fd, utf8file, PlaylistInfoPrint); } -int loadPlaylist(FILE * fp, char *utf8file) +int loadPlaylist(int fd, char *utf8file) { - return PlaylistIterFunc(fp, utf8file, PlaylistLoadIterFunc); + return PlaylistIterFunc(fd, utf8file, PlaylistLoadIterFunc); } diff --git a/src/playlist.h b/src/playlist.h index faab10021..25ed45dfb 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -38,61 +38,61 @@ void readPlaylistState(); void savePlaylistState(); -int clearPlaylist(FILE * fp); +int clearPlaylist(int fd); -int addToPlaylist(FILE * fp, char *file, int printId); +int addToPlaylist(int fd, char *file, int printId); -int addSongToPlaylist(FILE * fp, Song * song, int printId); +int addSongToPlaylist(int fd, Song * song, int printId); -int showPlaylist(FILE * fp); +int showPlaylist(int fd); -int deleteFromPlaylist(FILE * fp, int song); +int deleteFromPlaylist(int fd, int song); -int deleteFromPlaylistById(FILE * fp, int song); +int deleteFromPlaylistById(int fd, int song); -int playlistInfo(FILE * fp, int song); +int playlistInfo(int fd, int song); -int playlistId(FILE * fp, int song); +int playlistId(int fd, int song); -int stopPlaylist(FILE * fp); +int stopPlaylist(int fd); -int playPlaylist(FILE * fp, int song, int stopOnError); +int playPlaylist(int fd, int song, int stopOnError); -int playPlaylistById(FILE * fp, int song, int stopOnError); +int playPlaylistById(int fd, int song, int stopOnError); -int nextSongInPlaylist(FILE * fp); +int nextSongInPlaylist(int fd); void syncPlayerAndPlaylist(); -int previousSongInPlaylist(FILE * fp); +int previousSongInPlaylist(int fd); -int shufflePlaylist(FILE * fp); +int shufflePlaylist(int fd); -int savePlaylist(FILE * fp, char *utf8file); +int savePlaylist(int fd, char *utf8file); -int deletePlaylist(FILE * fp, char *utf8file); +int deletePlaylist(int fd, char *utf8file); -int deletePlaylistById(FILE * fp, char *utf8file); +int deletePlaylistById(int fd, char *utf8file); void deleteASongFromPlaylist(Song * song); -int moveSongInPlaylist(FILE * fp, int from, int to); +int moveSongInPlaylist(int fd, int from, int to); -int moveSongInPlaylistById(FILE * fp, int id, int to); +int moveSongInPlaylistById(int fd, int id, int to); -int swapSongsInPlaylist(FILE * fp, int song1, int song2); +int swapSongsInPlaylist(int fd, int song1, int song2); -int swapSongsInPlaylistById(FILE * fp, int id1, int id2); +int swapSongsInPlaylistById(int fd, int id1, int id2); -int loadPlaylist(FILE * fp, char *utf8file); +int loadPlaylist(int fd, char *utf8file); int getPlaylistRepeatStatus(); -int setPlaylistRepeatStatus(FILE * fp, int status); +int setPlaylistRepeatStatus(int fd, int status); int getPlaylistRandomStatus(); -int setPlaylistRandomStatus(FILE * fp, int status); +int setPlaylistRandomStatus(int fd, int status); int getPlaylistCurrentSong(); @@ -104,17 +104,17 @@ unsigned long getPlaylistVersion(); void playPlaylistIfPlayerStopped(); -int seekSongInPlaylist(FILE * fp, int song, float time); +int seekSongInPlaylist(int fd, int song, float time); -int seekSongInPlaylistById(FILE * fp, int id, float time); +int seekSongInPlaylistById(int fd, int id, float time); void playlistVersionChange(); -int playlistChanges(FILE * fp, mpd_uint32 version); +int playlistChanges(int fd, mpd_uint32 version); -int playlistChangesPosId(FILE * fp, mpd_uint32 version); +int playlistChangesPosId(int fd, mpd_uint32 version); -int PlaylistInfo(FILE * fp, char *utf8file, int detail); +int PlaylistInfo(int fd, char *utf8file, int detail); char *getStateFile(); diff --git a/src/sllist.c b/src/sllist.c new file mode 100644 index 000000000..1c11c973d --- /dev/null +++ b/src/sllist.c @@ -0,0 +1,71 @@ +/* the Music Player Daemon (MPD) + * (c)2003-2006 by Warren Dukes (warren.dukes@gmail.com) + * This project's homepage is: http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* a very simple singly-linked-list structure for queues/buffers */ + +#include "sllist.h" +#include "utils.h" + +static void init_strnode(struct strnode *x, char *s) +{ + x->data = s; + x->next = NULL; +} + +struct strnode *new_strnode(char *s) +{ + struct strnode *x = malloc(sizeof(struct strnode)); + init_strnode(x, s); + return x; +} + +struct strnode *new_strnode_dup(char *s, const size_t size) +{ + struct strnode *x = malloc(sizeof(struct strnode) + size); + x->next = NULL; + x->data = ((void *)x + sizeof(struct strnode)); + memcpy((void *)x->data, (void*)s, size); + return x; +} + +struct sllnode *new_sllnode(void *s, const size_t size) +{ + struct sllnode *x = malloc(sizeof(struct sllnode) + size); + x->next = NULL; + x->size = size; + x->data = ((void *)x + sizeof(struct sllnode)); + memcpy(x->data, (void *)s, size); + return x; +} + +struct strnode *dup_strlist(struct strnode *old) +{ + struct strnode *tmp, *new, *cur; + + tmp = old; + cur = new = new_strnode_dup(tmp->data, strlen(tmp->data) + 1); + tmp = tmp->next; + while (tmp) { + cur->next = new_strnode_dup(tmp->data, strlen(tmp->data) + 1); + cur = cur->next; + tmp = tmp->next; + } + return new; +} + + diff --git a/src/sllist.h b/src/sllist.h new file mode 100644 index 000000000..3ac1d1846 --- /dev/null +++ b/src/sllist.h @@ -0,0 +1,34 @@ +/* a very simple singly-linked-list structure for queues/buffers */ + +#ifndef SLLIST_H +#define SLLIST_H + +#include "utils.h" + +/* just free the entire structure if it's free-able, the 'data' member + * should _NEVER_ be explicitly freed + * + * there's no free command, iterate through them yourself and just + * call free() on it iff you malloc'd them */ + +struct strnode { + struct strnode *next; + char *data; +}; + +struct sllnode { + struct sllnode *next; + void *data; + size_t size; +}; + +struct strnode *new_strnode(char *s); + +struct strnode *new_strnode_dup(char *s, const size_t size); + +struct strnode *dup_strlist(struct strnode *old); + +struct sllnode *new_sllnode(void *s, const size_t size); + + +#endif /* SLLIST_H */ diff --git a/src/song.c b/src/song.c index b982b1007..a601d5f67 100644 --- a/src/song.c +++ b/src/song.c @@ -134,32 +134,32 @@ void freeSongList(SongList * list) freeList(list); } -void printSongUrl(FILE * fp, Song * song) +void printSongUrl(int fd, Song * song) { if (song->parentDir && song->parentDir->path) { - myfprintf(fp, "%s%s/%s\n", SONG_FILE, + fdprintf(fd, "%s%s/%s\n", SONG_FILE, getDirectoryPath(song->parentDir), song->url); } else { - myfprintf(fp, "%s%s\n", SONG_FILE, song->url); + fdprintf(fd, "%s%s\n", SONG_FILE, song->url); } } -int printSongInfo(FILE * fp, Song * song) +int printSongInfo(int fd, Song * song) { - printSongUrl(fp, song); + printSongUrl(fd, song); if (song->tag) - printMpdTag(fp, song->tag); + printMpdTag(fd, song->tag); return 0; } -int printSongInfoFromList(FILE * fp, SongList * list) +int printSongInfoFromList(int fd, SongList * list) { ListNode *tempNode = list->firstNode; while (tempNode != NULL) { - printSongInfo(fp, (Song *) tempNode->data); + printSongInfo(fd, (Song *) tempNode->data); tempNode = tempNode->nextNode; } @@ -174,7 +174,7 @@ void writeSongInfoFromList(FILE * fp, SongList * list) while (tempNode != NULL) { myfprintf(fp, "%s%s\n", SONG_KEY, tempNode->key); - printSongInfo(fp, (Song *) tempNode->data); + printSongInfo(fileno(fp), (Song *) tempNode->data); myfprintf(fp, "%s%li\n", SONG_MTIME, (long)((Song *) tempNode->data)->mtime); tempNode = tempNode->nextNode; diff --git a/src/song.h b/src/song.h index 104ad1686..d4fde5470 100644 --- a/src/song.h +++ b/src/song.h @@ -58,9 +58,9 @@ void freeSongList(SongList * list); Song *addSongToList(SongList * list, char *url, char *utf8path, int songType, struct _Directory *parentDir); -int printSongInfo(FILE * fp, Song * song); +int printSongInfo(int fd, Song * song); -int printSongInfoFromList(FILE * fp, SongList * list); +int printSongInfoFromList(int fd, SongList * list); void writeSongInfoFromList(FILE * fp, SongList * list); @@ -69,7 +69,7 @@ void readSongInfoIntoList(FILE * fp, SongList * list, int updateSongInfo(Song * song); -void printSongUrl(FILE * fp, Song * song); +void printSongUrl(int fd, Song * song); char *getSongUrl(Song * song); diff --git a/src/stats.c b/src/stats.c index c159fc4c1..32a7804c1 100644 --- a/src/stats.c +++ b/src/stats.c @@ -34,15 +34,15 @@ void initStats(void) stats.numberOfSongs = 0; } -int printStats(FILE * fp) +int printStats(int fd) { - myfprintf(fp, "artists: %li\n", getNumberOfTagItems(TAG_ITEM_ARTIST)); - myfprintf(fp, "albums: %li\n", getNumberOfTagItems(TAG_ITEM_ALBUM)); - myfprintf(fp, "songs: %i\n", stats.numberOfSongs); - myfprintf(fp, "uptime: %li\n", time(NULL) - stats.daemonStart); - myfprintf(fp, "playtime: %li\n", + fdprintf(fd, "artists: %li\n", getNumberOfTagItems(TAG_ITEM_ARTIST)); + fdprintf(fd, "albums: %li\n", getNumberOfTagItems(TAG_ITEM_ALBUM)); + fdprintf(fd, "songs: %i\n", stats.numberOfSongs); + fdprintf(fd, "uptime: %li\n", time(NULL) - stats.daemonStart); + fdprintf(fd, "playtime: %li\n", (long)(getPlayerTotalPlayTime() + 0.5)); - myfprintf(fp, "db_playtime: %li\n", stats.dbPlayTime); - myfprintf(fp, "db_update: %li\n", getDbModTime()); + fdprintf(fd, "db_playtime: %li\n", stats.dbPlayTime); + fdprintf(fd, "db_update: %li\n", getDbModTime()); return 0; } diff --git a/src/stats.h b/src/stats.h index 81fd9b3ae..4302732ce 100644 --- a/src/stats.h +++ b/src/stats.h @@ -35,6 +35,6 @@ extern Stats stats; void initStats(); -int printStats(FILE * fp); +int printStats(int fd); #endif @@ -121,15 +121,15 @@ void initTagConfig(void) free(temp); } -void printMpdTag(FILE * fp, MpdTag * tag) +void printMpdTag(int fd, MpdTag * tag) { int i; if (tag->time >= 0) - myfprintf(fp, "Time: %i\n", tag->time); + fdprintf(fd, "Time: %i\n", tag->time); for (i = 0; i < tag->numOfItems; i++) { - myfprintf(fp, "%s: %s\n", mpdTagItemKeys[tag->items[i].type], + fdprintf(fd, "%s: %s\n", mpdTagItemKeys[tag->items[i].type], tag->items[i].value); } } @@ -78,7 +78,7 @@ void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char *value, int len); #define addItemToMpdTag(tag, itemType, value) \ addItemToMpdTagWithLen(tag, itemType, value, strlen(value)) -void printMpdTag(FILE * fp, MpdTag * tag); +void printMpdTag(int fd, MpdTag * tag); MpdTag *mpdTagDup(MpdTag * tag); diff --git a/src/tagTracker.c b/src/tagTracker.c index 6d2843746..b4de6129d 100644 --- a/src/tagTracker.c +++ b/src/tagTracker.c @@ -147,7 +147,7 @@ void visitInTagTracker(int type, char *str) ((TagTrackerItem *) item)->visited = 1; } -void printVisitedInTagTracker(FILE * fp, int type) +void printVisitedInTagTracker(int fd, int type) { ListNode *node; TagTrackerItem *item; @@ -160,8 +160,8 @@ void printVisitedInTagTracker(FILE * fp, int type) while (node) { item = node->data; if (item->visited) { - myfprintf(fp, "%s: %s\n", mpdTagItemKeys[type], - node->key); + fdprintf(fd, "%s: %s\n", mpdTagItemKeys[type], + node->key); } node = node->nextNode; } diff --git a/src/tagTracker.h b/src/tagTracker.h index b3f9a97c6..260784d09 100644 --- a/src/tagTracker.h +++ b/src/tagTracker.h @@ -33,6 +33,6 @@ void resetVisitedFlagsInTagTracker(int type); void visitInTagTracker(int type, char *str); -void printVisitedInTagTracker(FILE * fp, int type); +void printVisitedInTagTracker(int fd, int type); #endif diff --git a/src/utils.h b/src/utils.h index 1788d7141..bc16905ea 100644 --- a/src/utils.h +++ b/src/utils.h @@ -21,7 +21,13 @@ #include "../config.h" +#include <unistd.h> +#include <stdlib.h> #include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> char *myFgets(char *buffer, int bufferSize, FILE * fp); @@ -37,4 +43,39 @@ char *appendToString(char *dest, const char *src); unsigned long readLEuint32(const unsigned char *p); +/* trivial functions, keep them inlined */ +static inline int xopen(const char *path, int flags, mode_t mode) +{ + int fd; + while(0>(fd = open(path,flags,mode)) && errno == EINTR); + return fd; +} + +static inline void xclose(int fd) +{ + while (close(fd) && errno == EINTR); +} + +static inline ssize_t xread(int fd, void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = read(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +static inline ssize_t xwrite(int fd, const void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = write(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + #endif diff --git a/src/volume.c b/src/volume.c index 32b56bd66..adff103ad 100644 --- a/src/volume.c +++ b/src/volume.c @@ -169,7 +169,7 @@ static int getOssVolumeLevel(void) return left; } -static int changeOssVolumeLevel(FILE * fp, int change, int rel) +static int changeOssVolumeLevel(int fd, int change, int rel) { int current; int new; @@ -177,7 +177,7 @@ static int changeOssVolumeLevel(FILE * fp, int change, int rel) if (rel) { if ((current = getOssVolumeLevel()) < 0) { - commandError(fp, ACK_ERROR_SYSTEM, + commandError(fd, ACK_ERROR_SYSTEM, "problem getting current volume", NULL); return -1; } @@ -198,7 +198,7 @@ static int changeOssVolumeLevel(FILE * fp, int change, int rel) if (ioctl(volume_ossFd, MIXER_WRITE(volume_ossControl), &level) < 0) { closeOssMixer(); - commandError(fp, ACK_ERROR_SYSTEM, "problems setting volume", + commandError(fd, ACK_ERROR_SYSTEM, "problems setting volume", NULL); return -1; } @@ -328,7 +328,7 @@ static int getAlsaVolumeLevel(void) return ret; } -static int changeAlsaVolumeLevel(FILE * fp, int change, int rel) +static int changeAlsaVolumeLevel(int fd, int change, int rel) { float vol; long level; @@ -361,7 +361,7 @@ static int changeAlsaVolumeLevel(FILE * fp, int change, int rel) if ((err = snd_mixer_selem_set_playback_volume_all(volume_alsaElem, level)) < 0) { - commandError(fp, ACK_ERROR_SYSTEM, "problems setting volume", + commandError(fd, ACK_ERROR_SYSTEM, "problems setting volume", NULL); WARNING("problems setting alsa volume: %s\n", snd_strerror(err)); @@ -471,7 +471,7 @@ int getVolumeLevel(void) } } -static int changeSoftwareVolume(FILE * fp, int change, int rel) +static int changeSoftwareVolume(int fd, int change, int rel) { int new = change; @@ -499,19 +499,19 @@ static int changeSoftwareVolume(FILE * fp, int change, int rel) return 0; } -int changeVolumeLevel(FILE * fp, int change, int rel) +int changeVolumeLevel(int fd, int change, int rel) { switch (volume_mixerType) { #ifdef HAVE_ALSA case VOLUME_MIXER_TYPE_ALSA: - return changeAlsaVolumeLevel(fp, change, rel); + return changeAlsaVolumeLevel(fd, change, rel); #endif #ifdef HAVE_OSS case VOLUME_MIXER_TYPE_OSS: - return changeOssVolumeLevel(fp, change, rel); + return changeOssVolumeLevel(fd, change, rel); #endif case VOLUME_MIXER_TYPE_SOFTWARE: - return changeSoftwareVolume(fp, change, rel); + return changeSoftwareVolume(fd, change, rel); default: return 0; break; diff --git a/src/volume.h b/src/volume.h index 0c0307da5..92fd868be 100644 --- a/src/volume.h +++ b/src/volume.h @@ -35,6 +35,6 @@ void finishVolume(); int getVolumeLevel(); -int changeVolumeLevel(FILE * fp, int change, int rel); +int changeVolumeLevel(int fd, int change, int rel); #endif |