~ubuntu-branches/ubuntu/trusty/mpd/trusty

« back to all changes in this revision

Viewing changes to src/state_file.c

  • Committer: Bazaar Package Importer
  • Author(s): Angel Abad
  • Date: 2011-02-02 12:26:30 UTC
  • mfrom: (1.5.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110202122630-bdyx8w4k94doz4fs
Tags: 0.16.1-1ubuntu1
* Merge from debian unstable. Remaining changes:
  - debian/control:
    + Don't build-depend on libmikmod2-dev (Debian bug #510675).
    + Move avahi-daemon from Suggests field to Recommends field.
  - debian/mpd.init.d:
    + Read mpd user from mpd.conf.
  - debian/control, debian/rules:
    + Add libmp3lame-dev to the build dependencies and enable lame.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2003-2009 The Music Player Daemon Project
 
2
 * Copyright (C) 2003-2010 The Music Player Daemon Project
3
3
 * http://www.musicpd.org
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
17
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 */
19
19
 
 
20
#include "config.h"
20
21
#include "state_file.h"
21
22
#include "output_state.h"
22
23
#include "playlist.h"
 
24
#include "playlist_state.h"
23
25
#include "volume.h"
 
26
#include "text_file.h"
 
27
#include "glib_compat.h"
24
28
 
25
29
#include <glib.h>
26
30
#include <assert.h>
30
34
#undef G_LOG_DOMAIN
31
35
#define G_LOG_DOMAIN "state_file"
32
36
 
33
 
static struct _sf_cb {
34
 
        void (*reader)(FILE *);
35
 
        void (*writer)(FILE *);
36
 
} sf_callbacks [] = {
37
 
        { read_sw_volume_state, save_sw_volume_state },
38
 
        { readAudioDevicesState, saveAudioDevicesState },
39
 
        { readPlaylistState, savePlaylistState },
40
 
};
41
 
 
42
37
static char *state_file_path;
43
38
 
44
39
/** the GLib source id for the save timer */
45
40
static guint save_state_source_id;
46
41
 
 
42
/**
 
43
 * These version numbers determine whether we need to save the state
 
44
 * file.  If nothing has changed, we won't let the hard drive spin up.
 
45
 */
 
46
static unsigned prev_volume_version, prev_output_version,
 
47
        prev_playlist_version;
 
48
 
47
49
static void
48
50
state_file_write(void)
49
51
{
50
 
        unsigned int i;
51
52
        FILE *fp;
52
53
 
53
 
        if (state_file_path == NULL)
54
 
                return;
 
54
        assert(state_file_path != NULL);
 
55
 
 
56
        g_debug("Saving state file %s", state_file_path);
55
57
 
56
58
        fp = fopen(state_file_path, "w");
57
59
        if (G_UNLIKELY(!fp)) {
60
62
                return;
61
63
        }
62
64
 
63
 
        for (i = 0; i < G_N_ELEMENTS(sf_callbacks); i++)
64
 
                sf_callbacks[i].writer(fp);
65
 
 
66
 
        while(fclose(fp) && errno == EINTR) /* nothing */;
 
65
        save_sw_volume_state(fp);
 
66
        audio_output_state_save(fp);
 
67
        playlist_state_save(fp, &g_playlist);
 
68
 
 
69
        fclose(fp);
 
70
 
 
71
        prev_volume_version = sw_volume_state_get_hash();
 
72
        prev_output_version = audio_output_state_get_version();
 
73
        prev_playlist_version = playlist_state_get_hash(&g_playlist);
67
74
}
68
75
 
69
76
static void
70
77
state_file_read(void)
71
78
{
72
 
        unsigned int i;
73
79
        FILE *fp;
 
80
        bool success;
74
81
 
75
82
        assert(state_file_path != NULL);
76
83
 
77
 
        g_debug("Saving state file");
 
84
        g_debug("Loading state file %s", state_file_path);
78
85
 
79
86
        fp = fopen(state_file_path, "r");
80
87
        if (G_UNLIKELY(!fp)) {
82
89
                          state_file_path, strerror(errno));
83
90
                return;
84
91
        }
85
 
        for (i = 0; i < G_N_ELEMENTS(sf_callbacks); i++) {
86
 
                sf_callbacks[i].reader(fp);
87
 
                rewind(fp);
 
92
 
 
93
        GString *buffer = g_string_sized_new(1024);
 
94
        const char *line;
 
95
        while ((line = read_text_line(fp, buffer)) != NULL) {
 
96
                success = read_sw_volume_state(line) ||
 
97
                        audio_output_state_read(line) ||
 
98
                        playlist_state_restore(line, fp, buffer, &g_playlist);
 
99
                if (!success)
 
100
                        g_warning("Unrecognized line in state file: %s", line);
88
101
        }
89
102
 
90
 
        while(fclose(fp) && errno == EINTR) /* nothing */;
 
103
        fclose(fp);
 
104
 
 
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);
 
108
 
 
109
 
 
110
        g_string_free(buffer, true);
91
111
}
92
112
 
93
113
/**
97
117
static gboolean
98
118
timer_save_state_file(G_GNUC_UNUSED gpointer data)
99
119
{
 
120
        if (prev_volume_version == sw_volume_state_get_hash() &&
 
121
            prev_output_version == audio_output_state_get_version() &&
 
122
            prev_playlist_version == playlist_state_get_hash(&g_playlist))
 
123
                /* nothing has changed - don't save the state file,
 
124
                   don't spin up the hard disk */
 
125
                return true;
 
126
 
100
127
        state_file_write();
101
128
        return true;
102
129
}
112
139
        state_file_path = g_strdup(path);
113
140
        state_file_read();
114
141
 
115
 
        save_state_source_id = g_timeout_add(5 * 60 * 1000,
116
 
                                             timer_save_state_file, NULL);
 
142
        save_state_source_id = g_timeout_add_seconds(5 * 60,
 
143
                                                     timer_save_state_file,
 
144
                                                     NULL);
117
145
}
118
146
 
119
147
void
120
148
state_file_finish(void)
121
149
{
 
150
        if (state_file_path == NULL)
 
151
                /* no state file configured, no cleanup required */
 
152
                return;
 
153
 
122
154
        if (save_state_source_id != 0)
123
155
                g_source_remove(save_state_source_id);
124
156
 
125
 
        if (state_file_path != NULL)
126
 
                state_file_write();
 
157
        state_file_write();
127
158
 
128
159
        g_free(state_file_path);
129
160
}