From dcff29e5aa18d8957635553753c4b4ddd730d790 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Sat, 3 Jan 2009 14:53:23 +0100
Subject: [PATCH] state_file: errors are non-fatal in read_state_file()

If the state file cannot be read, for whatever reason, don't abort
MPD.  The state file isn't _that_ important.
---
 NEWS             |  1 +
 src/playlist.c   | 32 ++++++++++++++++++++------------
 src/state_file.c | 19 +++----------------
 src/state_file.h |  1 -
 4 files changed, 24 insertions(+), 29 deletions(-)

diff --git a/NEWS b/NEWS
index d1f223eb6..4be474d9e 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ ver 0.15 - (200?/??/??)
   "log_file"
 * support logging to syslog
 * fall back to XDG music directory if no music_directory is configured
+* failure to read the state file is non-fatal
 
 ver 0.14 (2008/12/25)
 * audio outputs:
diff --git a/src/playlist.c b/src/playlist.c
index c36bb4bbe..49b3460f0 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -30,7 +30,6 @@
 #include "log.h"
 #include "mapper.h"
 #include "path.h"
-#include "state_file.h"
 #include "stored_playlist.h"
 #include "ack.h"
 #include "idle.h"
@@ -279,17 +278,26 @@ static void loadPlaylistFromStateFile(FILE *fp, char *buffer,
 	char *temp;
 	int song;
 
-	if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp))
-		state_file_fatal();
+	if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) {
+		g_warning("No playlist in state file");
+		return;
+	}
+
 	while (!g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_PLAYLIST_END)) {
 		g_strchomp(buffer);
 
 		temp = strtok(buffer, ":");
-		if (temp == NULL)
-			state_file_fatal();
+		if (temp == NULL) {
+			g_warning("Malformed playlist line in state file");
+			break;
+		}
+
 		song = atoi(temp);
-		if (!(temp = strtok(NULL, "")))
-			state_file_fatal();
+		if (!(temp = strtok(NULL, ""))) {
+			g_warning("Malformed playlist line in state file");
+			break;
+		}
+
 		if (addToPlaylist(temp, NULL) == PLAYLIST_RESULT_SUCCESS
 		    && current == song) {
 			if (state != PLAYER_STATE_STOP) {
@@ -304,8 +312,11 @@ static void loadPlaylistFromStateFile(FILE *fp, char *buffer,
 			}
 		}
 
-		if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp))
-			state_file_fatal();
+		if (!fgets(buffer, PLAYLIST_BUFFER_SIZE, fp)) {
+			g_warning("'%s' not found in state file",
+				  PLAYLIST_STATE_FILE_PLAYLIST_END);
+			break;
+		}
 	}
 }
 
@@ -357,9 +368,6 @@ void readPlaylistState(FILE *fp)
 			} else
 				setPlaylistRandomStatus(false);
 		} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_CURRENT)) {
-			if (strlen(buffer) ==
-			    strlen(PLAYLIST_STATE_FILE_CURRENT))
-				state_file_fatal();
 			current = atoi(&(buffer
 					 [strlen
 					  (PLAYLIST_STATE_FILE_CURRENT)]));
diff --git a/src/state_file.c b/src/state_file.c
index 53a6a711b..7666cc134 100644
--- a/src/state_file.c
+++ b/src/state_file.c
@@ -26,7 +26,6 @@
 
 #include <glib.h>
 #include <string.h>
-#include <sys/stat.h>
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "state_file"
@@ -74,24 +73,18 @@ void write_state_file(void)
 
 void read_state_file(void)
 {
-	struct stat st;
 	unsigned int i;
 	FILE *fp;
 
 	get_state_file_path();
 	if (!sfpath)
 		return;
-	if (stat(sfpath, &st) < 0) {
-		g_debug("failed to stat %s: %s", sfpath, strerror(errno));
-		return;
-	}
-	if (!S_ISREG(st.st_mode))
-		g_error("\"%s\" is not a regular file", sfpath);
 
 	while (!(fp = fopen(sfpath, "r")) && errno == EINTR);
 	if (G_UNLIKELY(!fp)) {
-		g_error("failed to open %s: %s",
-			sfpath, strerror(errno));
+		g_warning("failed to open %s: %s",
+			  sfpath, strerror(errno));
+		return;
 	}
 	for (i = 0; i < ARRAY_SIZE(sf_callbacks); i++) {
 		sf_callbacks[i].reader(fp);
@@ -100,9 +93,3 @@ void read_state_file(void)
 
 	while(fclose(fp) && errno == EINTR) /* nothing */;
 }
-
-void G_GNUC_NORETURN state_file_fatal(void)
-{
-	g_error("failed to parse %s", sfpath);
-}
-
diff --git a/src/state_file.h b/src/state_file.h
index 0fa1793d5..229df2861 100644
--- a/src/state_file.h
+++ b/src/state_file.h
@@ -23,6 +23,5 @@
 
 void write_state_file(void);
 void read_state_file(void);
-void G_GNUC_NORETURN state_file_fatal(void);
 
 #endif /* STATE_FILE_H */