2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "state_file.h"
22 #include "output_state.h"
24 #include "playlist_state.h"
26 #include "glib_compat.h"
34 #define G_LOG_DOMAIN "state_file"
36 static char *state_file_path
;
38 /** the GLib source id for the save timer */
39 static guint save_state_source_id
;
42 * These version numbers determine whether we need to save the state
43 * file. If nothing has changed, we won't let the hard drive spin up.
45 static unsigned prev_volume_version
, prev_output_version
,
46 prev_playlist_version
;
49 state_file_write(void)
53 assert(state_file_path
!= NULL
);
55 g_debug("Saving state file %s", state_file_path
);
57 fp
= fopen(state_file_path
, "w");
58 if (G_UNLIKELY(!fp
)) {
59 g_warning("failed to create %s: %s",
60 state_file_path
, strerror(errno
));
64 save_sw_volume_state(fp
);
65 audio_output_state_save(fp
);
66 playlist_state_save(fp
, &g_playlist
);
68 while(fclose(fp
) && errno
== EINTR
) /* nothing */;
70 prev_volume_version
= sw_volume_state_get_hash();
71 prev_output_version
= audio_output_state_get_version();
72 prev_playlist_version
= playlist_state_get_hash(&g_playlist
);
82 assert(state_file_path
!= NULL
);
84 g_debug("Loading state file %s", state_file_path
);
86 fp
= fopen(state_file_path
, "r");
87 if (G_UNLIKELY(!fp
)) {
88 g_warning("failed to open %s: %s",
89 state_file_path
, strerror(errno
));
93 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
96 success
= read_sw_volume_state(line
) ||
97 audio_output_state_read(line
) ||
98 playlist_state_restore(line
, fp
, &g_playlist
);
100 g_warning("Unrecognized line in state file: %s", line
);
103 while(fclose(fp
) && errno
== EINTR
) /* nothing */;
105 prev_volume_version
= sw_volume_state_get_hash();
106 prev_output_version
= audio_output_state_get_version();
107 prev_playlist_version
= playlist_state_get_hash(&g_playlist
);
111 * This function is called every 5 minutes by the GLib main loop, and
112 * saves the state file.
115 timer_save_state_file(G_GNUC_UNUSED gpointer data
)
117 if (prev_volume_version
== sw_volume_state_get_hash() &&
118 prev_output_version
== audio_output_state_get_version() &&
119 prev_playlist_version
== playlist_state_get_hash(&g_playlist
))
120 /* nothing has changed - don't save the state file,
121 don't spin up the hard disk */
129 state_file_init(const char *path
)
131 assert(state_file_path
== NULL
);
136 state_file_path
= g_strdup(path
);
139 save_state_source_id
= g_timeout_add_seconds(5 * 60,
140 timer_save_state_file
,
145 state_file_finish(void)
147 if (state_file_path
== NULL
)
148 /* no state file configured, no cleanup required */
151 if (save_state_source_id
!= 0)
152 g_source_remove(save_state_source_id
);
156 g_free(state_file_path
);