pkgsrc/audio/mserv/patches/patch-af

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