diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/audio.c | 48 | ||||
-rw-r--r-- | src/audio.h | 4 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/playlist.c | 282 | ||||
-rw-r--r-- | src/playlist.h | 6 | ||||
-rw-r--r-- | src/state_file.c | 112 | ||||
-rw-r--r-- | src/state_file.h | 30 | ||||
-rw-r--r-- | src/utils.h | 2 |
9 files changed, 261 insertions, 232 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 3c5d46990..1dfcd476e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,7 @@ mpd_headers = \ sig_handlers.h \ sllist.h \ song.h \ + state_file.h \ stats.h \ tag.h \ tagTracker.h \ @@ -111,6 +112,7 @@ mpd_SOURCES = \ signal_check.c \ sllist.c \ song.c \ + state_file.c \ stats.c \ tag.c \ tagTracker.c \ diff --git a/src/audio.c b/src/audio.c index 8ecae5ec3..b4f0dadc3 100644 --- a/src/audio.c +++ b/src/audio.c @@ -25,6 +25,7 @@ #include "playerData.h" #include "utils.h" #include "playlist.h" +#include "state_file.h" #include <stdlib.h> #include <string.h> @@ -462,32 +463,19 @@ void printAudioDevices(int fd) } } -void saveAudioDevicesState(void) +void saveAudioDevicesState(FILE *fp) { - char *stateFile; - FILE *fp; int i; - if (!(stateFile = getStateFile())) - return; - - while (!(fp = fopen(stateFile, "a")) && errno == EINTR) ; - if (!fp) { - ERROR("problems opening state file \"%s\" for " - "writing: %s\n", stateFile, strerror(errno)); - return; - } - assert(audioOutputArraySize != 0); for (i = 0; i < audioOutputArraySize; i++) { fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n", - (int)pdAudioDevicesEnabled[i], - audioOutputArray[i]->name); + (int)pdAudioDevicesEnabled[i], + audioOutputArray[i]->name); } - while (fclose(fp) && errno == EINTR) ; } -static void parse_audio_device_state(FILE * fp) +void readAudioDevicesState(FILE *fp) { char buffer[AUDIO_BUFFER_SIZE]; int i; @@ -521,29 +509,3 @@ static void parse_audio_device_state(FILE * fp) } } -void readAudioDevicesState(void) -{ - char *stateFile; - FILE *fp; - struct stat st; - - if (!(stateFile = getStateFile())) - return; - if (stat(stateFile, &st) < 0) { - DEBUG("failed to stat state file\n"); - return; - } - if (!S_ISREG(st.st_mode)) { - ERROR("state file \"%s\" is not a regular file\n", stateFile); - exit(EXIT_FAILURE); - } - - fp = fopen(stateFile, "r"); - if (!fp) { - ERROR("problems opening state file \"%s\" for " - "reading: %s\n", stateFile, strerror(errno)); - exit(EXIT_FAILURE); - } - parse_audio_device_state(fp); - fclose(fp); -} diff --git a/src/audio.h b/src/audio.h index 29309b9ce..70cc551fd 100644 --- a/src/audio.h +++ b/src/audio.h @@ -75,9 +75,9 @@ int disableAudioDevice(int fd, int device); void printAudioDevices(int fd); -void readAudioDevicesState(); +void readAudioDevicesState(FILE *fp); -void saveAudioDevicesState(); +void saveAudioDevicesState(FILE *fp); void loadAudioDrivers(); #endif diff --git a/src/main.c b/src/main.c index 67ae0f76b..3ba2afeb4 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ #include "inputPlugin.h" #include "audioOutput.h" #include "inputStream.h" +#include "state_file.h" #include "tag.h" #include "tagTracker.h" #include "dbUtils.h" @@ -346,7 +347,6 @@ static void startMainProcess(void) if (pid > 0) { initInputStream(); initReplayGainState(); - readAudioDevicesState(); /* free stuff we don't need */ freeAllListenSockets(); @@ -581,7 +581,7 @@ int main(int argc, char *argv[]) my_usleep(1); openVolumeDevice(); - readPlaylistState(); + read_state_file(); while (COMMAND_RETURN_KILL != doIOForInterfaces()) { if (COMMAND_RETURN_KILL == handlePendingSignals()) @@ -591,8 +591,7 @@ int main(int argc, char *argv[]) readDirectoryDBIfUpdateIsFinished(); } - savePlaylistState(); - saveAudioDevicesState(); + write_state_file(); freeAllInterfaces(); closeAllListenSockets(); diff --git a/src/playlist.c b/src/playlist.c index 64350d471..359e3ac24 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -27,6 +27,7 @@ #include "path.h" #include "utils.h" #include "sig_handlers.h" +#include "state_file.h" #include <string.h> #include <stdlib.h> @@ -92,16 +93,6 @@ static void swapOrder(int a, int b); static int playPlaylistOrderNumber(int fd, int orderNum); static void randomizeOrder(int start, int end); -char *getStateFile(void) -{ - ConfigParam *param = parseConfigFilePath(CONF_STATE_FILE, 0); - - if (!param) - return NULL; - - return param->value; -} - static void incrPlaylistVersion(void) { static unsigned long max = ((mpd_uint32) 1 << 31) - 1; @@ -256,208 +247,141 @@ int showPlaylist(int fd) return 0; } -void savePlaylistState(void) +void savePlaylistState(FILE *fp) { - char *stateFile = getStateFile(); - - if (stateFile) { - FILE *fp; - - while (!(fp = fopen(stateFile, "w")) && errno == EINTR) ; - if (!fp) { - ERROR("problems opening state file \"%s\" for " - "writing: %s\n", stateFile, strerror(errno)); - return; - } - - fprintf(fp, "%s", PLAYLIST_STATE_FILE_STATE); - switch (playlist_state) { - case PLAYLIST_STATE_PLAY: - switch (getPlayerState()) { - case PLAYER_STATE_PAUSE: - fprintf(fp, "%s\n", - PLAYLIST_STATE_FILE_STATE_PAUSE); - break; - default: - fprintf(fp, "%s\n", - PLAYLIST_STATE_FILE_STATE_PLAY); - } - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CURRENT, - playlist.order[playlist.current]); - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_TIME, - getPlayerElapsedTime()); + fprintf(fp, "%s", PLAYLIST_STATE_FILE_STATE); + switch (playlist_state) { + case PLAYLIST_STATE_PLAY: + switch (getPlayerState()) { + case PLAYER_STATE_PAUSE: + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PAUSE); break; default: - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_STOP); - break; + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_PLAY); } - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_RANDOM, - playlist.random); - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT, - playlist.repeat); - fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE, - (int)(getPlayerCrossFade())); - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); - fflush(fp); - showPlaylist(fileno(fp)); - fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END); - - while (fclose(fp) && errno == EINTR) ; + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CURRENT, + playlist.order[playlist.current]); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_TIME, + getPlayerElapsedTime()); + break; + default: + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_STATE_STOP); + break; } + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_RANDOM, playlist.random); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_REPEAT, playlist.repeat); + fprintf(fp, "%s%i\n", PLAYLIST_STATE_FILE_CROSSFADE, + (int)(getPlayerCrossFade())); + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_BEGIN); + fflush(fp); + showPlaylist(fileno(fp)); + fprintf(fp, "%s\n", PLAYLIST_STATE_FILE_PLAYLIST_END); } -void loadPlaylistFromStateFile(FILE *fp, char *buffer, int state, int current, - int time) +static void loadPlaylistFromStateFile(FILE *fp, char *buffer, + int state, int current, int time) { char *temp; int song; - char *stateFile = getStateFile(); - if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { - ERROR("error parsing state file \"%s\"\n", stateFile); - exit(EXIT_FAILURE); - } + if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) + state_file_fatal(); while (strcmp(buffer, PLAYLIST_STATE_FILE_PLAYLIST_END)) { song = atoi(strtok(buffer, ":")); - if (!(temp = strtok(NULL, ""))) { - ERROR("error parsing state file \"%s\"\n", stateFile); - exit(EXIT_FAILURE); - } + if (!(temp = strtok(NULL, ""))) + state_file_fatal(); if (!addToPlaylist(STDERR_FILENO, temp, 0) && current == song) { if (state != PLAYER_STATE_STOP) { playPlaylist(STDERR_FILENO, - playlist.length - 1, 0); + playlist.length - 1, 0); } if (state == PLAYER_STATE_PAUSE) { playerPause(STDERR_FILENO); } if (state != PLAYER_STATE_STOP) { seekSongInPlaylist(STDERR_FILENO, - playlist.length - 1, - time); + playlist.length - 1, time); } } - if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { - ERROR("error parsing state file \"%s\"\n", stateFile); - exit(EXIT_FAILURE); - } + if (!myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) + state_file_fatal(); } } -void readPlaylistState(void) +void readPlaylistState(FILE *fp) { - char *stateFile = getStateFile(); - - if (stateFile) { - FILE *fp; - struct stat st; - int current = -1; - int time = 0; - int state = PLAYER_STATE_STOP; - char buffer[PLAYLIST_BUFFER_SIZE]; - - if (stat(stateFile, &st) < 0) { - DEBUG("failed to stat state file\n"); - return; - } - if (!S_ISREG(st.st_mode)) { - ERROR("state file \"%s\" is not a regular " - "file\n", stateFile); - exit(EXIT_FAILURE); - } + int current = -1; + int time = 0; + int state = PLAYER_STATE_STOP; + char buffer[PLAYLIST_BUFFER_SIZE]; - fp = fopen(stateFile, "r"); - if (!fp) { - ERROR("problems opening state file \"%s\" for " - "reading: %s\n", stateFile, strerror(errno)); - exit(EXIT_FAILURE); - } - - while (myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { - if (strncmp(buffer, PLAYLIST_STATE_FILE_STATE, - strlen(PLAYLIST_STATE_FILE_STATE)) == 0) { - if (strcmp(&(buffer - [strlen - (PLAYLIST_STATE_FILE_STATE)]), - PLAYLIST_STATE_FILE_STATE_PLAY) == - 0) { - state = PLAYER_STATE_PLAY; - } else if (strcmp(&(buffer - [strlen - (PLAYLIST_STATE_FILE_STATE)]), - PLAYLIST_STATE_FILE_STATE_PAUSE) - == 0) { - state = PLAYER_STATE_PAUSE; - } - } else if (strncmp(buffer, PLAYLIST_STATE_FILE_TIME, - strlen(PLAYLIST_STATE_FILE_TIME)) == - 0) { - time = - atoi(& - (buffer - [strlen(PLAYLIST_STATE_FILE_TIME)])); - } else - if (strncmp - (buffer, PLAYLIST_STATE_FILE_REPEAT, - strlen(PLAYLIST_STATE_FILE_REPEAT)) == 0) { - if (strcmp - (& - (buffer - [strlen(PLAYLIST_STATE_FILE_REPEAT)]), - "1") == 0) { - setPlaylistRepeatStatus(STDERR_FILENO, - 1); - } else - setPlaylistRepeatStatus(STDERR_FILENO, - 0); + while (myFgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) { + if (strncmp(buffer, PLAYLIST_STATE_FILE_STATE, + strlen(PLAYLIST_STATE_FILE_STATE)) == 0) { + if (strcmp(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]), + PLAYLIST_STATE_FILE_STATE_PLAY) == 0) { + state = PLAYER_STATE_PLAY; } else - if (strncmp - (buffer, PLAYLIST_STATE_FILE_CROSSFADE, - strlen(PLAYLIST_STATE_FILE_CROSSFADE)) == 0) { - setPlayerCrossFade(atoi - (& - (buffer - [strlen - (PLAYLIST_STATE_FILE_CROSSFADE)]))); + if (strcmp + (&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]), + PLAYLIST_STATE_FILE_STATE_PAUSE) + == 0) { + state = PLAYER_STATE_PAUSE; + } + } else if (strncmp(buffer, PLAYLIST_STATE_FILE_TIME, + strlen(PLAYLIST_STATE_FILE_TIME)) == 0) { + time = + atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)])); + } else + if (strncmp + (buffer, PLAYLIST_STATE_FILE_REPEAT, + strlen(PLAYLIST_STATE_FILE_REPEAT)) == 0) { + if (strcmp + (&(buffer[strlen(PLAYLIST_STATE_FILE_REPEAT)]), + "1") == 0) { + setPlaylistRepeatStatus(STDERR_FILENO, 1); } else - if (strncmp - (buffer, PLAYLIST_STATE_FILE_RANDOM, - strlen(PLAYLIST_STATE_FILE_RANDOM)) == 0) { - if (strcmp - (& - (buffer - [strlen(PLAYLIST_STATE_FILE_RANDOM)]), - "1") == 0) { - setPlaylistRandomStatus(STDERR_FILENO, - 1); - } else - setPlaylistRandomStatus(STDERR_FILENO, - 0); - } else if (strncmp(buffer, PLAYLIST_STATE_FILE_CURRENT, - strlen(PLAYLIST_STATE_FILE_CURRENT)) - == 0) { - if (strlen(buffer) == - strlen(PLAYLIST_STATE_FILE_CURRENT)) { - ERROR("error parsing state " - "file \"%s\"\n", stateFile); - exit(EXIT_FAILURE); - } - current = atoi(&(buffer - [strlen - (PLAYLIST_STATE_FILE_CURRENT)])); + setPlaylistRepeatStatus(STDERR_FILENO, 0); + } else + if (strncmp + (buffer, PLAYLIST_STATE_FILE_CROSSFADE, + strlen(PLAYLIST_STATE_FILE_CROSSFADE)) == 0) { + setPlayerCrossFade(atoi + (& + (buffer + [strlen + (PLAYLIST_STATE_FILE_CROSSFADE)]))); + } else + if (strncmp + (buffer, PLAYLIST_STATE_FILE_RANDOM, + strlen(PLAYLIST_STATE_FILE_RANDOM)) == 0) { + if (strcmp + (& + (buffer + [strlen(PLAYLIST_STATE_FILE_RANDOM)]), + "1") == 0) { + setPlaylistRandomStatus(STDERR_FILENO, 1); } else - if (strncmp - (buffer, PLAYLIST_STATE_FILE_PLAYLIST_BEGIN, - strlen(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN) - ) == 0) { - if (state == PLAYER_STATE_STOP) - current = -1; - loadPlaylistFromStateFile(fp, buffer, state, - current, time); - } + setPlaylistRandomStatus(STDERR_FILENO, 0); + } else if (strncmp(buffer, PLAYLIST_STATE_FILE_CURRENT, + strlen(PLAYLIST_STATE_FILE_CURRENT)) + == 0) { + if (strlen(buffer) == + strlen(PLAYLIST_STATE_FILE_CURRENT)) + state_file_fatal(); + current = atoi(&(buffer + [strlen + (PLAYLIST_STATE_FILE_CURRENT)])); + } else + if (strncmp + (buffer, PLAYLIST_STATE_FILE_PLAYLIST_BEGIN, + strlen(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN) + ) == 0) { + if (state == PLAYER_STATE_STOP) + current = -1; + loadPlaylistFromStateFile(fp, buffer, state, + current, time); } - - fclose(fp); } } diff --git a/src/playlist.h b/src/playlist.h index 25ed45dfb..837bff161 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -34,9 +34,9 @@ void initPlaylist(); void finishPlaylist(); -void readPlaylistState(); +void readPlaylistState(FILE *); -void savePlaylistState(); +void savePlaylistState(FILE *); int clearPlaylist(int fd); @@ -116,6 +116,4 @@ int playlistChangesPosId(int fd, mpd_uint32 version); int PlaylistInfo(int fd, char *utf8file, int detail); -char *getStateFile(); - #endif diff --git a/src/state_file.c b/src/state_file.c new file mode 100644 index 000000000..1307faa54 --- /dev/null +++ b/src/state_file.c @@ -0,0 +1,112 @@ +/* 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 + */ + +#include "../config.h" +#include "state_file.h" +#include "conf.h" +#include "gcc.h" +#include "log.h" +#include "audio.h" +#include "playlist.h" +#include "utils.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> + +static struct _sf_cb { + void (*reader)(FILE *); + void (*writer)(FILE *); +} sf_callbacks [] = { + { readAudioDevicesState, saveAudioDevicesState }, + { readPlaylistState, savePlaylistState }, +}; + +static const char *sfpath = NULL; + +static void get_state_file_path(void) +{ + ConfigParam *param; + if (sfpath) + return; + param = parseConfigFilePath(CONF_STATE_FILE, 0); + if (param) + sfpath = (const char *)param->value; +} + +void write_state_file(void) +{ + int i; + FILE *fp; + + if (!sfpath) + return; + while (!(fp = fopen(sfpath, "w")) && errno == EINTR); + + if (mpd_unlikely(!fp)) { + ERROR("problems opening state file \"%s\" for writing: %s\n", + sfpath, strerror(errno)); + return; + } + + for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++) + sf_callbacks[i].writer(fp); + + while(fclose(fp) && errno == EINTR) /* nothing */; +} + +void read_state_file(void) +{ + struct stat st; + int i; + FILE *fp; + + get_state_file_path(); + if (!sfpath) + return; + if (stat(sfpath, &st) < 0) { + DEBUG("failed to stat state file: %s\n", sfpath); + return; + } + if (!S_ISREG(st.st_mode)) { + ERROR("state file \"%s\" is not a regular file\n", sfpath); + exit(EXIT_FAILURE); + } + + while (!(fp = fopen(sfpath, "r")) && errno == EINTR); + if (mpd_unlikely(!fp)) { + ERROR("problems opening state file \"%s\" for reading: %s\n", + sfpath, strerror(errno)); + exit(EXIT_FAILURE); + } + for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++) { + sf_callbacks[i].reader(fp); + rewind(fp); + } + + while(fclose(fp) && errno == EINTR) /* nothing */; +} + +void mpd_noreturn state_file_fatal(void) +{ + ERROR("error parsing state file \"%s\"\n", sfpath); + exit(EXIT_FAILURE); +} + diff --git a/src/state_file.h b/src/state_file.h new file mode 100644 index 000000000..e717fbe87 --- /dev/null +++ b/src/state_file.h @@ -0,0 +1,30 @@ +/* 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 + */ + +#ifndef STATE_FILE_H +#define STATE_FILE_H + +#include "gcc.h" + +#include <stdio.h> + +void write_state_file(void); +void read_state_file(void); +void mpd_noreturn state_file_fatal(void); + +#endif /* STATE_FILE_H */ diff --git a/src/utils.h b/src/utils.h index bc16905ea..02f70e946 100644 --- a/src/utils.h +++ b/src/utils.h @@ -29,6 +29,8 @@ #include <sys/stat.h> #include <fcntl.h> +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + char *myFgets(char *buffer, int bufferSize, FILE * fp); char *strDupToUpper(char *str); |