1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
$NetBSD: patch-ac,v 1.8 2003/11/11 09:17:53 abs Exp $
--- mserv/mserv.c.orig Sun Aug 3 15:57:20 2003
+++ mserv/mserv.c
@@ -62,12 +62,17 @@ met:
#include <sys/ioctl.h>
#include <time.h>
+#ifdef PARSE_OGG_INFO
+#include <vorbis/codec.h>
+#include <vorbis/vorbisfile.h>
+#endif
+
#include "mserv.h"
#include "misc.h"
#include "cmd.h"
#include "acl.h"
#include "mp3info.h"
-#include "soundcard.h"
+#include "mservsoundcard.h"
#include "defconf.h"
#include "conf.h"
#include "opt.h"
@@ -2019,11 +2024,13 @@ static t_track *mserv_loadtrk(const char
alen = strlen(buffer);
if (buffer[alen-1] != '\n') {
mserv_log("Line %d too long in '%s'", line, fullpath_trk);
+ fclose(fd);
return NULL;
}
buffer[--alen] = '\0';
if (!(l = strcspn(buffer, "=")) || l >= 64) {
mserv_log("Invalid track line %d in '%s'", line, fullpath_trk);
+ fclose(fd);
return NULL;
}
strncpy(token, buffer, l);
@@ -2059,6 +2066,7 @@ static t_track *mserv_loadtrk(const char
}
if ((arate = malloc(sizeof(t_rating)+strlen(token)+1)) == NULL) {
mserv_log("Out of memory creating ratings for '%s'", fullpath_trk);
+ fclose(fd);
return NULL;
}
memset(arate, 0, sizeof(t_rating));
@@ -2082,15 +2090,18 @@ static t_track *mserv_loadtrk(const char
}
if (!*author) {
mserv_log("No author specified in '%s'", fullpath_trk);
+ fclose(fd);
return NULL;
}
if (!*name) {
mserv_log("No name specified in '%s'", fullpath_trk);
+ fclose(fd);
return NULL;
}
if (fstat(fileno(fd), &buf) == -1) {
perror("fstat");
mserv_log("Unable to stat '%s': %s", filename, strerror(errno));
+ fclose(fd);
return NULL;
}
mtime = buf.st_mtime;
@@ -2098,8 +2109,17 @@ static t_track *mserv_loadtrk(const char
}
if (duration == 0 && !*miscinfo) {
len = strlen(fullpath_file);
+#ifdef PARSE_OGG_INFO
+ if (len > 4 && !stricmp(".mp3", fullpath_file+len-4) ||
+ !stricmp(".ogg", fullpath_file+len-4)) {
+ if (!stricmp(".mp3", fullpath_file+len-4))
+ duration = mserv_mp3info_readlen(fullpath_file, &bitrate, &id3tag);
+ else
+ duration = mserv_ogginfo_readlen(fullpath_file, &bitrate, &id3tag);
+#else
if (len > 4 && !stricmp(".mp3", fullpath_file+len-4)) {
duration = mserv_mp3info_readlen(fullpath_file, &bitrate, &id3tag);
+#endif
if (duration == -1) {
mserv_log("Unable to determine details of mp3 '%s': %s",
filename, strerror(errno));
@@ -3427,6 +3447,62 @@ int mserv_setmixer(t_client *cl, int wha
close(mixer_fd);
mserv_response(cl, "NAN", NULL);
return -1;
+}
+
+#endif
+
+#ifdef PARSE_OGG_INFO
+int mserv_ogginfo_readlen(const char *fname, int *bitrate_ret,
+ t_id3tag *id3tag)
+{
+ OggVorbis_File vf;
+ FILE *f;
+ ogg_sync_state sync;
+ vorbis_info *vi;
+ vorbis_comment *vc;
+ char **comment;
+ double duration;
+
+ if (id3tag)
+ memset(id3tag, 0, sizeof(*id3tag));
+
+ if ((f = fopen(fname, "rb")) == NULL)
+ return -1;
+
+ if (ov_open(f, &vf, NULL, 0) < 0) {
+ fclose(f);
+ return -1;
+ }
+
+ if ( !(vi = ov_info(&vf, -1)) || !(vc = ov_comment(&vf, -1))) {
+ ov_clear(&vf);
+ fclose(f);
+ return -1;
+ }
+
+ if (bitrate_ret)
+ *bitrate_ret = vi->bitrate_nominal/1024;
+
+ for (comment = vc->user_comments ; *comment ; ++comment) {
+ if (strncmp(*comment, "title=", 6) == 0) {
+ strlcpy(id3tag->title, *comment + 6, MP3ID3_TITLELEN+1);
+ id3tag->present = 1;
+ }
+ else if (strncmp(*comment, "artist=", 7) == 0)
+ strlcpy(id3tag->artist, *comment + 7, MP3ID3_ARTISTLEN+1);
+ else if (strncmp(*comment, "album=", 6) == 0)
+ strlcpy(id3tag->album, *comment + 6, MP3ID3_ALBUMLEN+1);
+ else if (strncmp(*comment, "date=", 5) == 0)
+ strlcpy(id3tag->year, *comment + 5, MP3ID3_YEARLEN+1);
+ else if (strncmp(*comment, "genre=", 6) == 0)
+ strlcpy(id3tag->genre, *comment + 6, 31);
+ /* tracknumber ignored */
+ }
+
+ duration = ov_time_total(&vf, -1);
+ ov_clear(&vf);
+ fclose(f);
+ return (int)duration * 100;
}
#endif
|