~ubuntu-branches/ubuntu/utopic/mpd/utopic-proposed

« back to all changes in this revision

Viewing changes to src/song_update.c

  • Committer: Package Import Robot
  • Author(s): Steve Kowalik
  • Date: 2013-11-12 18:17:40 UTC
  • mfrom: (2.2.36 sid)
  • Revision ID: package-import@ubuntu.com-20131112181740-72aa4zihehoobedp
Tags: 0.18.3-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Add libmp3lame-dev to Build-Depends, and enable LAME.
  - Read the user for the daemon from the config file in the init script.
  - Move avahi-daemon from Suggests to Recommends.
  - Added apport hook to include user configuration file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2003-2011 The Music Player Daemon Project
3
 
 * http://www.musicpd.org
4
 
 *
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.
9
 
 *
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.
14
 
 *
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.
18
 
 */
19
 
 
20
 
#include "config.h" /* must be first for large file support */
21
 
#include "song.h"
22
 
#include "uri.h"
23
 
#include "directory.h"
24
 
#include "mapper.h"
25
 
#include "decoder_list.h"
26
 
#include "decoder_plugin.h"
27
 
#include "tag_ape.h"
28
 
#include "tag_id3.h"
29
 
#include "tag.h"
30
 
#include "tag_handler.h"
31
 
#include "input_stream.h"
32
 
 
33
 
#include <glib.h>
34
 
 
35
 
#include <assert.h>
36
 
#include <sys/types.h>
37
 
#include <sys/stat.h>
38
 
#include <stdio.h>
39
 
 
40
 
struct song *
41
 
song_file_load(const char *path, struct directory *parent)
42
 
{
43
 
        struct song *song;
44
 
        bool ret;
45
 
 
46
 
        assert((parent == NULL) == g_path_is_absolute(path));
47
 
        assert(!uri_has_scheme(path));
48
 
        assert(strchr(path, '\n') == NULL);
49
 
 
50
 
        song = song_file_new(path, parent);
51
 
 
52
 
        //in archive ?
53
 
        if (parent != NULL && parent->device == DEVICE_INARCHIVE) {
54
 
                ret = song_file_update_inarchive(song);
55
 
        } else {
56
 
                ret = song_file_update(song);
57
 
        }
58
 
        if (!ret) {
59
 
                song_free(song);
60
 
                return NULL;
61
 
        }
62
 
 
63
 
        return song;
64
 
}
65
 
 
66
 
/**
67
 
 * Attempts to load APE or ID3 tags from the specified file.
68
 
 */
69
 
static bool
70
 
tag_scan_fallback(const char *path,
71
 
                  const struct tag_handler *handler, void *handler_ctx)
72
 
{
73
 
        return tag_ape_scan2(path, handler, handler_ctx) ||
74
 
                tag_id3_scan(path, handler, handler_ctx);
75
 
}
76
 
 
77
 
bool
78
 
song_file_update(struct song *song)
79
 
{
80
 
        const char *suffix;
81
 
        char *path_fs;
82
 
        const struct decoder_plugin *plugin;
83
 
        struct stat st;
84
 
        struct input_stream *is = NULL;
85
 
 
86
 
        assert(song_is_file(song));
87
 
 
88
 
        /* check if there's a suffix and a plugin */
89
 
 
90
 
        suffix = uri_get_suffix(song->uri);
91
 
        if (suffix == NULL)
92
 
                return false;
93
 
 
94
 
        plugin = decoder_plugin_from_suffix(suffix, NULL);
95
 
        if (plugin == NULL)
96
 
                return false;
97
 
 
98
 
        path_fs = map_song_fs(song);
99
 
        if (path_fs == NULL)
100
 
                return false;
101
 
 
102
 
        if (song->tag != NULL) {
103
 
                tag_free(song->tag);
104
 
                song->tag = NULL;
105
 
        }
106
 
 
107
 
        if (stat(path_fs, &st) < 0 || !S_ISREG(st.st_mode)) {
108
 
                g_free(path_fs);
109
 
                return false;
110
 
        }
111
 
 
112
 
        song->mtime = st.st_mtime;
113
 
 
114
 
        GMutex *mutex = NULL;
115
 
        GCond *cond;
116
 
#if !GCC_CHECK_VERSION(4, 2)
117
 
        /* work around "may be used uninitialized in this function"
118
 
           false positive */
119
 
        cond = NULL;
120
 
#endif
121
 
 
122
 
        do {
123
 
                /* load file tag */
124
 
                song->tag = tag_new();
125
 
                if (decoder_plugin_scan_file(plugin, path_fs,
126
 
                                             &full_tag_handler, song->tag))
127
 
                        break;
128
 
 
129
 
                tag_free(song->tag);
130
 
                song->tag = NULL;
131
 
 
132
 
                /* fall back to stream tag */
133
 
                if (plugin->scan_stream != NULL) {
134
 
                        /* open the input_stream (if not already
135
 
                           open) */
136
 
                        if (is == NULL) {
137
 
                                mutex = g_mutex_new();
138
 
                                cond = g_cond_new();
139
 
                                is = input_stream_open(path_fs, mutex, cond,
140
 
                                                       NULL);
141
 
                        }
142
 
 
143
 
                        /* now try the stream_tag() method */
144
 
                        if (is != NULL) {
145
 
                                song->tag = tag_new();
146
 
                                if (decoder_plugin_scan_stream(plugin, is,
147
 
                                                               &full_tag_handler,
148
 
                                                               song->tag))
149
 
                                        break;
150
 
 
151
 
                                tag_free(song->tag);
152
 
                                song->tag = NULL;
153
 
 
154
 
                                input_stream_lock_seek(is, 0, SEEK_SET, NULL);
155
 
                        }
156
 
                }
157
 
 
158
 
                plugin = decoder_plugin_from_suffix(suffix, plugin);
159
 
        } while (plugin != NULL);
160
 
 
161
 
        if (is != NULL)
162
 
                input_stream_close(is);
163
 
 
164
 
        if (mutex != NULL) {
165
 
                g_cond_free(cond);
166
 
                g_mutex_free(mutex);
167
 
        }
168
 
 
169
 
        if (song->tag != NULL && tag_is_empty(song->tag))
170
 
                tag_scan_fallback(path_fs, &full_tag_handler, song->tag);
171
 
 
172
 
        g_free(path_fs);
173
 
        return song->tag != NULL;
174
 
}
175
 
 
176
 
bool
177
 
song_file_update_inarchive(struct song *song)
178
 
{
179
 
        const char *suffix;
180
 
        const struct decoder_plugin *plugin;
181
 
 
182
 
        assert(song_is_file(song));
183
 
 
184
 
        /* check if there's a suffix and a plugin */
185
 
 
186
 
        suffix = uri_get_suffix(song->uri);
187
 
        if (suffix == NULL)
188
 
                return false;
189
 
 
190
 
        plugin = decoder_plugin_from_suffix(suffix, false);
191
 
        if (plugin == NULL)
192
 
                return false;
193
 
 
194
 
        if (song->tag != NULL)
195
 
                tag_free(song->tag);
196
 
 
197
 
        //accept every file that has music suffix
198
 
        //because we don't support tag reading through
199
 
        //input streams
200
 
        song->tag = tag_new();
201
 
 
202
 
        return true;
203
 
}