1
1
/* This program is licensed under the GNU General Public License,
2
2
* version 2, a copy of which is included with this program.
4
* (c) 2000-2001 Michael Smith <msmith@labyrinth.net.au>
4
* (c) 2000-2002 Michael Smith <msmith@xiph.org>
5
5
* (c) 2001 Ralph Giles <giles@ashlu.bc.ca>
7
7
* Front end to show how to use vcedit;
49
void print_comments(FILE *out, vorbis_comment *vc);
50
int add_comment(char *line, vorbis_comment *vc);
54
void print_comments(FILE *out, vorbis_comment *vc, int raw);
55
int add_comment(char *line, vorbis_comment *vc, int raw);
52
57
param_t *new_param(void);
58
void free_param(param_t *param);
53
59
void parse_options(int argc, char *argv[], param_t *param);
54
60
void open_files(param_t *p);
55
61
void close_files(param_t *p);
91
101
if(vcedit_open(state, param->in) < 0)
93
fprintf(stderr, "Failed to open file as vorbis: %s\n",
103
fprintf(stderr, _("Failed to open file as vorbis: %s\n"),
94
104
vcedit_error(state));
98
111
/* extract and display the comments */
99
112
vc = vcedit_comments(state);
100
print_comments(param->com, vc);
113
print_comments(param->com, vc, param->raw);
103
116
vcedit_clear(state);
105
118
close_files(param);
113
127
if(vcedit_open(state, param->in) < 0)
115
fprintf(stderr, "Failed to open file as vorbis: %s\n",
129
fprintf(stderr, _("Failed to open file as vorbis: %s\n"),
116
130
vcedit_error(state));
128
145
for(i=0; i < param->commentcount; i++)
130
if(add_comment(param->comments[i], vc) < 0)
131
fprintf(stderr, "Bad comment: \"%s\"\n", param->comments[i]);
147
if(add_comment(param->comments[i], vc, param->raw) < 0)
148
fprintf(stderr, _("Bad comment: \"%s\"\n"), param->comments[i]);
134
151
/* build the replacement structure */
138
155
char *buf = (char *)malloc(sizeof(char)*1024);
140
157
while (fgets(buf, 1024, param->com))
141
if (add_comment(buf, vc) < 0) {
158
if (add_comment(buf, vc, param->raw) < 0) {
143
"bad comment: \"%s\"\n",
160
_("bad comment: \"%s\"\n"),
150
167
/* write out the modified stream */
151
168
if(vcedit_write(state, param->out) < 0)
153
fprintf(stderr, "Failed to write comments to output file: %s\n",
170
fprintf(stderr, _("Failed to write comments to output file: %s\n"),
154
171
vcedit_error(state));
179
void print_comments(FILE *out, vorbis_comment *vc)
201
void print_comments(FILE *out, vorbis_comment *vc, int raw)
182
204
char *decoded_value;
184
206
for (i = 0; i < vc->comments; i++)
186
if (utf8_decode(vc->user_comments[i], &decoded_value) >= 0)
208
if (!raw && utf8_decode(vc->user_comments[i], &decoded_value) >= 0)
188
210
fprintf(out, "%s\n", decoded_value);
189
211
free(decoded_value);
207
int add_comment(char *line, vorbis_comment *vc)
229
int add_comment(char *line, vorbis_comment *vc, int raw)
209
231
char *mark, *value, *utf8_value;
258
vorbis_comment_add_tag(vc, line, value);
235
261
/* convert the value from the native charset to UTF-8 */
236
if (utf8_encode(value, &utf8_value) >= 0) {
262
else if (utf8_encode(value, &utf8_value) >= 0) {
238
264
/* append the comment and return */
239
265
vorbis_comment_add_tag(vc, line, utf8_value);
240
266
free(utf8_value);
243
fprintf(stderr, "Couldn't convert comment to UTF8, "
269
fprintf(stderr, _("Couldn't convert comment to UTF8, "
262
" vorbiscomment [-l] file.ogg (to list the comments)\n"
263
" vorbiscomment -a in.ogg out.ogg (to append comments)\n"
264
" vorbiscomment -w in.ogg out.ogg (to modify comments)\n"
265
" in the write case, a new set of comments in the form\n"
266
" 'TAG=value' is expected on stdin. This set will\n"
267
" completely replace the existing set.\n"
268
" Either of -a and -w can take only a single filename,\n"
269
" in which case a temporary file will be used.\n"
270
" -c can be used to take comments from a specified file\n"
271
" instead of stdin.\n"
272
" Example: vorbiscomment -a in.ogg -c comments.txt\n"
273
" will append the comments in comments.txt to in.ogg\n"
274
" Finally, you may specify any number of tags to add on\n"
275
" the command line using the -t option. e.g.\n"
288
" vorbiscomment [-Vh]\n"
289
" vorbiscomment [-lR] file\n"
290
" vorbiscomment [-qR] [-c file] [-t tag] <-a|-w> inputfile [outputfile]\n"
292
" -l list the comments\n"
293
" -a append comments\n"
294
" -w write comments, replacing the existing ones\n"
295
" -c <file> read the comments from the specified file\n"
299
" -R, --raw read and write comments in utf8\n"
301
" If no OUTPUTFILE is specified, vorbiscomment will use a temporary file\n"
303
" vorbiscomment reads comments from:\n"
304
" - stdin in the form of 'TAG=value'\n"
305
" - a specified file instead of stdin, using '-c <FILE>'\n"
306
" - the command line, using '-t <TAG>' (disables reading from stdin)\n"
309
" vorbiscomment -a in.ogg -c comments.txt\n"
276
310
" vorbiscomment -a in.ogg -t \"ARTIST=Some Guy\" -t \"TITLE=A Title\"\n"
277
" (note that when using this, reading comments from the comment\n"
278
" file or stdin is disabled)\n"
312
" NOTE: Raw mode (--raw, -R) will read and write comments in utf8,\n"
313
" rather than converting to the user's character set. This is\n"
314
" useful for using vorbiscomment in scripts. However, this is\n"
315
" not sufficient for general round-tripping of comments in all\n"
321
void free_param(param_t *param) {
322
free(param->infilename);
323
free(param->outfilename);
326
372
setlocale(LC_ALL, "");
328
while ((ret = getopt_long(argc, argv, "alwhqc:t:",
374
while ((ret = getopt_long(argc, argv, "alwhqVc:t:R",
329
375
long_options, &option_index)) != -1) {
332
fprintf(stderr, "Internal error parsing command options\n");
378
fprintf(stderr, _("Internal error parsing command options\n"));
336
382
param->mode = MODE_LIST;
339
388
param->mode = MODE_WRITE;
342
391
param->mode = MODE_APPEND;
394
fprintf(stderr, "Vorbiscomment " VERSION "\n");
416
469
if (p->mode == MODE_WRITE || p->mode == MODE_APPEND) {
418
471
/* open output for write mode */
472
if(!strcmp(p->infilename, p->outfilename)) {
473
fprintf(stderr, _("Input filename may not be the same as output filename\n"));
420
477
if (strncmp(p->outfilename,"-",2) == 0) {
435
492
(strncmp(p->commentfilename,"-",2) == 0)) {
438
p->com = fopen(p->commentfilename, "rb");
495
p->com = fopen(p->commentfilename, "r");
440
497
if (p->com == NULL) {
442
"Error opening comment file '%s'.\n",
499
_("Error opening comment file '%s'.\n"),
443
500
p->commentfilename);
452
509
(strncmp(p->commentfilename,"-",2) == 0)) {
455
p->com = fopen(p->commentfilename, "wb");
512
p->com = fopen(p->commentfilename, "w");
457
514
if (p->com == NULL) {
459
"Error opening comment file '%s'\n",
516
_("Error opening comment file '%s'\n"),
460
517
p->commentfilename);
478
535
if (p->out != NULL && p->out != stdout) fclose(p->out);
479
536
if (p->com != NULL && p->com != stdout && p->com != stdin) fclose(p->com);
482
rename(p->outfilename, p->infilename);
539
/* Some platforms fail to rename a file if the new name already exists,
540
* so we need to remove, then rename. How stupid.
542
if(rename(p->outfilename, p->infilename)) {
543
if(remove(p->infilename))
544
fprintf(stderr, _("Error removing old file %s\n"), p->infilename);
545
else if(rename(p->outfilename, p->infilename))
546
fprintf(stderr, _("Error renaming %s to %s\n"), p->outfilename,