281 lines
8 KiB
Text
281 lines
8 KiB
Text
$NetBSD: patch-af,v 1.10 2012/02/07 09:44:22 martin Exp $
|
|
|
|
--- mserv/mserv.c.orig 2003-08-03 16:57:20.000000000 +0200
|
|
+++ mserv/mserv.c 2012-02-07 10:39:02.000000000 +0100
|
|
@@ -62,12 +62,17 @@
|
|
#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"
|
|
@@ -79,6 +84,10 @@
|
|
# define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
|
|
#endif
|
|
|
|
+#ifndef HAVE_STRLCPY
|
|
+#define strlcpy strncpy
|
|
+#endif
|
|
+
|
|
extern char *optarg;
|
|
extern int optind;
|
|
/* extern int getopt(int, char *const *, const char *); */ /* sunos ;( */
|
|
@@ -131,7 +140,8 @@
|
|
static void mserv_scandir(void);
|
|
static void mserv_scandir_recurse(const char *pathname);
|
|
static t_track *mserv_loadtrk(const char *filename);
|
|
-static t_album *mserv_loadalbum(const char *filename, int onlyifexists);
|
|
+static t_album *mserv_loadalbum(const char *filename, int onlyifexists,
|
|
+ const char *default_author);
|
|
static int album_insertsort(t_album *album);
|
|
static t_author *mserv_authorlist(void);
|
|
static int author_insertsort(t_author **list, t_author *author);
|
|
@@ -224,7 +234,7 @@
|
|
int i;
|
|
struct protoent *protocol;
|
|
struct sockaddr_in sin;
|
|
- int so_int;
|
|
+ int so_int, proto;
|
|
int flags;
|
|
char *mserv_root = NULL;
|
|
char *mserv_conf = NULL;
|
|
@@ -292,7 +302,7 @@
|
|
ps->pw_dir[strlen(ps->pw_dir)-1] == '/' ? "" : "/");
|
|
} else {
|
|
/* copy out of environment */
|
|
- if ((m = malloc(strlen(mserv_root))) == NULL) {
|
|
+ if ((m = malloc(strlen(mserv_root)+1)) == NULL) {
|
|
fprintf(stderr, "%s: out of memory\n", progname);
|
|
exit(1);
|
|
}
|
|
@@ -305,7 +315,7 @@
|
|
l--;
|
|
mserv_root[l] = '\0';
|
|
if (!mserv_conf) {
|
|
- if ((m = malloc(strlen(mserv_root)+sizeof("/config"))) == NULL) {
|
|
+ if ((m = malloc(strlen(mserv_root)+sizeof("/config")+1)) == NULL) {
|
|
fprintf(stderr, "%s: out of memory\n", progname);
|
|
exit(1);
|
|
}
|
|
@@ -427,8 +437,13 @@
|
|
|
|
if (mserv_verbose && mserv_port)
|
|
printf("Port set via command line options to %d\n", mserv_port);
|
|
+
|
|
protocol = getprotobyname("IP");
|
|
- mserv_socket = socket(AF_INET, SOCK_STREAM, protocol->p_proto);
|
|
+ if (protocol)
|
|
+ proto = protocol->p_proto;
|
|
+ else
|
|
+ proto = IPPROTO_IP;
|
|
+ mserv_socket = socket(AF_INET, SOCK_STREAM, proto);
|
|
if (mserv_socket == -1) {
|
|
mserv_log("Socket error '%s'", strerror(errno));
|
|
mserv_closedown(1);
|
|
@@ -1624,6 +1639,7 @@
|
|
int i;
|
|
t_album *album;
|
|
int flag = 0;
|
|
+ const char *default_author = 0;
|
|
|
|
/* pathname is "" or "directory/" or "directory/directory/..." */
|
|
|
|
@@ -1686,22 +1702,32 @@
|
|
toomany = 1;
|
|
break;
|
|
}
|
|
+
|
|
if (mserv_verbose)
|
|
mserv_log("Track file: %s", fullpath);
|
|
if ((tracks[tnum] = mserv_loadtrk(filename)) == NULL) {
|
|
mserv_log("Unable to add track '%s'", fullpath);
|
|
} else {
|
|
+
|
|
+ if (default_author == 0)
|
|
+ default_author = tracks[tnum]->author;
|
|
+ else if (default_author != (const char *)-1 && strcmp(default_author,
|
|
+ tracks[tnum]->author))
|
|
+ default_author = (const char *)-1;
|
|
+
|
|
tracks[tnum]->id = mserv_nextid_track++;
|
|
tracks[tnum]->n_album = mserv_nextid_album;
|
|
tracks[tnum]->n_track = tnum+1;
|
|
tracks[tnum]->next = mserv_tracks;
|
|
mserv_tracks = tracks[tnum++];
|
|
}
|
|
+
|
|
flag = 1; /* there is at least one track in this directory */
|
|
}
|
|
closedir(dir);
|
|
/* load album, but only if there is an album file or flag is set */
|
|
- if ((album = mserv_loadalbum(pathname, flag ? 0 : 1)) == NULL)
|
|
+ if ((album = mserv_loadalbum(pathname, flag ? 0 : 1,
|
|
+ (default_author == (const char *)-1) ?0 :default_author)) == NULL)
|
|
return;
|
|
qsort(tracks, TRACKSPERALBUM, sizeof(t_track *),
|
|
mserv_trackcompare_filename);
|
|
@@ -1815,7 +1841,7 @@
|
|
}
|
|
}
|
|
|
|
-static t_album *mserv_loadalbum(const char *filename, int onlyifexists)
|
|
+static t_album *mserv_loadalbum(const char *filename, int onlyifexists, const char *default_author)
|
|
{
|
|
FILE *fd;
|
|
char fullpath[MAXFNAME];
|
|
@@ -1899,8 +1925,13 @@
|
|
return NULL;
|
|
mtime = time(NULL);
|
|
}
|
|
- if (!*author)
|
|
- strcpy(author, "!-Unindexed");
|
|
+ if (!*author) {
|
|
+ if (default_author)
|
|
+ strcpy(author, default_author);
|
|
+ else
|
|
+ strcpy(author, "!-Unindexed");
|
|
+ }
|
|
+
|
|
if (!*name) {
|
|
if (!*filename || !*(filename+1)) {
|
|
strcpy(name, "rootdir");
|
|
@@ -2019,11 +2050,13 @@
|
|
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 +2092,7 @@
|
|
}
|
|
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 +2116,18 @@
|
|
}
|
|
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 +2135,17 @@
|
|
}
|
|
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));
|
|
@@ -2719,7 +2765,7 @@
|
|
}
|
|
if (buf.st_mtime == album->mtime)
|
|
return album;
|
|
- if ((newalbum = mserv_loadalbum(album->filename, 1)) == NULL) {
|
|
+ if ((newalbum = mserv_loadalbum(album->filename, 1, 0)) == NULL) {
|
|
mserv_log("Unable to re-load '%s'", album->filename);
|
|
return album;
|
|
}
|
|
@@ -3430,3 +3476,59 @@
|
|
}
|
|
|
|
#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 (strncasecmp(*comment, "title=", 6) == 0) {
|
|
+ strlcpy(id3tag->title, *comment + 6, MP3ID3_TITLELEN+1);
|
|
+ id3tag->present = 1;
|
|
+ }
|
|
+ else if (strncasecmp(*comment, "artist=", 7) == 0)
|
|
+ strlcpy(id3tag->artist, *comment + 7, MP3ID3_ARTISTLEN+1);
|
|
+ else if (strncasecmp(*comment, "album=", 6) == 0)
|
|
+ strlcpy(id3tag->album, *comment + 6, MP3ID3_ALBUMLEN+1);
|
|
+ else if (strncasecmp(*comment, "date=", 5) == 0)
|
|
+ strlcpy(id3tag->year, *comment + 5, MP3ID3_YEARLEN+1);
|
|
+ else if (strncasecmp(*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
|