~ubuntu-branches/ubuntu/precise/flac/precise-updates

« back to all changes in this revision

Viewing changes to src/metaflac/operations_shorthand_vorbiscomment.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529225636-ljeff8xxip09qaap
Tags: 1.1.4-1
* New upstream release. closes: #405167, #411311
  - libOggFLAC and libOggFLAC++ have been merged into libFLAC, so
    remove their corresponding packages.
  - Because of the API changes required to effect the above, there has
    been yet another soname bump. libflac7 -> libflac8 and
    libflac++5 -> libflac++6. Emails have been dispatched to the
    maintainers of dependent packages.
* Some notes on patches that were removed:
  - 02_stdin_stdout, 06_manpage_mention_utf8_convert: merged upstream
  - 08_manpage_warnings: Upstream has changed the manpage so it defintely
    can't fit in in 80 cols, so just forget about it. We'll live.
  - 05_eof_warnings_are_errors: Upstream decided to add a -w option to
    flac to treat all warnings as errors. I am going to defer to that
    for now, but if people think it's stupid let me know and I'll port
    the patch forward.
  - 04_stack_smasher: was a backport from 1.1.3, so it's obsolete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* metaflac - Command-line FLAC metadata editor
2
 
 * Copyright (C) 2001,2002,2003,2004,2005  Josh Coalson
 
2
 * Copyright (C) 2001,2002,2003,2004,2005,2006,2007  Josh Coalson
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU General Public License
16
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
17
 */
18
18
 
 
19
#if HAVE_CONFIG_H
 
20
#  include <config.h>
 
21
#endif
 
22
 
19
23
#include "options.h"
20
24
#include "utils.h"
21
25
#include "FLAC/assert.h"
 
26
#include "share/grabbag.h" /* for grabbag__file_get_filesize() */
22
27
#include "share/utf8.h"
 
28
#include <errno.h>
23
29
#include <stdlib.h>
24
30
#include <string.h>
25
31
 
27
33
static FLAC__bool remove_vc_field(const char *filename, FLAC__StreamMetadata *block, const char *field_name, FLAC__bool *needs_write);
28
34
static FLAC__bool remove_vc_firstfield(const char *filename, FLAC__StreamMetadata *block, const char *field_name, FLAC__bool *needs_write);
29
35
static FLAC__bool set_vc_field(const char *filename, FLAC__StreamMetadata *block, const Argument_VcField *field, FLAC__bool *needs_write, FLAC__bool raw);
30
 
static FLAC__bool import_vc_from(const char *filename, FLAC__StreamMetadata *block, const Argument_Filename *vc_filename, FLAC__bool *needs_write, FLAC__bool raw);
31
 
static FLAC__bool export_vc_to(const char *filename, FLAC__StreamMetadata *block, const Argument_Filename *vc_filename, FLAC__bool raw);
 
36
static FLAC__bool import_vc_from(const char *filename, FLAC__StreamMetadata *block, const Argument_String *vc_filename, FLAC__bool *needs_write, FLAC__bool raw);
 
37
static FLAC__bool export_vc_to(const char *filename, FLAC__StreamMetadata *block, const Argument_String *vc_filename, FLAC__bool raw);
32
38
 
33
39
FLAC__bool do_shorthand_operation__vorbis_comment(const char *filename, FLAC__bool prefix_with_filename, FLAC__Metadata_Chain *chain, const Operation *operation, FLAC__bool *needs_write, FLAC__bool raw)
34
40
{
171
177
{
172
178
        FLAC__StreamMetadata_VorbisComment_Entry entry;
173
179
        char *converted;
174
 
        FLAC__bool needs_free = false;
175
180
 
176
181
        FLAC__ASSERT(0 != block);
177
182
        FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
178
183
        FLAC__ASSERT(0 != field);
179
184
        FLAC__ASSERT(0 != needs_write);
180
185
 
181
 
        if(raw) {
182
 
                entry.entry = (FLAC__byte *)field->field;
183
 
        }
184
 
        else if(utf8_encode(field->field, &converted) >= 0) {
185
 
                entry.entry = (FLAC__byte *)converted;
186
 
                needs_free = true;
187
 
        }
188
 
        else {
189
 
                fprintf(stderr, "%s: ERROR: couldn't convert comment to UTF-8\n", filename);
190
 
                return false;
191
 
        }
192
 
 
193
 
        entry.length = strlen((const char *)entry.entry);
194
 
 
195
 
        if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
196
 
                if(needs_free)
 
186
        if(field->field_value_from_file) {
 
187
                /* read the file into 'data' */
 
188
                FILE *f = 0;
 
189
                char *data = 0;
 
190
                const off_t size = grabbag__file_get_filesize(field->field_value);
 
191
                if(size < 0) {
 
192
                        fprintf(stderr, "%s: ERROR: can't open file '%s' for '%s' tag value\n", filename, field->field_value, field->field_name);
 
193
                        return false;
 
194
                }
 
195
                if(size >= 0x100000) { /* magic arbitrary limit, actual format limit is near 16MB */
 
196
                        fprintf(stderr, "%s: ERROR: file '%s' for '%s' tag value is too large\n", filename, field->field_value, field->field_name);
 
197
                        return false;
 
198
                }
 
199
                if(0 == (data = malloc(size+1)))
 
200
                        die("out of memory allocating tag value");
 
201
                data[size] = '\0';
 
202
                if(0 == (f = fopen(field->field_value, "rb")) || fread(data, 1, size, f) != (size_t)size) {
 
203
                        fprintf(stderr, "%s: ERROR: while reading file '%s' for '%s' tag value: %s\n", filename, field->field_value, field->field_name, strerror(errno));
 
204
                        free(data);
 
205
                        if(f)
 
206
                                fclose(f);
 
207
                        return false;
 
208
                }
 
209
                fclose(f);
 
210
                if(strlen(data) != (size_t)size) {
 
211
                        free(data);
 
212
                        fprintf(stderr, "%s: ERROR: file '%s' for '%s' tag value has embedded NULs\n", filename, field->field_value, field->field_name);
 
213
                        return false;
 
214
                }
 
215
 
 
216
                /* move 'data' into 'converted', converting to UTF-8 if necessary */
 
217
                if(raw) {
 
218
                        converted = data;
 
219
                }
 
220
                else if(utf8_encode(data, &converted) >= 0) {
 
221
                        free(data);
 
222
                }
 
223
                else {
 
224
                        free(data);
 
225
                        fprintf(stderr, "%s: ERROR: converting file '%s' contents to UTF-8 for tag value\n", filename, field->field_value);
 
226
                        return false;
 
227
                }
 
228
 
 
229
                /* create and entry and append it */
 
230
                if(!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, field->field_name, converted)) {
197
231
                        free(converted);
198
 
                fprintf(stderr, "%s: ERROR: memory allocation failure\n", filename);
199
 
                return false;
 
232
                        fprintf(stderr, "%s: ERROR: file '%s' for '%s' tag value is not valid UTF-8\n", filename, field->field_value, field->field_name);
 
233
                        return false;
 
234
                }
 
235
                free(converted);
 
236
                if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/false)) {
 
237
                        fprintf(stderr, "%s: ERROR: memory allocation failure\n", filename);
 
238
                        return false;
 
239
                }
 
240
 
 
241
                *needs_write = true;
 
242
                return true;
200
243
        }
201
244
        else {
 
245
                FLAC__bool needs_free = false;
 
246
                if(raw) {
 
247
                        entry.entry = (FLAC__byte *)field->field;
 
248
                }
 
249
                else if(utf8_encode(field->field, &converted) >= 0) {
 
250
                        entry.entry = (FLAC__byte *)converted;
 
251
                        needs_free = true;
 
252
                }
 
253
                else {
 
254
                        fprintf(stderr, "%s: ERROR: converting comment '%s' to UTF-8\n", filename, field->field);
 
255
                        return false;
 
256
                }
 
257
                entry.length = strlen((const char *)entry.entry);
 
258
                if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) {
 
259
                        if(needs_free)
 
260
                                free(converted);
 
261
                        /*
 
262
                         * our previous parsing has already established that the field
 
263
                         * name is OK, so it must be the field value
 
264
                         */
 
265
                        fprintf(stderr, "%s: ERROR: tag value for '%s' is not valid UTF-8\n", filename, field->field_name);
 
266
                        return false;
 
267
                }
 
268
 
 
269
                if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
 
270
                        if(needs_free)
 
271
                                free(converted);
 
272
                        fprintf(stderr, "%s: ERROR: memory allocation failure\n", filename);
 
273
                        return false;
 
274
                }
 
275
 
202
276
                *needs_write = true;
203
277
                if(needs_free)
204
278
                        free(converted);
206
280
        }
207
281
}
208
282
 
209
 
FLAC__bool import_vc_from(const char *filename, FLAC__StreamMetadata *block, const Argument_Filename *vc_filename, FLAC__bool *needs_write, FLAC__bool raw)
 
283
FLAC__bool import_vc_from(const char *filename, FLAC__StreamMetadata *block, const Argument_String *vc_filename, FLAC__bool *needs_write, FLAC__bool raw)
210
284
{
211
285
        FILE *f;
212
286
        char line[65536];
222
296
                f = fopen(vc_filename->value, "r");
223
297
 
224
298
        if(0 == f) {
225
 
                fprintf(stderr, "%s: ERROR: can't open import file %s\n", filename, vc_filename->value);
 
299
                fprintf(stderr, "%s: ERROR: can't open import file %s: %s\n", filename, vc_filename->value, strerror(errno));
226
300
                return false;
227
301
        }
228
302
 
240
314
                                Argument_VcField field;
241
315
                                *p = '\0';
242
316
                                memset(&field, 0, sizeof(Argument_VcField));
 
317
                                field.field_value_from_file = false;
243
318
                                if(!parse_vorbis_comment_field(line, &field.field, &field.field_name, &field.field_value, &field.field_value_length, &violation)) {
244
319
                                        FLAC__ASSERT(0 != violation);
245
320
                                        fprintf(stderr, "%s: ERROR: malformed vorbis comment field \"%s\",\n       %s\n", vc_filename->value, line, violation);
263
338
        return ret;
264
339
}
265
340
 
266
 
FLAC__bool export_vc_to(const char *filename, FLAC__StreamMetadata *block, const Argument_Filename *vc_filename, FLAC__bool raw)
 
341
FLAC__bool export_vc_to(const char *filename, FLAC__StreamMetadata *block, const Argument_String *vc_filename, FLAC__bool raw)
267
342
{
268
343
        FILE *f;
269
344
        FLAC__bool ret;
278
353
                f = fopen(vc_filename->value, "w");
279
354
 
280
355
        if(0 == f) {
281
 
                fprintf(stderr, "%s: ERROR: can't open export file %s\n", filename, vc_filename->value);
 
356
                fprintf(stderr, "%s: ERROR: can't open export file %s: %s\n", filename, vc_filename->value, strerror(errno));
282
357
                return false;
283
358
        }
284
359