summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Teterin <mi@FreeBSD.org>2010-12-14 06:11:04 +0000
committerMikhail Teterin <mi@FreeBSD.org>2010-12-14 06:11:04 +0000
commit39faccbe393b2c31feb9510072b6407c40952953 (patch)
treeba56637458de9e66a6a66d2b24eebd1f9a58e0b9
parentRemove misc/zaptel port (superseded by misc/dahdi). (diff)
Add the port of minidlna -- the DLNA-speaking service.
(Took me 6 months to come up with the etc/rc.d/ script...)
Notes
Notes: svn path=/head/; revision=266271
-rw-r--r--GIDs1
-rw-r--r--UIDs1
-rw-r--r--net/Makefile1
-rw-r--r--net/minidlna/Makefile49
-rw-r--r--net/minidlna/distinfo2
-rw-r--r--net/minidlna/files/BSDmakefile36
-rw-r--r--net/minidlna/files/config.h34
-rw-r--r--net/minidlna/files/getifaddr.c327
-rw-r--r--net/minidlna/files/minidlna.sh.in34
-rw-r--r--net/minidlna/files/patch-2928850639
-rw-r--r--net/minidlna/files/patch-aa11
-rw-r--r--net/minidlna/files/patch-ab9
-rw-r--r--net/minidlna/files/patch-inline23
-rw-r--r--net/minidlna/files/patch-minidlna.c72
-rw-r--r--net/minidlna/files/patch-upnphttp95
-rw-r--r--net/minidlna/files/pkg-message.in5
-rw-r--r--net/minidlna/files/scandir-patch38
-rw-r--r--net/minidlna/pkg-descr10
-rw-r--r--net/minidlna/pkg-plist4
19 files changed, 1391 insertions, 0 deletions
diff --git a/GIDs b/GIDs
index f7e5b3064996..36c8debe608a 100644
--- a/GIDs
+++ b/GIDs
@@ -180,3 +180,4 @@ activemq:*:929:
ifgraph:*:930:
asterisk:*:931:
sancp:*:932:
+dlna:*:933:
diff --git a/UIDs b/UIDs
index 5da66d910918..28d807600a34 100644
--- a/UIDs
+++ b/UIDs
@@ -188,3 +188,4 @@ activemq:*:929:929::0:0:ActiveMQ Daemon:/nonexistent:/sbin/nologin
ifgraph:*:930:930::0:0:ifGraph:/nonexistent:/sbin/nologin
asterisk:*:931:931::0:0:Asterisk User:/nonexistent:/sbin/nologin
sancp:*:932:932::0:0:SANCP Daemon:/var/log/sancp:/sbin/nologin
+dlna:*:933:933::0:0:DLNA Daemon:/nonexistent:/sbin/nologin
diff --git a/net/Makefile b/net/Makefile
index 65424d5ef1d2..7a62d576df0a 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -376,6 +376,7 @@
SUBDIR += mgen
SUBDIR += micro_inetd
SUBDIR += micro_proxy
+ SUBDIR += minidlna
SUBDIR += minisapserver
SUBDIR += minissdpd
SUBDIR += miniupnpc
diff --git a/net/minidlna/Makefile b/net/minidlna/Makefile
new file mode 100644
index 000000000000..55ca58cab6b3
--- /dev/null
+++ b/net/minidlna/Makefile
@@ -0,0 +1,49 @@
+# New ports collection makefile for: minidlna
+# Date created: 2010-06-13
+# Whom: Mikhail Teterin <mi@aldan.algebra.com>
+#
+# $FreeBSD$
+#
+
+PORTNAME= minidlna
+PORTVERSION= 2010.12.12
+CATEGORIES= net multimedia www
+MASTER_SITES= http://aldan.algebra.com/~mi/
+
+MAINTAINER= mi@aldan.algebra.com
+COMMENT= Media-server compatible with "Digital Life Network Alliance"
+
+LIB_DEPENDS= sqlite3:${PORTSDIR}/databases/sqlite3 \
+ jpeg:${PORTSDIR}/graphics/jpeg \
+ exif:${PORTSDIR}/graphics/libexif \
+ id3tag:${PORTSDIR}/audio/libid3tag \
+ ogg:${PORTSDIR}/audio/libogg \
+ vorbis:${PORTSDIR}/audio/libvorbis \
+ FLAC:${PORTSDIR}/audio/flac \
+ avformat:${PORTSDIR}/multimedia/ffmpeg
+
+USE_XZ= yes
+MAKE_JOBS_SAFE= yes
+MAKEFILE= ${FILESDIR}/BSDmakefile
+NO_WRKSUBDIR= yes
+MAKE_ENV+= FILESDIR="${FILESDIR}" INSTALL_DATA="${INSTALL_DATA}"
+EXTRACT_AFTER_ARGS=|${TAR} -xpf - --exclude getifaddr.c
+
+PKGMESSAGE= ${WRKSRC}/pkg-message
+SUB_FILES+= pkg-message
+USE_RC_SUBR= minidlna.sh
+SUB_LIST+= USER=${USERS}
+
+USERS= dlna
+GROUPS= dlna
+
+post-install:
+ ${FMT} ${PKGMESSAGE}
+
+.include <bsd.port.pre.mk>
+
+.if ${OSVERSION} < 801000
+EXTRA_PATCHES= ${FILESDIR}/scandir-patch
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/net/minidlna/distinfo b/net/minidlna/distinfo
new file mode 100644
index 000000000000..9483112396e7
--- /dev/null
+++ b/net/minidlna/distinfo
@@ -0,0 +1,2 @@
+SHA256 (minidlna-2010.12.12.tar.xz) = 3a2434bacb0f091376f452f2bfc322d61e2c375e476440e1b863e473a5e664e3
+SIZE (minidlna-2010.12.12.tar.xz) = 156524
diff --git a/net/minidlna/files/BSDmakefile b/net/minidlna/files/BSDmakefile
new file mode 100644
index 000000000000..ab8a0128bc29
--- /dev/null
+++ b/net/minidlna/files/BSDmakefile
@@ -0,0 +1,36 @@
+PROG= minidlna
+NO_MAN= Ha-ha...
+
+OS!= uname
+VERS!= uname -r
+
+CFLAGS+=-I${FILESDIR} -I${.CURDIR} -I${LOCALBASE}/include -I${LOCALBASE}/include/ffmpeg
+CFLAGS+=-I${LOCALBASE}/include/libavutil
+CFLAGS+=-DPREFIX='"${PREFIX}"' -DOS='"${OS}"' -DOSVERSION='"${VERS}"'
+CFLAGS+=-Wformat -Werror
+
+LDADD+= -L${LOCALBASE}/lib
+LDADD+= -lsqlite3 -ljpeg -lexif -lid3tag -logg -lvorbis -lFLAC -lavformat
+
+SRCS= albumart.c daemonize.c getifaddr.c image_utils.c log.c \
+ metadata.c minidlna.c minissdp.c minixml.c options.c playlist.c \
+ scanner.c sql.c upnpdescgen.c upnpevents.c upnpglobalvars.c \
+ upnphttp.c upnpreplyparse.c upnpsoap.c utils.c uuid.c
+
+# TiVo-related sources still need massaging to compile on BSD:
+# SRCS+= tivo_beacon.c tivo_commands.c tivo_utils.c
+
+.PATH: ${FILESDIR} ${.CURDIR}/tagutils
+
+SRCS+= misc.c tagutils.c textutils.c
+
+WARNS= 2
+
+BINDIR= ${PREFIX}/sbin
+
+beforeinstall:
+ ${INSTALL_DATA} ${.CURDIR}/minidlna.conf ${PREFIX}/etc/minidlna.conf.sample
+ test -e ${PREFIX}/etc/minidlna.conf || \
+ ${INSTALL_DATA} ${.CURDIR}/minidlna.conf ${PREFIX}/etc/minidlna.conf
+
+.include <bsd.prog.mk>
diff --git a/net/minidlna/files/config.h b/net/minidlna/files/config.h
new file mode 100644
index 000000000000..10b7a3d7f41f
--- /dev/null
+++ b/net/minidlna/files/config.h
@@ -0,0 +1,34 @@
+/* MiniDLNA Project
+ * http://sourceforge.net/projects/minidlna/
+ * (c) 2008-2009 Justin Maggard
+ * generated by ./genconfig.sh on нд 13 чер 2010 00:06:49 EDT */
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define PFRULE_INOUT_COUNTS
+#define OS_NAME OS
+#define OS_VERSION OS "/" OSVERSION
+#define OS_URL "http://www." OS ".org/"
+
+/* full path of the file database */
+#define DEFAULT_DB_PATH "/var/db/minidlna"
+#define DEFAULT_LOG_PATH "/var/log"
+
+/* Comment the following line to use home made daemonize() func instead
+ * of BSD daemon() */
+#define USE_DAEMON
+
+/* Enable if the system inotify.h exists. Otherwise our own inotify.h will be used. */
+/*#define HAVE_INOTIFY_H*/
+
+/* Enable if the system iconv.h exists. ID3 tag reading in various character sets will not work properly otherwise. */
+#define HAVE_ICONV_H
+
+/* Enable NETGEAR-specific tweaks. */
+/*#define NETGEAR*/
+/* Enable ReadyNAS-specific tweaks. */
+/*#define READYNAS*/
+/* Compile in TiVo support. */
+/* #define TIVO_SUPPORT -- not yet ported to FreeBSD */
+
+#endif
diff --git a/net/minidlna/files/getifaddr.c b/net/minidlna/files/getifaddr.c
new file mode 100644
index 000000000000..021512ed1187
--- /dev/null
+++ b/net/minidlna/files/getifaddr.c
@@ -0,0 +1,327 @@
+/* $Id: getifaddr.c,v 1.12 2010/11/11 23:48:13 jmaggard Exp $ */
+/* MiniUPnP project
+ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
+ *
+ * Copyright (c) 2006, Thomas Bernard
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#if defined(sun)
+#include <sys/sockio.h>
+#endif
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <arpa/inet.h>
+#include <net/route.h>
+#include <err.h>
+#include <netinet/if_ether.h>
+
+#include <ifaddrs.h>
+#include <sys/param.h>
+#if defined(BSD) || defined(__APPLE__)
+#include <net/if_dl.h>
+#endif
+#ifdef __linux__
+#define AF_LINK AF_PACKET
+#endif
+
+#include "getifaddr.h"
+#include "log.h"
+
+int
+getifaddr(const char * ifname, char * buf, int len)
+{
+ /* SIOCGIFADDR struct ifreq * */
+ int s;
+ struct ifreq ifr;
+ int ifrlen;
+ struct sockaddr_in * addr;
+ ifrlen = sizeof(ifr);
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if(s < 0)
+ {
+ DPRINTF(E_ERROR, L_GENERAL, "socket(PF_INET, SOCK_DGRAM): %s\n", strerror(errno));
+ return -1;
+ }
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ if(ioctl(s, SIOCGIFADDR, &ifr, &ifrlen) < 0)
+ {
+ DPRINTF(E_ERROR, L_GENERAL, "ioctl(s, SIOCGIFADDR, ...): %s\n", strerror(errno));
+ close(s);
+ return -1;
+ }
+ addr = (struct sockaddr_in *)&ifr.ifr_addr;
+ if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
+ {
+ DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
+ close(s);
+ return -1;
+ }
+ close(s);
+ return 0;
+}
+
+#if 0
+int
+getsysaddr(char * buf, int len)
+{
+ int i;
+ int s = socket(PF_INET, SOCK_STREAM, 0);
+ struct sockaddr_in addr;
+ struct ifreq ifr;
+ int ret = -1;
+
+ for (i=1; i > 0; i++)
+ {
+ // de hack: uncomment this out: ifr.ifr_ifindex = i;
+ if( ioctl(s, SIOCGIFNAME, &ifr) < 0 )
+ break;
+ if(ioctl(s, SIOCGIFADDR, &ifr, sizeof(struct ifreq)) < 0)
+ continue;
+ memcpy(&addr, &ifr.ifr_addr, sizeof(addr));
+ if(strncmp(inet_ntoa(addr.sin_addr), "127.", 4) == 0)
+ continue;
+ if(!inet_ntop(AF_INET, &addr.sin_addr, buf, len))
+ {
+ DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
+ close(s);
+ break;
+ }
+ ret = 0;
+ break;
+ }
+ close(s);
+
+ return(ret);
+}
+#else
+int
+getsysaddr(char * buf, int len) {
+ int rv=-1;
+ struct ifaddrs * ifap = 0;
+
+ int res = getifaddrs( & ifap );
+ if ( 0 != res ) {
+ printf( "%s\n", strerror( errno ) );
+ exit( -1 );
+ }
+
+ struct ifaddrs *ifnr;
+ for (ifnr = ifap; ( void * ) 0 != ifnr; ifnr = ifnr->ifa_next ) {
+ if ( AF_INET == ifnr->ifa_addr->sa_family ) {
+ struct sockaddr_in *addr_in = ( struct sockaddr_in * ) ifnr->ifa_addr;
+
+ unsigned a = ( htonl( addr_in->sin_addr.s_addr ) >> 0x18 ) & 0xFF;
+ if (a==127) continue;
+
+ if(!inet_ntop(AF_INET, &addr_in->sin_addr, buf, len)) {
+ printf("inet_ntop(): %s\n", strerror(errno));
+ break;
+ }
+
+ rv=0;
+ break;
+ }
+ rv=0;
+ }
+
+ freeifaddrs( ifap );
+ return rv;
+}
+#endif
+
+int
+getsysifname(char * buf, size_t len) {
+ int rv=-1;
+ struct ifaddrs * ifap = 0;
+
+ int res = getifaddrs( & ifap );
+ if ( 0 != res ) {
+ printf( "%s\n", strerror( errno ) );
+ exit( -1 );
+ }
+
+ struct ifaddrs *ifnr;
+ for (ifnr = ifap; ( void * ) 0 != ifnr; ifnr = ifnr->ifa_next ) {
+ if ( AF_INET == ifnr->ifa_addr->sa_family ) {
+ char *ifname=ifnr->ifa_name;
+ struct sockaddr_in *addr_in = ( struct sockaddr_in * ) ifnr->ifa_addr;
+
+ unsigned a = ( htonl( addr_in->sin_addr.s_addr ) >> 0x18 ) & 0xFF;
+ if (a==127) continue;
+
+ if(!inet_ntop(AF_INET, &addr_in->sin_addr, buf, len)) {
+ printf("inet_ntop(): %s\n", strerror(errno));
+ break;
+ }
+
+ rv=0;
+ strncpy(buf, ifname, len);
+ break;
+ }
+ rv=0;
+ }
+
+ freeifaddrs( ifap );
+
+ return rv;
+}
+
+int
+getsyshwaddr(char *buf, int len)
+{
+ struct ifaddrs *ifap;
+ char sysifname[256];
+ int rv=-1;
+ uint8_t node[6];
+
+ getsysifname(sysifname, sizeof(sysifname));
+ if (getifaddrs(&ifap) == 0) {
+ struct ifaddrs *p;
+ for (p = ifap; p; p = p->ifa_next) {
+ if (p->ifa_addr->sa_family == AF_LINK) {
+ char *ifname=p->ifa_name;
+ if(strncmp(sysifname, ifname, sizeof(sysifname))) continue;
+#ifdef __linux__
+ // Linux
+ struct ifreq ifr;
+
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ ifr.ifr_addr.sa_family = AF_INET;
+ strcpy(ifr.ifr_name, ifname);
+ ioctl(fd, SIOCGIFHWADDR, &ifr);
+ close(fd);
+
+ memcpy(node, ifr.ifr_hwaddr.sa_data, 6);
+#else
+ struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
+ memcpy(node, sdp->sdl_data + sdp->sdl_nlen, 6);
+#endif
+ if(len>12)
+ sprintf(buf, "%02x%02x%02x%02x%02x%02x", node[0], node[1], node[2], node[3], node[4], node[5]);
+ else
+ memmove(buf, node, 6);
+ rv=0;
+ break;
+ }
+ }
+ freeifaddrs(ifap);
+ }
+ return rv;
+}
+
+#ifdef __linux__
+int
+get_remote_mac(struct in_addr ip_addr, unsigned char * mac)
+{
+ struct in_addr arp_ent;
+ FILE * arp;
+ char remote_ip[16];
+ int matches, hwtype, flags;
+ memset(mac, 0xFF, 6);
+
+ arp = fopen("/proc/net/arp", "r");
+ if( !arp )
+ return 1;
+ while( !feof(arp) )
+ {
+ matches = fscanf(arp, "%s 0x%X 0x%X %hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ remote_ip, &hwtype, &flags,
+ &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
+ if( matches != 9 )
+ continue;
+ inet_pton(AF_INET, remote_ip, &arp_ent);
+ if( ip_addr.s_addr == arp_ent.s_addr )
+ break;
+ mac[0] = 0xFF;
+ }
+ fclose(arp);
+
+ if( mac[0] == 0xFF )
+ {
+ memset(mac, 0xFF, 6);
+ return 1;
+ }
+
+ return 0;
+}
+#else
+int
+get_remote_mac(struct in_addr ip_addr, unsigned char *mac)
+{
+ int found_entry=0;
+ int mib[6];
+ size_t needed;
+ char *lim, *buf, *next;
+ struct rt_msghdr *rtm;
+ struct sockaddr_inarp *sin;
+ struct sockaddr_dl *sdl;
+ extern int h_errno;
+
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0;
+ mib[3] = AF_INET;
+ mib[4] = NET_RT_FLAGS;
+ mib[5] = RTF_LLINFO;
+ if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+ err(1, "route-sysctl-estimate");
+ if ((buf = malloc(needed)) == NULL)
+ err(1, "malloc");
+ if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
+ err(1, "actual retrieval of routing table");
+ lim = buf + needed;
+ for (next = buf; next < lim; next += rtm->rtm_msglen) {
+ rtm = (struct rt_msghdr *)next;
+ sin = (struct sockaddr_inarp *)(rtm + 1);
+ sdl = (struct sockaddr_dl *)(sin + 1);
+ if (ip_addr.s_addr != sin->sin_addr.s_addr)
+ continue;
+ if (sdl->sdl_alen) {
+ found_entry = 1;
+ memmove(mac, (u_char *)LLADDR(sdl), 6);
+ break;
+ }
+ }
+ if(!found_entry) memset(mac, 0xFF, 6);
+ //free(buf);
+ return !found_entry;
+}
+#endif
diff --git a/net/minidlna/files/minidlna.sh.in b/net/minidlna/files/minidlna.sh.in
new file mode 100644
index 000000000000..f49a950decde
--- /dev/null
+++ b/net/minidlna/files/minidlna.sh.in
@@ -0,0 +1,34 @@
+#!/bin/sh
+# $FreeBSD$
+#
+# PROVIDE: minidlna
+# REQUIRE: DAEMON
+#
+# Add the following line to /etc/rc.conf[.local] to enable minidlna:
+#
+# minidlna_enable="YES"
+#
+
+. /etc/rc.subr
+
+minidlna_enable=${minidlna_enable-"NO"}
+minidlna_uid=${minidlna_uid-"%%USER%%"}
+
+name=minidlna
+rcvar=`set_rcvar`
+command=%%PREFIX%%/sbin/minidlna
+
+pidfile="/var/run/minidlna.pid"
+
+start_precmd=rmpid
+stop_postcmd=rmpid
+rmpid()
+{
+ rm -f $pidfile
+}
+
+load_rc_config $name
+command_args="$command_args -P $pidfile -u $minidlna_uid"
+required_dirs="/var/db/minidlna"
+
+run_rc_command $1
diff --git a/net/minidlna/files/patch-2928850 b/net/minidlna/files/patch-2928850
new file mode 100644
index 000000000000..b6831fbde0a4
--- /dev/null
+++ b/net/minidlna/files/patch-2928850
@@ -0,0 +1,639 @@
+Based on patch by jayp from:
+
+ http://sourceforge.net/tracker/?func=detail&aid=2989136&group_id=243163&atid=1121518
+
+with some modifications...
+
+--- TODO 25 Feb 2009 21:16:51 -0000 1.5
++++ TODO 9 Jan 2010 13:19:49 -0000
+@@ -7,3 +7,7 @@
+
+ Wishlist:
+ * Transcoding
++
++Dominik:
++* send buffer size needs optimizations
++* inotify stuff
+--- albumart.c 19 Nov 2009 03:22:35 -0000 1.24
++++ albumart.c 9 Jan 2010 13:19:49 -0000
+@@ -21,6 +21,10 @@
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
++#include <sys/param.h>
++#if defined(__APPLE__) || defined(BSD)
++#include <sys/limits.h>
++#endif
+ #include <libgen.h>
+ #include <setjmp.h>
+ #include <errno.h>
+@@ -37,7 +41,11 @@
+ int
+ art_cache_exists(const char * orig_path, char ** cache_file)
+ {
+- asprintf(cache_file, "%s/art_cache%s", db_path, orig_path);
++ int ret=asprintf(cache_file, "%s/art_cache%s", db_path, orig_path);
++ if( ret == -1 ) {
++ DPRINTF(E_DEBUG, L_METADATA, "asprintf error :: error no. %d [%s]\n", errno, strerror(errno));
++ return -1;
++ }
+ strcpy(strchr(*cache_file, '\0')-4, ".jpg");
+
+ return (!access(*cache_file, F_OK));
+@@ -130,7 +138,8 @@
+ break;
+ }
+
+- dir = dirname(strdup(path));
++ char *pathdup=strdup(path);
++ dir = dirname(pathdup);
+ dh = opendir(dir);
+ if( !dh )
+ return;
+@@ -143,7 +152,10 @@
+ break;
+ case DT_LNK:
+ case DT_UNKNOWN:
+- asprintf(&file, "%s/%s", dir, dp->d_name);
++ if(-1==asprintf(&file, "%s/%s", dir, dp->d_name)) {
++ DPRINTF(E_DEBUG, L_METADATA, "asprintf error :: error no. %d [%s]\n", errno, strerror(errno));
++ return;
++ }
+ type = resolve_unknown_type(file, ALL_MEDIA);
+ free(file);
+ break;
+@@ -158,7 +170,9 @@
+ (album_art_name || strncmp(dp->d_name, match, ncmp) == 0) )
+ {
+ DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like cover art for %s\n", path, dp->d_name);
+- asprintf(&file, "%s/%s", dir, dp->d_name);
++ if(-1==asprintf(&file, "%s/%s", dir, dp->d_name)) {
++ DPRINTF(E_DEBUG, L_METADATA, "asprintf error :: error no. %d [%s]\n", errno, strerror(errno));
++ }
+ art_id = find_album_art(file, NULL, 0);
+ if( sql_exec(db, "UPDATE DETAILS set ALBUM_ART = %lld where PATH = '%q'", art_id, file) != SQLITE_OK )
+ DPRINTF(E_WARN, L_METADATA, "Error setting %s as cover art for %s\n", match, dp->d_name);
+@@ -167,7 +181,7 @@
+ }
+ closedir(dh);
+
+- free(dir);
++ free(pathdup);
+ free(match);
+ }
+
+--- image_utils.c 6 Nov 2009 19:03:55 -0000 1.10
++++ image_utils.c 9 Jan 2010 13:19:49 -0000
+@@ -33,7 +33,11 @@
+ #include <sys/types.h>
+ #include <setjmp.h>
+ #include <jpeglib.h>
++#ifdef __linux__
+ #include <endian.h>
++#else
++#include <machine/endian.h>
++#endif
+
+ #include "upnpreplyparse.h"
+ #include "image_utils.h"
+--- metadata.c 10 Nov 2009 20:11:50 -0000 1.52
++++ metadata.c 9 Jan 2010 13:19:49 -0000
+@@ -25,6 +25,7 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
++#include <libgen.h>
+
+ #include <libexif/exif-loader.h>
+ #include "image_utils.h"
+@@ -616,7 +617,7 @@
+ {
+ av_close_input_file(ctx);
+ if( !is_audio(path) )
+- DPRINTF(E_DEBUG, L_METADATA, "File %s does not contain a video stream.\n", basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "File %s does not contain a video stream.\n", basename((char*)path));
+ return 0;
+ }
+ if( audio_stream >= 0 )
+@@ -709,7 +710,7 @@
+ }
+ if( video_stream >= 0 )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "Container: '%s' [%s]\n", ctx->iformat->name, basename((char*)path));
+ asprintf(&m.resolution, "%dx%d", ctx->streams[video_stream]->codec->width, ctx->streams[video_stream]->codec->height);
+ if( ctx->bit_rate > 8 )
+ asprintf(&m.bitrate, "%u", ctx->bit_rate / 8);
+@@ -738,7 +739,7 @@
+ case CODEC_ID_MPEG2VIDEO:
+ if( strcmp(ctx->iformat->name, "mpegts") == 0 )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, basename(path), m.resolution);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS\n", video_stream, basename((char*)path), m.resolution);
+ char res;
+ tsinfo_t * ts = ctx->priv_data;
+ if( ts->packet_size == 192 )
+@@ -759,7 +760,7 @@
+ }
+ else if( strcmp(ctx->iformat->name, "mpeg") == 0 )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, basename(path), m.resolution);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 PS\n", video_stream, basename((char*)path), m.resolution);
+ char region[5];
+ if( (ctx->streams[video_stream]->codec->height == 576) ||
+ (ctx->streams[video_stream]->codec->height == 288) )
+@@ -771,7 +772,7 @@
+ }
+ else
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [UNKNOWN CONTAINER] is %s MPEG2\n", video_stream, basename(path), m.resolution);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [UNKNOWN CONTAINER] is %s MPEG2\n", video_stream, basename((char*)path), m.resolution);
+ }
+ break;
+ case CODEC_ID_H264:
+@@ -811,7 +812,7 @@
+ ts_timestamp==NONE?"_ISO" : ts_timestamp==VALID?"_T":"", dlna_no_conv);
+ break;
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for TS/AVC/%cD file %s\n", res, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for TS/AVC/%cD file %s\n", res, basename((char*)path));
+ break;
+ }
+ if( m.dlna_pn && (ts_timestamp != NONE) )
+@@ -842,27 +843,27 @@
+ asprintf(&m.dlna_pn, "AVC_MP4_MP_SD_AAC_MULT5;%s", dlna_no_conv);
+ break;
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MP4/AVC/SD file %s\n", basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MP4/AVC/SD file %s\n", basename((char*)path));
+ break;
+ }
+ }
+ }
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is h.264\n", video_stream, basename((char*)path));
+ break;
+ case CODEC_ID_MPEG4:
+ if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("XVID") )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s XViD\n", video_stream, basename(path), m.resolution);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s XViD\n", video_stream, basename((char*)path), m.resolution);
+ asprintf(&m.artist, "DiVX");
+ }
+ else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DX50") )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s DiVX5\n", video_stream, basename(path), m.resolution);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s DiVX5\n", video_stream, basename((char*)path), m.resolution);
+ asprintf(&m.artist, "DiVX");
+ }
+ else if( ctx->streams[video_stream]->codec->codec_tag == get_fourcc("DIVX") )
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is DiVX\n", video_stream, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is DiVX\n", video_stream, basename((char*)path));
+ asprintf(&m.artist, "DiVX");
+ }
+ else if( ends_with(path, ".3gp") && (strcmp(ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0) )
+@@ -878,18 +879,18 @@
+ break;
+ default:
+ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n",
+- ctx->streams[audio_stream]->codec->codec_id, basename(path));
++ ctx->streams[audio_stream]->codec->codec_id, basename((char*)path));
+ break;
+ }
+ }
+ else
+ {
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%X]\n", video_stream, basename(path), ctx->streams[video_stream]->codec->codec_tag);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%X]\n", video_stream, basename((char*)path), ctx->streams[video_stream]->codec->codec_tag);
+ }
+ break;
+ case CODEC_ID_WMV3:
+ case CODEC_ID_VC1:
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is VC1\n", video_stream, basename((char*)path));
+ char profile[5]; profile[0] = '\0';
+ asprintf(&m.mime, "video/x-ms-wmv");
+ if( (ctx->streams[video_stream]->codec->width <= 352) &&
+@@ -905,7 +906,7 @@
+ asprintf(&m.dlna_pn, "WMVSPML_BASE;%s", dlna_no_conv);
+ break;
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", audio_profile, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", audio_profile, basename((char*)path));
+ break;
+ }
+ }
+@@ -925,7 +926,7 @@
+ asprintf(&m.dlna_pn, "WMVMED_BASE;%s", dlna_no_conv);
+ break;
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", audio_profile, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", audio_profile, basename((char*)path));
+ break;
+ }
+ }
+@@ -942,7 +943,7 @@
+ asprintf(&m.dlna_pn, "WMVHIGH_FULL;%s", dlna_no_conv);
+ break;
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", audio_profile, basename(path));
++ DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", audio_profile, basename((char*)path));
+ break;
+ }
+ }
+@@ -950,7 +951,7 @@
+ case CODEC_ID_MSMPEG4V3:
+ asprintf(&m.mime, "video/x-msvideo");
+ default:
+- DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", video_stream, basename(path), m.resolution, ctx->streams[video_stream]->codec->codec_id);
++ DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s [type %d]\n", video_stream, basename((char*)path), m.resolution, ctx->streams[video_stream]->codec->codec_id);
+ break;
+ }
+ }
+--- minidlna.c 19 Nov 2009 03:22:35 -0000 1.55
++++ minidlna.c 9 Jan 2010 13:19:49 -0000
+@@ -13,6 +13,7 @@
+ #include <string.h>
+ #include <stdio.h>
+ #include <ctype.h>
++#include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+@@ -652,7 +653,7 @@
+ }
+
+ /* set signal handler */
+- signal(SIGCLD, SIG_IGN);
++ signal(SIGCHLD, SIG_IGN);
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = sigterm;
+ if (sigaction(SIGTERM, &sa, NULL))
+@@ -725,7 +726,8 @@
+ {
+ updateID = sql_get_int_field(db, "SELECT UPDATE_ID from SETTINGS");
+ }
+- if( sql_get_int_field(db, "pragma user_version") != DB_VERSION )
++ int user_version=sql_get_int_field(db, "pragma user_version");
++ if( user_version != DB_VERSION )
+ {
+ if( new_db )
+ {
+@@ -733,7 +735,7 @@
+ }
+ else
+ {
+- DPRINTF(E_WARN, L_GENERAL, "Database version mismatch; need to recreate...\n");
++ DPRINTF(E_WARN, L_GENERAL, "Database version mismatch: user_version is %d, DB_VERSION is %d; need to recreate...\n", user_version, DB_VERSION);
+ }
+ sqlite3_close(db);
+ char *cmd;
+--- minidlna.conf 19 Nov 2009 03:22:35 -0000 1.14
++++ minidlna.conf 9 Jan 2010 13:19:49 -0000
+@@ -11,13 +11,14 @@
+ # + "A" for audio (eg. media_dir=A,/home/jmaggard/Music)
+ # + "V" for video (eg. media_dir=V,/home/jmaggard/Videos)
+ # + "P" for images (eg. media_dir=P,/home/jmaggard/Pictures)
+-media_dir=/opt
++media_dir=/Volumes/Data/dominik/Filme/minidlna
++#media_dir=/Volumes/Data/dominik/Unfug
+
+ # set this if you want to customize the name that shows up on your clients
+-#friendly_name=My DLNA Server
++friendly_name=sesam minidlna
+
+ # set this if you would like to specify the directory where you want MiniDLNA to store its database and album art cache
+-#db_dir=/var/cache/minidlna
++db_dir=/var/db/minidlna
+
+ # this should be a list of file names to check for when searching for album art
+ # note: names should be delimited with a forward slash ("/")
+@@ -25,7 +26,7 @@
+
+ # set this to no to disable inotify monitoring to automatically discover new files
+ # note: the default is yes
+-inotify=yes
++inotify=no
+
+ # set this to yes to enable support for streaming .jpg and .mp3 files to a TiVo supporting HMO
+ enable_tivo=no
+--- scanner.c 17 Nov 2009 19:13:00 -0000 1.53
++++ scanner.c 9 Jan 2010 13:19:49 -0000
+@@ -25,6 +25,10 @@
+ #include <sys/stat.h>
+ #include <sys/time.h>
+ #include <sys/resource.h>
++#include <sys/param.h>
++#if defined(__APPLE__) || defined(BSD)
++#include <sys/limits.h>
++#endif
+
+ #include <sqlite3.h>
+
+@@ -399,8 +403,8 @@
+
+ if( refID )
+ {
+- dir = strdup(path);
+- dir = dirname(dir);
++ char *pathdup = strdup(path);
++ dir = dirname(pathdup);
+ asprintf(&id_buf, "%s%s$%X", base, parentID, objectID);
+ asprintf(&parent_buf, "%s%s", base, parentID);
+ while( !found )
+@@ -436,7 +440,7 @@
+ free(refID);
+ free(parent_buf);
+ free(id_buf);
+- free(dir);
++ free(pathdup);
+ return 1;
+ }
+
+@@ -779,13 +783,15 @@
+ if( flag )
+ fclose(flag);
+ #endif
+- freopen("/dev/null", "a", stderr);
++ // TAG_CHANGED_UPSTREAM_CODE_SEMANTICALLY
++ //int saved_stderr=dup(2);
++ //freopen("/dev/null", "a", stderr);
+ while( media_path )
+ {
+ ScanDirectory(media_path->path, NULL, media_path->type);
+ media_path = media_path->next;
+ }
+- freopen("/proc/self/fd/2", "a", stderr);
++ //dup2(saved_stderr, 2);
+ #ifdef READYNAS
+ if( access("/ramfs/.rescan_done", F_OK) == 0 )
+ system("/bin/sh /ramfs/.rescan_done");
+--- upnpglobalvars.c 19 Nov 2009 03:22:35 -0000 1.14
++++ upnpglobalvars.c 9 Jan 2010 13:19:49 -0000
+@@ -12,7 +12,11 @@
+ */
+ #include <sys/types.h>
+ #include <netinet/in.h>
++#ifdef __linux__
+ #include <linux/limits.h>
++#else
++#include <limits.h>
++#endif
+
+ #include "config.h"
+ #include "upnpglobalvars.h"
+@@ -22,6 +26,9 @@
+
+ /* startup time */
+ time_t startup_time = 0;
++#ifdef __APPLE__
++unsigned long long startup_time_ns = 0;
++#endif
+
+ struct runtime_vars_s runtime_vars;
+ int runtime_flags = INOTIFY_MASK;
+--- upnpglobalvars.h 19 Nov 2009 03:22:35 -0000 1.44
++++ upnpglobalvars.h 9 Jan 2010 13:19:49 -0000
+@@ -14,7 +14,13 @@
+ #define __UPNPGLOBALVARS_H__
+
+ #include <time.h>
++#ifdef HAVE_LINUX_TYPES_H
+ #include <linux/types.h> // Defines __u32
++#else
++#include <sys/types.h>
++typedef u_int32_t __u32;
++typedef int32_t __s32;
++#endif
+
+ #include "minidlnatypes.h"
+ #include "config.h"
+@@ -79,6 +85,7 @@
+
+ /* statup time */
+ extern time_t startup_time;
++extern unsigned long long startup_time_ns;
+
+ extern struct runtime_vars_s runtime_vars;
+ /* runtime boolean flags */
+--- upnpsoap.c 17 Dec 2009 18:55:44 -0000 1.64
++++ upnpsoap.c 9 Jan 2010 13:19:50 -0000
+@@ -1136,14 +1136,6 @@
+ newSearchCriteria = modifyString(strdup(SearchCriteria), "@id", "OBJECT_ID", 0);
+ SearchCriteria = newSearchCriteria;
+ }
+- if( strstr(SearchCriteria, "res is ") )
+- {
+- if( newSearchCriteria )
+- newSearchCriteria = modifyString(newSearchCriteria, "res is ", "MIME is ", 0);
+- else
+- newSearchCriteria = modifyString(strdup(SearchCriteria), "res is ", "MIME is ", 0);
+- SearchCriteria = newSearchCriteria;
+- }
+ #if 0 // Does 360 need this?
+ if( strstr(SearchCriteria, "&amp;") )
+ {
+--- utils.c 25 Nov 2009 00:03:09 -0000 1.19
++++ utils.c 9 Jan 2010 13:19:50 -0000
+@@ -19,7 +19,11 @@
+ #include <ctype.h>
+ #include <string.h>
+ #include <stdlib.h>
++#ifdef __linux
+ #include <linux/limits.h>
++#else
++#include <limits.h>
++#endif
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+@@ -187,7 +191,7 @@
+ if (mkdir(path, mode) < 0) {
+ /* If we failed for any other reason than the directory
+ * already exists, output a diagnostic and return -1.*/
+- if (errno != EEXIST
++ if ( (errno != EEXIST && errno != EISDIR)
+ || (stat(path, &st) < 0 || !S_ISDIR(st.st_mode))) {
+ break;
+ }
+@@ -200,7 +204,7 @@
+
+ } while (1);
+
+- DPRINTF(E_WARN, L_GENERAL, "make_dir: cannot create directory '%s'\n", path);
++ DPRINTF(E_WARN, L_GENERAL, "make_dir: cannot create directory '%s'. errno=%d, error=%s\n", path, errno, strerror(errno));
+ return -1;
+ }
+
+--- uuid.c 28 Oct 2009 19:26:38 -0000 1.4
++++ uuid.c 9 Jan 2010 13:19:50 -0000
+@@ -11,34 +11,86 @@
+ */
+ #include <stdio.h>
+ #include <stdlib.h>
+-#include <time.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <string.h>
+-#include <net/if.h>
+ #include <sys/ioctl.h>
+-#include <sys/time.h>
++#include <sys/param.h>
+ #include <errno.h>
++#if defined(__APPLE__) || defined(BSD)
++#include <sys/socket.h>
++#endif
++
++#include <net/if.h>
++
++#if defined __linux__
++#include <time.h>
++#elif defined(__APPLE__)
++#include <sys/time.h>
++#include <mach/mach_time.h>
++#elif defined BSD
++#include <sys/time.h>
++#include <sys/timespec.h>
++#endif
+
+ #include "getifaddr.h"
+ #include "log.h"
+
+ #define ETH_ALEN 6
++#ifdef NSEC_PER_SEC
++#undef NSEC_PER_SEC
+ #define NSEC_PER_SEC 1000000000L
++#endif
+ #define NSEC_PER_MSEC 1000000L
+
+ static u_int32_t clock_seq;
+ static const u_int32_t clock_seq_max = 0x3fff; /* 14 bits */
+ static int clock_seq_initialized;
+
+-unsigned long long
+-monotonic_us(void)
+-{
+- struct timespec ts;
+-
+- syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts);
+- return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
++u_int64_t clocktime_ns() {
++#ifdef __APPLE__
++ u_int64_t tm;
++
++ static mach_timebase_info_data_t timebase_info= {0,0};
++ if (timebase_info.denom == 0) (void) mach_timebase_info(&timebase_info);
++
++ static u_int64_t startup_time_usec=0;
++ static u_int64_t startup_time_nsec=0;
++ if (startup_time_usec==0) {
++ struct timeval tp;
++ gettimeofday(&tp, 0);
++ startup_time_usec = tp.tv_sec * 1000000ULL + tp.tv_usec;
++ tm=mach_absolute_time();
++ startup_time_nsec = (tm * timebase_info.numer) / timebase_info.denom;
++ }
++ tm=mach_absolute_time();
++ return (tm * timebase_info.numer) / timebase_info.denom - startup_time_nsec + 1000ULL * startup_time_usec;
++#elif defined(BSD) || defined(__linux__)
++ struct timespec ts;
++ clock_gettime(CLOCK_REALTIME, &ts); // Works on Linux
++ return ts.tv_sec*1000000000ULL+ts.tv_nsec;
++#else
++#error unsupported OS for clocktime_ns, please port or bug report.
++#endif
++}
++
++u_int64_t monotonic_ns() {
++#ifdef __APPLE__
++ u_int64_t tm;
++
++ static mach_timebase_info_data_t timebase_info= {0,0};
++ if (timebase_info.denom == 0) (void) mach_timebase_info(&timebase_info);
++
++ tm=mach_absolute_time();
++ return (tm * timebase_info.numer) / timebase_info.denom;
++#elif defined(BSD) || defined(__linux__)
++ struct timespec ts;
++ clock_gettime(CLOCK_MONOTONIC, &ts);
++ return ts.tv_sec*1000000000ULL+ts.tv_nsec;
++#else
++#error unsupported OS for clocktime_ns, please port or bug report.
++#endif
+ }
+
+ int
+@@ -79,7 +131,7 @@
+ /* Paranoia. /dev/urandom may be missing.
+ * rand() is guaranteed to generate at least [0, 2^15) range,
+ * but lowest bits in some libc are not so "random". */
+- srand(monotonic_us());
++ srand(monotonic_ns());
+ pid = getpid();
+ while(1)
+ {
+@@ -110,7 +162,6 @@
+ static unsigned int clock_seq_started;
+ static char last_node[6] = { 0, 0, 0, 0, 0, 0 };
+
+- struct timespec ts;
+ u_int64_t time_all;
+ int inc_clock_seq = 0;
+
+@@ -148,10 +199,9 @@
+ * nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of
+ * Gregorian reform to the Christian calendar).
+ */
+- syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts);
+- time_all = ((u_int64_t)ts.tv_sec) * (NSEC_PER_SEC / 100);
+- time_all += ts.tv_nsec / 100;
+
++ // time in (100ns) since 1970
++ time_all = clocktime_ns()/100;
+ /* add offset from Gregorian Calendar to Jan 1 1970 */
+ time_all += 12219292800000ULL * (NSEC_PER_MSEC / 100);
+ time_all &= 0x0fffffffffffffffULL; /* limit to 60 bits */
+--- tagutils/misc.c 25 Feb 2009 21:16:51 -0000 1.1
++++ tagutils/misc.c 9 Jan 2010 13:19:50 -0000
+@@ -22,7 +22,11 @@
+
+ #include <stdio.h>
+ #include <string.h>
++#ifdef __linux__
+ #include <endian.h>
++#else
++#include <machine/endian.h>
++#endif
+
+ #include "misc.h"
+
+--- tagutils/tagutils-asf.h 25 Feb 2009 21:16:51 -0000 1.1
++++ tagutils/tagutils-asf.h 9 Jan 2010 13:19:50 -0000
+@@ -24,7 +24,11 @@
+
+ #define __PACKED__ __attribute__((packed))
+
++#ifdef __linux__
+ #include <endian.h>
++#else
++#include <machine/endian.h>
++#endif
+
+ typedef struct _GUID {
+ __u32 l;
+--- tagutils/tagutils-mp3.c 27 May 2009 23:09:11 -0000 1.5
++++ tagutils/tagutils-mp3.c 9 Jan 2010 13:19:50 -0000
+@@ -25,6 +25,11 @@
+ * This file is derived from mt-daap project.
+ */
+
++#ifdef __APPLE__
++// detue: recheck this on osx: on linux, it makes compilation break oO
++#include <libgen.h>
++#endif
++
+ static int
+ _get_mp3tags(char *file, struct song_metadata *psong)
+ {
diff --git a/net/minidlna/files/patch-aa b/net/minidlna/files/patch-aa
new file mode 100644
index 000000000000..c3c8157567fe
--- /dev/null
+++ b/net/minidlna/files/patch-aa
@@ -0,0 +1,11 @@
+--- tagutils/tagutils.c 2010-12-13 01:41:52.000000000 -0500
++++ tagutils/tagutils.c 2010-12-13 17:28:29.000000000 -0500
+@@ -36,6 +36,7 @@
+ #include <vorbis/codec.h>
+ #include <FLAC/metadata.h>
++#include <libgen.h>
+
+-#include "../config.h"
++#include "config.h"
+ #ifdef HAVE_ICONV_H
+ #include <iconv.h>
diff --git a/net/minidlna/files/patch-ab b/net/minidlna/files/patch-ab
new file mode 100644
index 000000000000..f02c0ee6c4ba
--- /dev/null
+++ b/net/minidlna/files/patch-ab
@@ -0,0 +1,9 @@
+--- tagutils/tagutils-misc.c 2010-12-13 01:41:52.000000000 -0500
++++ tagutils/tagutils-misc.c 2010-12-13 17:31:49.000000000 -0500
+@@ -34,5 +34,5 @@
+ static iconv_result
+ do_iconv(const char* to_ces, const char* from_ces,
+- char *inbuf, size_t inbytesleft,
++ const char *inbuf, size_t inbytesleft,
+ char *outbuf_orig, size_t outbytesleft_orig)
+ {
diff --git a/net/minidlna/files/patch-inline b/net/minidlna/files/patch-inline
new file mode 100644
index 000000000000..370a5942ca21
--- /dev/null
+++ b/net/minidlna/files/patch-inline
@@ -0,0 +1,23 @@
+--- tagutils/misc.h 2009-02-25 16:16:51.000000000 -0500
++++ tagutils/misc.h 2010-07-08 07:30:12.000000000 -0400
+@@ -38,13 +38,12 @@
+ #endif
+
++__u16 le16_to_cpu(__u16 le16);
++__u32 le32_to_cpu(__u32 le32);
++__u64 le64_to_cpu(__u64 le64);
++__u8 fget_byte(FILE *fp);
++__u16 fget_le16(FILE *fp);
++__u32 fget_le32(FILE *fp);
+
+-inline __u16 le16_to_cpu(__u16 le16);
+-inline __u32 le32_to_cpu(__u32 le32);
+-inline __u64 le64_to_cpu(__u64 le64);
+-inline __u8 fget_byte(FILE *fp);
+-inline __u16 fget_le16(FILE *fp);
+-inline __u32 fget_le32(FILE *fp);
+-
+-inline __u32 cpu_to_be32(__u32 cpu32);
++__u32 cpu_to_be32(__u32 cpu32);
+
+ extern char * sha1_hex(char *key);
diff --git a/net/minidlna/files/patch-minidlna.c b/net/minidlna/files/patch-minidlna.c
new file mode 100644
index 000000000000..8e5a64e32740
--- /dev/null
+++ b/net/minidlna/files/patch-minidlna.c
@@ -0,0 +1,72 @@
+--- minidlna.c 2010-12-14 00:35:56.000000000 -0500
++++ minidlna.c 2010-12-14 00:38:02.000000000 -0500
+@@ -67,4 +67,8 @@
+ #include <pwd.h>
+
++#include <err.h>
++#include <stdint.h>
++#include <sysexits.h>
++
+ #include "config.h"
+
+@@ -282,5 +286,5 @@
+ /*const char * logfilename = 0;*/
+ const char * presurl = 0;
+- const char * optionsfile = "/etc/minidlna.conf";
++ const char * optionsfile = PREFIX "/etc/minidlna.conf";
+ char mac_str[13];
+ char * string, * word;
+@@ -289,4 +293,5 @@
+ char real_path[PATH_MAX];
+ char ext_ip_addr[INET_ADDRSTRLEN] = {'\0'};
++ uid_t uid = (uid_t)-1;
+
+ /* first check if "-f" option is used */
+@@ -617,4 +622,21 @@
+ exit(0);
+ break;
++ case 'u':
++ if(i+1 == argc)
++ err(EX_USAGE, "Option -%c takes one argument.", argv[i][1]);
++ else {
++ char *endp;
++ i++;
++ uid = strtol(argv[i], &endp, 0);
++ if (*endp) {
++ /* Symbolic username given, not UID. */
++ struct passwd *entry = getpwnam(argv[i]);
++
++ if (entry == NULL)
++ err(EX_NOUSER, "%s", argv[i]);
++ uid = entry->pw_uid;
++ }
++ }
++ break;
+ default:
+ fprintf(stderr, "Unknown option: %s\n", argv[i]);
+@@ -644,4 +666,5 @@
+ "\t\t[-s serial] [-m model_number] \n"
+ "\t\t[-t notify_interval] [-P pid_filename]\n"
++ "\t\t[-u uid_to_run_as]\n"
+ "\t\t[-w url] [-R] [-V] [-h]\n"
+ "\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
+@@ -725,4 +748,7 @@
+ writepidfile(pidfilename, pid);
+
++ if (uid != (uid_t)-1 && setuid(uid) == -1)
++ err(EX_NOPERM, "setuid(%ld)", (long)uid);
++
+ return 0;
+ }
+@@ -841,4 +867,5 @@
+ #endif
+ }
++#if defined(__linux__)
+ if( sqlite3_threadsafe() && sqlite3_libversion_number() >= 3005001 &&
+ GETFLAG(INOTIFY_MASK) && pthread_create(&inotify_thread, NULL, start_inotify, NULL) )
+@@ -846,4 +873,5 @@
+ DPRINTF(E_FATAL, L_GENERAL, "ERROR: pthread_create() failed for start_inotify.\n");
+ }
++#endif
+
+ sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr);
diff --git a/net/minidlna/files/patch-upnphttp b/net/minidlna/files/patch-upnphttp
new file mode 100644
index 000000000000..2827a4423af1
--- /dev/null
+++ b/net/minidlna/files/patch-upnphttp
@@ -0,0 +1,95 @@
+--- upnphttp.c 2010-12-13 01:41:52.000000000 -0500
++++ upnphttp.c 2010-12-13 17:28:08.000000000 -0500
+@@ -66,5 +66,4 @@
+ #include <fcntl.h>
+ #include <errno.h>
+-#include <sys/sendfile.h>
+ #include <arpa/inet.h>
+
+@@ -80,10 +79,16 @@
+ #include "tivo_commands.h"
+ #endif
++#ifdef __linux__
+ //#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much?
+ #define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much?
+ #define MIN_BUFFER_SIZE 65536
++#endif
+
+ #include "icons.c"
+
++#ifndef MSG_MORE /* A Linux-only flag for send(2) */
++# define MSG_MORE 0
++#endif
++
+ struct upnphttp *
+ New_upnphttp(int s)
+@@ -1115,6 +1120,7 @@
+ }
+
+-void
++static void
+ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset)
++#if defined(__linux__)
+ {
+ off_t send_size;
+@@ -1166,4 +1172,25 @@
+ free(buf);
+ }
++#elif defined(__FreeBSD__) || defined(__NetBSD__) || \
++ defined(__OpenBSD__) || defined(__DragonFlyBSD__)
++{
++
++ off_t sent;
++
++ while (offset < end_offset)
++ {
++ if (sendfile(sendfd, h->socket, offset,
++ end_offset - offset + 1, NULL, &sent, SF_MNOWAIT) == -1) {
++ DPRINTF(E_ERROR, L_HTTP,
++ "sendfile error :: error no. %d [%s]\n",
++ errno, strerror(errno));
++ if (errno != EAGAIN)
++ break;
++ }
++ offset += sent;
++
++ }
++}
++#endif
+
+ void
+@@ -1287,5 +1314,5 @@
+ "contentFeatures.dlna.org: DLNA.ORG_PN=JPEG_TN\r\n"
+ "Server: " MINIDLNA_SERVER_STRING "\r\n",
+- size, date);
++ (intmax_t)size, date);
+
+ if( h->reqflags & FLAG_XFERBACKGROUND )
+@@ -1355,5 +1382,5 @@
+ "EXT:\r\n"
+ "Server: " MINIDLNA_SERVER_STRING "\r\n\r\n",
+- size, date);
++ (intmax_t)size, date);
+
+ if( (send_data(h, header, ret, MSG_MORE) == 0) && (h->req_command != EHead) && (sendfh > 0) )
+@@ -1813,5 +1840,5 @@
+ sprintf(hdr_buf, "Content-Length: %jd\r\n"
+ "Content-Range: bytes %jd-%jd/%jd\r\n",
+- total, h->req_RangeStart, h->req_RangeEnd, size);
++ (intmax_t)total, (intmax_t)h->req_RangeStart, (intmax_t)h->req_RangeEnd, (intmax_t)size);
+ }
+ else
+@@ -1821,5 +1848,5 @@
+ sprintf(hdr_buf, "Content-Length: %jd\r\n"
+ "Content-Range: bytes %jd-%jd/%jd\r\n",
+- total, h->req_RangeStart, size-1, size);
++ (intmax_t)total, (intmax_t)h->req_RangeStart, (intmax_t)(size-1), (intmax_t)size);
+ }
+ }
+@@ -1828,5 +1855,5 @@
+ h->req_RangeEnd = size;
+ total = size;
+- sprintf(hdr_buf, "Content-Length: %jd\r\n", total);
++ sprintf(hdr_buf, "Content-Length: %jd\r\n", (intmax_t)total);
+ }
+ strcat(header, hdr_buf);
diff --git a/net/minidlna/files/pkg-message.in b/net/minidlna/files/pkg-message.in
new file mode 100644
index 000000000000..8fd73e638995
--- /dev/null
+++ b/net/minidlna/files/pkg-message.in
@@ -0,0 +1,5 @@
+
+Examine the %%PREFIX%%/etc/minidlna.conf and adjust it to match your system.
+
+The DB-directory should exist and be writable to user running minidlna.
+
diff --git a/net/minidlna/files/scandir-patch b/net/minidlna/files/scandir-patch
new file mode 100644
index 000000000000..7c056061cc48
--- /dev/null
+++ b/net/minidlna/files/scandir-patch
@@ -0,0 +1,38 @@
+--- scanner.c 17 Nov 2009 19:13:00 -0000 1.53
++++ scanner.c 9 Jan 2010 13:19:49 -0000
+@@ -629,7 +633,7 @@
+ }
+
+ int
+-filter_audio(const struct dirent *d)
++filter_audio(struct dirent *d)
+ {
+ return ( (*d->d_name != '.') &&
+ ((d->d_type == DT_DIR) ||
+@@ -641,7 +645,7 @@
+ }
+
+ int
+-filter_video(const struct dirent *d)
++filter_video(struct dirent *d)
+ {
+ return ( (*d->d_name != '.') &&
+ ((d->d_type == DT_DIR) ||
+@@ -653,7 +657,7 @@
+ }
+
+ int
+-filter_images(const struct dirent *d)
++filter_images(struct dirent *d)
+ {
+ return ( (*d->d_name != '.') &&
+ ((d->d_type == DT_DIR) ||
+@@ -665,7 +669,7 @@
+ }
+
+ int
+-filter_media(const struct dirent *d)
++filter_media(struct dirent *d)
+ {
+ return ( (*d->d_name != '.') &&
+ ((d->d_type == DT_DIR) ||
diff --git a/net/minidlna/pkg-descr b/net/minidlna/pkg-descr
new file mode 100644
index 000000000000..b0288169afc1
--- /dev/null
+++ b/net/minidlna/pkg-descr
@@ -0,0 +1,10 @@
+MiniDLNA (aka ReadyDLNA) is server software with the aim of being
+fully compliant with DLNA/UPnP-AV clients.
+
+The media files are listed in an SQLite database allowing prompt
+restarts.
+
+Only Linux BINARY releases are available from the author(s) at this
+time, so this port builds from a dated snapshot of the CVS-tree.
+
+WWW: http://minidlna.sourceforge.net/
diff --git a/net/minidlna/pkg-plist b/net/minidlna/pkg-plist
new file mode 100644
index 000000000000..1484b3c32d2b
--- /dev/null
+++ b/net/minidlna/pkg-plist
@@ -0,0 +1,4 @@
+sbin/minidlna
+@unexec if cmp -s %D/etc/minidlna.conf %D/etc/minidlna.conf.sample; then rm -f %D/etc/minidlna.conf; fi
+etc/minidlna.conf.sample
+@exec [ -f %D/etc/minidlna.conf ] || cp -p %D/etc/minidlna.conf.sample %D/etc/minidlna.conf