diff options
author | Carl Fürstenberg <carl@excito.com> | 2011-10-11 18:33:18 +0400 |
---|---|---|
committer | Carl Fürstenberg <carl@excito.com> | 2011-10-11 18:33:18 +0400 |
commit | f80459caf02283511b73b7cc8c1d325c2e15a638 (patch) | |
tree | cbfdee2fc553161ef4c318129a45191e84c856dd | |
parent | fbbed4180f7338b35a06562c646976d7ee03b88e (diff) | |
parent | 949a855125f01c25fe880eaf2df18729d681596d (diff) |
Merge branch 'cvs'old_scons
Conflicts:
INSTALL
src/inotify.c
src/metadata.c
src/minidlna.c
src/scanner.c
src/upnphttp.c
39 files changed, 1148 insertions, 176 deletions
@@ -0,0 +1 @@ +Justin Maggard <jmaggard@users.sourceforge.net> diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..f35e9e2 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,53 @@ +AM_CFLAGS = -Wall -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 @STATIC_CFLAGS@ + +SUBDIRS=po + +bin_PROGRAMS = minidlna testupnpdescgen +minidlna_SOURCES = minidlna.c upnphttp.c upnpdescgen.c upnpsoap.c \ + upnpreplyparse.c minixml.c \ + getifaddr.c daemonize.c upnpglobalvars.c \ + options.c minissdp.c uuid.c upnpevents.c \ + sql.c utils.c metadata.c scanner.c inotify.c \ + tivo_utils.c tivo_beacon.c tivo_commands.c \ + tagutils/textutils.c tagutils/misc.c tagutils/tagutils.c \ + playlist.c image_utils.c albumart.c log.c + + +#if NEED_VORBIS +vorbisflag = -lvorbis +#endif + +#if NEED_OGG +flacoggflag = -logg +#endif + +minidlna_LDADD = \ + @LIBJPEG_LIBS@ \ + @LIBID3TAG_LIBS@ \ + @LIBSQLITE3_LIBS@ \ + @LIBAVFORMAT_LIBS@ \ + @LIBAVUTIL_LIBS@ \ + @LIBAVCODEC_LIBS@ \ + @LIBEXIF_LIBS@ \ + @LIBDL_LIBS@ \ + @LIBRT_LIBS@ \ + -lpthread -lFLAC $(flacoggflag) $(vorbisflag) + +minidlna_LDFLAGS = @STATIC_LDFLAGS@ + +testupnpdescgen_SOURCES = testupnpdescgen.c upnpdescgen.c +testupnpdescgen_LDADD = \ + @LIBJPEG_LIBS@ \ + @LIBID3TAG_LIBS@ \ + @LIBSQLITE3_LIBS@ \ + @LIBAVFORMAT_LIBS@ \ + @LIBAVUTIL_LIBS@ \ + @LIBAVCODEC_LIBS@ \ + @LIBEXIF_LIBS@ \ + @LIBDL_LIBS@ \ + -lpthread -lFLAC $(flacoggflag) $(vorbisflag) + + +ACLOCAL_AMFLAGS = -I m4 + +EXTRA_DIST = m4/ChangeLog @@ -1,5 +1,7 @@ -1.0.23 - Released 00-Month-0000 +1.1.0 - Released 00-Month-0000 -------------------------------- +- Add support for other operating systems. +- Switch to autoconf from our little genconfig.sh. - Enable the subtitle menu on some Samsung TV's. 1.0.22 - Released 24-Aug-2011 @@ -21,5 +21,16 @@ and http://www.dlna.org/ for mode details on DLNA. See the INSTALL file for instructions on compiling, installing, and configuring minidlna. +Prerequisites +================== + +- libexif +- libjpeg +- libid3tag +- libFLAC +- libvorbis +- libsqlite3 +- libavformat (the ffmpeg libraries) + Justin Maggard diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..f005a50 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +package="minidlna" + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +cd "$srcdir" +DIE=0 + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +echo "Generating configuration files for $package, please wait...." + +autoreconf -vfi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..045b020 --- /dev/null +++ b/configure.ac @@ -0,0 +1,570 @@ +AC_INIT(MiniDLNA,1.1.0,,minidlna) +#LT_INIT + +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE(minidlna,1.1.0) +AC_CONFIG_HEADERS([config.h]) +AC_USE_SYSTEM_EXTENSIONS + +#MiniDLNA + +AM_ICONV +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION(0.14.4) + +# Checks for programs. +# AC_PROG_CXX +AC_PROG_AWK +AC_PROG_CC +# AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET + + +################################################################################################################ +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_INT32_T +AC_TYPE_MODE_T +AC_TYPE_OFF_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_STRUCT_ST_BLOCKS +AC_HEADER_STDBOOL +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T +AC_C_BIGENDIAN + +# Checks for library functions. +AC_FUNC_FORK +AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK +AC_CHECK_FUNCS([gethostname getifaddrs gettimeofday inet_ntoa memmove memset mkdir realpath select sendfile setlocale socket strcasecmp strchr strdup strerror strncasecmp strpbrk strrchr strstr strtol strtoul]) + +################################################################################################################ +# Special include directories +case $host in + *-*-darwin*) + DARWIN_OS=1 + SEARCH_DIR="/opt/local" + ;; + *-*-solaris*) + AC_DEFINE([SOLARIS], [1], [we are on solaris]) + ;; + *-*-cygwin*) + CYGWIN_OS=1 + ;; + *-*-freebsd*) + FREEBSD_OS=1 + ;; + *-*-openbsd*) + OPENBSD_OS=1 + ;; +esac + +AC_CHECK_HEADERS(syscall.h sys/syscall.h mach/mach_time.h) +AC_MSG_CHECKING([for __NR_clock_gettime syscall]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <asm/unistd.h> + ], + [ + #ifndef __NR_clock_gettime + #error + #endif + ] + )], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_CLOCK_GETTIME_SYSCALL], [1], [Whether the __NR_clock_gettime syscall is defined]) + ], + [ + AC_MSG_RESULT([no]) + AC_CHECK_LIB([rt], [clock_gettime], [LIBRT_LIBS="-lrt"],) + AC_SUBST(LIBRT_LIBS) + ]) + +################################################################################################################ +### Library checks +AC_CHECK_LIB([dl], [dlopen], [LIBDL_LIBS="-ldl"],) +AC_SUBST(LIBDL_LIBS) + +CPPFLAGS_SAVE="$CPPFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + fi + AC_CHECK_HEADERS([libavutil/avutil.h ffmpeg/libavutil/avutil.h libav/libavutil/avutil.h avutil.h ffmpeg/avutil.h libav/avutil.h], [break], [continue], []) + if test -n "$dir"; then + if test x"$ac_cv_header_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include" + elif test x"$ac_cv_header_libavutil_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libavutil" + elif test x"$ac_cv_header_ffmpeg_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg" + elif test x"$ac_cv_header_ffmpeg_libavutil_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg/libavutil" + elif test x"$ac_cv_header_libav_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav" + elif test x"$ac_cv_header_libav_libavutil_avutil_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav/libavutil" + else + unset ac_cv_header_avutil_h + unset ac_cv_header_libavutil_avutil_h + unset ac_cv_header_ffmpeg_avutil_h + unset ac_cv_header_ffmpeg_libavutil_avutil_h + unset ac_cv_header_libav_avutil_h + unset ac_cv_header_libav_libavutil_avutil_h + CPPFLAGS="$CPPFLAGS_SAVE" + continue + fi + fi + HAVE_LIBAVUTIL=1 + break +done +if test -z "$HAVE_LIBAVUTIL"; then + AC_MSG_ERROR([libavutil headers not found or not usable]) +fi + +CPPFLAGS_SAVE="$CPPFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + fi + AC_CHECK_HEADERS([libavcodec/avcodec.h ffmpeg/libavcodec/avcodec.h libav/libavcodec/avcodec.h avcodec.h ffmpeg/avcodec.h libav/avcodec.h], [break], [continue], []) + if test -n "$dir"; then + if test x"$ac_cv_header_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include" + elif test x"$ac_cv_header_libavcodec_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libavcodec" + elif test x"$ac_cv_header_ffmpeg_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg" + elif test x"$ac_cv_header_ffmpeg_libavcodec_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg/libavcodec" + elif test x"$ac_cv_header_libav_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav" + elif test x"$ac_cv_header_libav_libavcodec_avcodec_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav/libavcodec" + else + unset ac_cv_header_avcodec_h + unset ac_cv_header_libavcodec_avcodec_h + unset ac_cv_header_ffmpeg_avcodec_h + unset ac_cv_header_ffmpeg_libavcodec_avcodec_h + unset ac_cv_header_libav_avcodec_h + unset ac_cv_header_libav_libavcodec_avcodec_h + CPPFLAGS="$CPPFLAGS_SAVE" + continue + fi + fi + HAVE_LIBAVCODEC=1 + break +done +if test -z "$HAVE_LIBAVCODEC"; then + AC_MSG_ERROR([libavcodec headers not found or not usable]) +fi + +CPPFLAGS_SAVE="$CPPFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + fi + AC_CHECK_HEADERS([libavformat/avformat.h ffmpeg/libavformat/avformat.h libav/libavformat/avformat.h avformat.h ffmpeg/avformat.h libav/avformat.h], [break], [continue], []) + if test -n "$dir"; then + if test x"$ac_cv_header_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include" + elif test x"$ac_cv_header_libavformat_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libavformat" + elif test x"$ac_cv_header_ffmpeg_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg" + elif test x"$ac_cv_header_ffmpeg_libavformat_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/ffmpeg/libavformat" + elif test x"$ac_cv_header_libav_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav" + elif test x"$ac_cv_header_libav_libavformat_avformat_h" = xyes; then + CPPFLAGS="$CPPFLAGS_SAVE -I$dir/include/libav/libavformat" + else + unset ac_cv_header_avformat_h + unset ac_cv_header_libavformat_avformat_h + unset ac_cv_header_ffmpeg_avformat_h + unset ac_cv_header_ffmpeg_libavformat_avformat_h + unset ac_cv_header_libav_avformat_h + unset ac_cv_header_libav_libavformat_avformat_h + CPPFLAGS="$CPPFLAGS_SAVE" + continue + fi + fi + HAVE_LIBAVFORMAT=1 + break +done +if test -z "$HAVE_LIBAVFORMAT"; then + AC_MSG_ERROR([libavformat headers not found or not usable]) +fi + +CPPFLAGS_SAVE="$CPPFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + CPPFLAGS="$CPPFLAGS -I$dir/include" + fi + AC_CHECK_HEADERS([jpeglib.h sqlite3.h libexif/exif-loader.h id3tag.h ogg/ogg.h vorbis/codec.h FLAC/metadata.h],,[unset $as_ac_Header; break],) + if test x"$ac_cv_header_jpeglib_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_sqlite3_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_libexif_exif_loader_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_id3tag_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_ogg_ogg_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_vorbis_codec_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + elif test x"$ac_cv_header_FLAC_metadata_h" != x"yes"; then + CPPFLAGS="$CPPFLAGS_SAVE" + continue + else + break; + fi +done +test x"$ac_cv_header_jpeglib_h" != x"yes" && AC_MSG_ERROR([libjpeg headers not found or not usable]) +test x"$ac_cv_header_sqlite3_h" != x"yes" && AC_MSG_ERROR([libsqlite3 headers not found or not usable]) +test x"$ac_cv_header_libexif_exif_loader_h" != x"yes" && AC_MSG_ERROR([libexif headers not found or not usable]) +test x"$ac_cv_header_id3tag_h" != x"yes" && AC_MSG_ERROR([libid3tag headers not found or not usable]) +test x"$ac_cv_header_ogg_ogg_h" != x"yes" && AC_MSG_ERROR([libogg headers not found or not usable]) +test x"$ac_cv_header_vorbis_codec_h" != x"yes" && AC_MSG_ERROR([libvorbis headers not found or not usable]) +test x"$ac_cv_header_FLAC_metadata_h" != x"yes" && AC_MSG_ERROR([libFLAC headers not found or not usable]) + +CFLAGS_SAVE="$CFLAGS" +CFLAGS="$CFLAGS -Wall -Werror" +AC_MSG_CHECKING([if we should use the daemon() libc function]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <stdlib.h> + ], + [ + (void)daemon(0, 0); + ] + )], + [ + AC_DEFINE([USE_DAEMON], [1], + [use the system's builtin daemon()]) + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + ]) + +AC_MSG_CHECKING([if scandir declaration requires const char cast]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <stdlib.h> + #include <sys/types.h> + #include <dirent.h> + ], + [ + int filter(struct dirent *d); + struct dirent **ptr = NULL; + char *name = NULL; + (void)scandir(name, &ptr, filter, alphasort); + ] + )], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_DEFINE([SCANDIR_CONST], [1], + [scandir needs const char cast]) + + AC_MSG_RESULT([yes]) + ]) + +AC_MSG_CHECKING([for linux sendfile support]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <sys/types.h> + #include <sys/sendfile.h> + ], + [ + int tofd = 0, fromfd = 0; + off_t offset; + size_t total = 0; + ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); + return nwritten; + ] + )], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_LINUX_SENDFILE_API], [1], [Whether linux sendfile() API is available]) + ], + [ + AC_MSG_RESULT([no]) + ]) + +AC_MSG_CHECKING([for darwin sendfile support]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <stdlib.h> + #include <sys/types.h> + #include <sys/socket.h> + #include <sys/uio.h> + ], + [ + int fd = 0, s = 0; + off_t offset = 0, len; + struct sf_hdtr *hdtr = NULL; + int flags = 0; + int ret; + ret = sendfile(fd, s, offset, &len, hdtr, flags); + return ret; + ] + )], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_DARWIN_SENDFILE_API], [1], [Whether darwin sendfile() API is available]) + ], + [ + AC_MSG_RESULT([no]) + ]) + +AC_MSG_CHECKING([for freebsd sendfile support]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <stdlib.h> + #include <sys/types.h> + #include <sys/socket.h> + #include <sys/uio.h> + ], + [ + int fromfd=0, tofd=0, ret, total=0; + off_t offset=0, nwritten; + struct sf_hdtr hdr; + struct iovec hdtrl; + hdr.headers = &hdtrl; + hdr.hdr_cnt = 1; + hdr.trailers = NULL; + hdr.trl_cnt = 0; + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); + ] + )], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_FREEBSD_SENDFILE_API], [1], [Whether freebsd sendfile() API is available]) + ], + [ + AC_MSG_RESULT([no]) + ]) +CFLAGS="$CFLAGS_SAVE" + +LDFLAGS_SAVE="$LDFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_CHECK_LIB([jpeg], [jpeg_set_defaults], [LIBJPEG_LIBS="-ljpeg"], [unset ac_cv_lib_jpeg_jpeg_set_defaults; LDFLAGS="$LDFLAGS_SAVE"; continue]) + break +done +test x"$ac_cv_lib_jpeg_jpeg_set_defaults" = x"yes" || AC_MSG_ERROR([Could not find libjpeg]) +AC_SUBST(LIBJPEG_LIBS) + +LDFLAGS_SAVE="$LDFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_CHECK_LIB([exif], [exif_data_new_from_file], [LIBEXIF_LIBS="-lexif"], [unset ac_cv_lib_exif_exif_data_new_from_file; LDFLAGS="$LDFLAGS_SAVE"; continue]) + break +done +test x"$ac_cv_lib_jpeg_jpeg_set_defaults" = x"yes" || AC_MSG_ERROR([Could not find libexif]) +AC_SUBST(LIBEXIF_LIBS) + +LDFLAGS_SAVE="$LDFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_CHECK_LIB([id3tag], [id3_file_open], [LIBID3TAG_LIBS="-lid3tag"], [unset ac_cv_lib_id3tag_id3_file_open; LDFLAGS="$LDFLAGS_SAVE"; continue]) + break +done +test x"$ac_cv_lib_id3tag_id3_file_open" = x"yes" || AC_MSG_ERROR([Could not find libid3tag]) +AC_SUBST(LIBID3TAG_LIBS) + +LDFLAGS_SAVE="$LDFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_CHECK_LIB([sqlite3], [sqlite3_open], [LIBSQLITE3_LIBS="-lsqlite3"], [unset ac_cv_lib_sqlite3_sqlite3_open; LDFLAGS="$LDFLAGS_SAVE"; continue]) + break +done +test x"$ac_cv_lib_sqlite3_sqlite3_open" = x"yes" || AC_MSG_ERROR([Could not find libsqlite3]) +AC_SUBST(LIBSQLITE3_LIBS) + +LDFLAGS_SAVE="$LDFLAGS" +for dir in "" /usr/local $SEARCH_DIR; do + if test -n "$dir"; then + LDFLAGS="$LDFLAGS -L$dir/lib" + fi + AC_CHECK_LIB([avformat], [av_open_input_file], [LIBAVFORMAT_LIBS="-lavformat"], [unset ac_cv_lib_avformat_av_open_input_file; LDFLAGS="$LDFLAGS_SAVE"; continue]) + AC_SUBST(LIBJPEG_LIBS) + break +done +test x"$ac_cv_lib_avformat_av_open_input_file" = x"yes" || AC_MSG_ERROR([Could not find libavformat - part of ffmpeg]) +AC_SUBST(LIBAVFORMAT_LIBS) + +AC_CHECK_LIB(avutil ,[av_rescale_q], [LIBAVUTIL_LIBS="-lavutil"], [AC_MSG_ERROR([Could not find libavutil - part of ffmpeg])]) +AC_SUBST(LIBAVUTIL_LIBS) + +AC_CHECK_LIB(avcodec ,[avcodec_init], [LIBAVCODEC_LIBS="-lavcodec"], [AC_MSG_ERROR([Could not find libavcodec - part of ffmpeg])]) +AC_SUBST(LIBAVCODEC_LIBS) + +AC_CHECK_LIB(pthread, pthread_create) + +# test if we have vorbisfile +# prior versions had ov_open_callbacks in libvorbis, test that, too. +AC_CHECK_LIB(vorbisfile, ov_open_callbacks, + [AC_CHECK_HEADERS([vorbis/vorbisfile.h], + AM_CONDITIONAL(HAVE_VORBISFILE, true) + AC_DEFINE(HAVE_VORBISFILE,1,[Have vorbisfile]), + AM_CONDITIONAL(HAVE_VORBISFILE, false) + AC_DEFINE(HAVE_VORBISFILE,0,[lacking vorbisfile]))], + AM_CONDITIONAL(HAVE_VORBISFILE, false), + -lvorbis -logg) +AC_CHECK_LIB(FLAC, FLAC__stream_decoder_init_stream, + [AC_CHECK_HEADERS([FLAC/all.h], + AM_CONDITIONAL(HAVE_FLAC, true) + AC_DEFINE(HAVE_FLAC,1,[Have flac]), + AM_CONDITIONAL(HAVE_FLAC, false))], + AM_CONDITIONAL(HAVE_FLAC, false), + -logg) +# test without -logg to see whether we really need it (libflac can be without) +AC_CHECK_LIB(FLAC, FLAC__stream_decoder_init_ogg_stream, + AM_CONDITIONAL(HAVE_FLAC, true) + AC_DEFINE(HAVE_FLAC,1,[Have flac]) + AM_CONDITIONAL(NEED_OGG, false), + [AM_CONDITIONAL(NEED_OGG, true)]) +AC_CHECK_LIB(vorbisfile, vorbis_comment_query, + AM_CONDITIONAL(NEED_VORBIS, false), + AM_CONDITIONAL(NEED_VORBIS, true), + -logg) + +################################################################################################################ +### Header checks + +AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h fcntl.h libintl.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h sys/file.h sys/inotify.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h]) + +AC_CHECK_FUNCS(inotify_init, AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotify support]), [ + AC_MSG_CHECKING([for __NR_inotify_init syscall]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [ + #include <asm/unistd.h> + ], + [ + #ifndef __NR_inotify_init + #error + #endif + ] + )], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotify support]) + ]) +]) + +################################################################################################################ +### Build Options + +AC_ARG_WITH(logpath, + AS_HELP_STRING([--with-log-path],[Log path]), + [with_logpath="$withval"],[with_logpath="/var/log"]) +AC_DEFINE_UNQUOTED([DEFAULT_LOG_PATH],"${with_logpath}",[Log path]) + + +AC_ARG_WITH(dbpath, + AS_HELP_STRING([--with-db-path],[DB path]), + [with_dbpath="$withval"],[with_dbpath="/var/cache/minidlna"]) +AC_DEFINE_UNQUOTED([DEFAULT_DB_PATH],"${with_dbpath}",[DB path]) + +AC_ARG_WITH(osname, + AS_HELP_STRING([--with-os-name],[OS Name]), + [with_osname="$withval"],[with_osname="$(uname -s)"]) +AC_DEFINE_UNQUOTED([OS_NAME],"${with_osname}",[OS Name]) + +AC_ARG_WITH(osver, + AS_HELP_STRING([--with-os-version],[OS Version]), + [with_osver="$withval"],[with_osver="$(uname -r)"]) +AC_DEFINE_UNQUOTED([OS_VERSION],"${with_osver}",[OS Version]) + +AC_ARG_WITH(osurl, + AS_HELP_STRING([--with-os-url],[OS URL]), + [with_osurl="$withval"],[with_osurl="http://www.netgear.com"]) +AC_DEFINE_UNQUOTED([OS_URL],"${with_osurl}",[OS URL]) + +AC_ARG_WITH(tivo, + AS_HELP_STRING([--with-tivo],[TiVo Support]), + [with_tivo="$withval"],[with_tivo="yes"]) +if test "$with_tivo" = "yes"; then + AC_DEFINE([TIVO_SUPPORT],[1],[Define to 1 if you want to enable TiVo support]) +fi + +AC_ARG_WITH(netgear, + AS_HELP_STRING([--with-netgear],[NETGEAR ReadyNAS Support]), + [with_netgear="$withval"],[with_netgear="no"]) +if test "$with_netgear" = "yes"; then + AC_DEFINE([NETGEAR],[1],[Define to 1 if you want to enable NETGEAR support]) + AC_DEFINE([READYNAS],[1],[Define to 1 if you want to enable NETGEAR support]) + AC_DEFINE([PNPX],[5],[Define to 1 if you want to enable NETGEAR support]) + AC_DEFINE_UNQUOTED([OS_URL],"http://www.readynas.com/",[OS URL]) +fi + +AC_ARG_WITH(staticbin, + AS_HELP_STRING([--with-staticbin],[Build statically linked binaries]), + [with_staticbin="$withval"],[with_staticbin="no"]) +if test "$with_staticbin" = "yes"; then + STATIC_CFLAGS="-DSTATIC" + AC_SUBST(STATIC_CFLAGS) + STATIC_LDFLAGS="-Wl,-Bstatic" + AC_SUBST(STATIC_LDFLAGS) +fi + +case "$target_os" in + darwin*) + ;; + freebsd*) + VER=`grep '#define __FreeBSD_version' /usr/include/sys/param.h | awk '{print $3}'` + OS_URL=http://www.freebsd.org/ + ;; + solaris*) + AC_DEFINE([USE_IPF], [1], [Define to enable IPF]) + AC_DEFINE([LOG_PERROR], [0], [Define to enable logging]) + AC_DEFINE([SOLARIS_KSTATS], [1], [Define to enable Solaris Kernel Stats]) + ;; + kfreebsd*) + OS_URL=http://www.debian.org/ + ;; + linux*) + ;; + *) + echo "Unknown OS : $target_os" + ;; +esac + + +AC_OUTPUT([ po/Makefile.in +Makefile +]) diff --git a/sendfile.h b/sendfile.h new file mode 100644 index 0000000..32bde69 --- /dev/null +++ b/sendfile.h @@ -0,0 +1,53 @@ +#if defined(HAVE_LINUX_SENDFILE_API) + +#include <sys/sendfile.h> + +int sys_sendfile(int sock, int sendfd, off_t *offset, off_t len) +{ + return sendfile(sock, sendfd, offset, len); +} + +#elif defined(HAVE_DARWIN_SENDFILE_API) + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + +int sys_sendfile(int sock, int sendfd, off_t *offset, off_t len) +{ + int ret; + + ret = sendfile(sendfd, sock, *offset, &len, NULL, 0); + *offset += len; + + return ret; +} + +#elif defined(HAVE_FREEBSD_SENDFILE_API) + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + +int sys_sendfile(int sock, int sendfd, off_t *offset, off_t len) +{ + int ret; + size_t nbytes = len; + + ret = sendfile(sendfd, sock, *offset, nbytes, NULL, &len, SF_MNOWAIT); + *offset += len; + + return ret; +} + +#else + +#include <errno.h> + +int sys_sendfile(int sock, int sendfd, off_t *offset, off_t len) +{ + errno = EINVAL; + return -1; +} + +#endif diff --git a/src/albumart.c b/src/albumart.c index f184377..189cdd5 100644 --- a/src/albumart.c +++ b/src/albumart.c @@ -20,6 +20,7 @@ #include <string.h> #include <unistd.h> #include <dirent.h> +#include <sys/param.h> #include <sys/stat.h> #include <sys/param.h> #include <libgen.h> diff --git a/src/daemonize.c b/src/daemonize.c index 57edbec..63771d8 100644 --- a/src/daemonize.c +++ b/src/daemonize.c @@ -43,12 +43,12 @@ #endif /* HAVE_CONFIG_H */ #include "log.h" -#ifndef USE_DAEMON - int daemonize(void) { - int pid, i; + int pid; +#ifndef USE_DAEMON + int i; switch(fork()) { @@ -74,16 +74,20 @@ daemonize(void) dup(i); /* stderr */ umask(027); - chdir("/"); /* chdir to /tmp ? */ - - return pid; + chdir("/"); + break; /* parent process */ default: exit(0); } -} +#else + if( daemon(0, 0) < 0 ) + perror("daemon()"); + pid = getpid(); #endif + return pid; +} int writepidfile(const char * fname, int pid) @@ -92,7 +96,7 @@ writepidfile(const char * fname, int pid) int pidstringlen; int pidfile; - if(!fname || (strlen(fname) == 0)) + if(!fname || *fname == '\0') return -1; if( (pidfile = open(fname, O_WRONLY|O_CREAT, 0644)) < 0) @@ -127,7 +131,7 @@ checkforrunning(const char * fname) int pidfile; pid_t pid; - if(!fname || (strlen(fname) == 0)) + if(!fname || *fname == '\0') return -1; if( (pidfile = open(fname, O_RDONLY)) < 0) diff --git a/src/daemonize.h b/src/daemonize.h index 0d83626..4842bde 100644 --- a/src/daemonize.h +++ b/src/daemonize.h @@ -33,13 +33,11 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#ifndef USE_DAEMON /* daemonize() * "fork" to background, detach from terminal, etc... * returns: pid of the daemon, exits upon failure */ int daemonize(void); -#endif /* writepidfile() * write the pid to a file */ diff --git a/src/getifaddr.c b/src/getifaddr.c index f0cbdfc..4aeb92b 100644 --- a/src/getifaddr.c +++ b/src/getifaddr.c @@ -1,4 +1,4 @@ -/* $Id: getifaddr.c,v 1.14 2011/05/02 23:50:52 jmaggard Exp $ */ +/* $Id$ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * @@ -43,19 +43,82 @@ #include <sys/sockio.h> #endif +#include "config.h" +#if HAVE_GETIFADDRS +#include <ifaddrs.h> +#ifdef __linux__ +#ifndef AF_LINK +#define AF_LINK AF_INET +#endif +#else +#include <net/if_dl.h> +#endif +#endif #include "getifaddr.h" #include "log.h" +static uint32_t +get_netmask(struct sockaddr_in *netmask) +{ + uint32_t mask; + int i; + + if (!netmask) + return 0; + mask = ntohl(netmask->sin_addr.s_addr); + for (i = 0; i < 32; i++) + { + if ((mask >> i) & 1) + break; + } + mask = 32 - i; + + return mask; +} + int getifaddr(const char * ifname, char * buf, int len) { /* SIOCGIFADDR struct ifreq * */ + uint32_t mask = 0; + int i; +#if HAVE_GETIFADDRS + struct ifaddrs *ifap, *p; + struct sockaddr_in *addr_in; + + if( getifaddrs(&ifap) != 0 ) + { + DPRINTF(E_ERROR, L_GENERAL, "getifaddrs(): %s\n", strerror(errno)); + return -1; + } + for( p = ifap; p != NULL; p = p->ifa_next ) + { + if( p->ifa_addr->sa_family == AF_INET ) + { + if( strcmp(p->ifa_name, ifname) != 0 ) + continue; + addr_in = (struct sockaddr_in *)p->ifa_addr; + if(!inet_ntop(AF_INET, &addr_in->sin_addr, buf, len)) + { + DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno)); + break; + } + addr_in = (struct sockaddr_in *)p->ifa_netmask; + mask = get_netmask(addr_in); + break; + } + } + freeifaddrs(ifap); + if( !p ) + { + DPRINTF(E_ERROR, L_GENERAL, "Network interface %s not found\n", ifname); + return -1; + } +#else int s; struct ifreq ifr; int ifrlen; struct sockaddr_in * addr; - uint32_t mask; - int i; ifrlen = sizeof(ifr); s = socket(PF_INET, SOCK_DGRAM, 0); @@ -81,22 +144,17 @@ getifaddr(const char * ifname, char * buf, int len) if(ioctl(s, SIOCGIFNETMASK, &ifr, &ifrlen) == 0) { addr = (struct sockaddr_in *)&ifr.ifr_netmask; - mask = ntohl(addr->sin_addr.s_addr); - for (i = 0; i < 32; i++) - { - if ((mask >> i) & 1) - break; - } - mask = 32 - i; - if (mask) - { - i = strlen(buf); - snprintf(buf+i, len-i, "/%u", mask); - } + mask = get_netmask(addr); } else DPRINTF(E_ERROR, L_GENERAL, "ioctl(s, SIOCGIFNETMASK, ...): %s\n", strerror(errno)); close(s); +#endif + if (mask) + { + i = strlen(buf); + snprintf(buf+i, len-i, "/%u", mask); + } return 0; } @@ -104,12 +162,42 @@ int getsysaddr(char * buf, int len) { int i; + uint32_t mask = 0; + int ret = -1; +#if HAVE_GETIFADDRS + struct ifaddrs *ifap, *p; + struct sockaddr_in *addr_in; + uint8_t a; + + if( getifaddrs(&ifap) != 0 ) + { + DPRINTF(E_ERROR, L_GENERAL, "getifaddrs(): %s\n", strerror(errno)); + return -1; + } + for( p = ifap; p != NULL; p = p->ifa_next ) + { + if (p->ifa_addr->sa_family == AF_INET) + { + addr_in = (struct sockaddr_in *)p->ifa_addr; + 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)) + { + DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno)); + break; + } + addr_in = (struct sockaddr_in *)p->ifa_netmask; + mask = get_netmask(addr_in); + ret = 0; + break; + } + } + freeifaddrs(ifap); +#else int s = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; struct ifreq ifr; - uint32_t mask; - int ret = -1; - for (i=1; i > 0; i++) { ifr.ifr_ifindex = i; @@ -128,24 +216,19 @@ getsysaddr(char * buf, int len) close(s); break; } - ret = 0; - memcpy(&addr, &ifr.ifr_netmask, sizeof(addr)); - mask = ntohl(addr.sin_addr.s_addr); - for (i = 0; i < 32; i++) - { - if ((mask >> i) & 1) - break; - } - mask = 32 - i; - if (mask) - { - i = strlen(buf); - snprintf(buf+i, len-i, "/%u", mask); - } + mask = get_netmask(&addr); + ret = 0; break; } close(s); +#endif + + if (mask) + { + i = strlen(buf); + snprintf(buf+i, len-i, "/%u", mask); + } return(ret); } @@ -153,11 +236,55 @@ getsysaddr(char * buf, int len) int getsyshwaddr(char * buf, int len) { - struct if_nameindex *ifaces, *if_idx; unsigned char mac[6]; + int ret = -1; +#if HAVE_GETIFADDRS + struct ifaddrs *ifap, *p; + struct sockaddr_in *addr_in; + uint8_t a; + + if( getifaddrs(&ifap) != 0 ) + { + DPRINTF(E_ERROR, L_GENERAL, "getifaddrs(): %s\n", strerror(errno)); + return -1; + } + for( p = ifap; p != NULL; p = p->ifa_next ) + { + if (p->ifa_addr->sa_family == AF_LINK) + { + addr_in = (struct sockaddr_in *)p->ifa_addr; + a = (htonl(addr_in->sin_addr.s_addr) >> 0x18) & 0xFF; + if( a == 127 ) + continue; +#ifdef __linux__ + struct ifreq ifr; + int fd; + fd = socket(AF_INET, SOCK_DGRAM, 0); + if( fd < 0 ) + continue; + strncpy(ifr.ifr_name, p->ifa_name, IFNAMSIZ); + if( ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 ) + { + close(fd); + continue; + } + memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); +#else + struct sockaddr_dl *sdl; + sdl = (struct sockaddr_dl*)p->ifa_addr; + memcpy(mac, LLADDR(sdl), sdl->sdl_alen); +#endif + if( MACADDR_IS_ZERO(mac) ) + continue; + ret = 0; + break; + } + } + freeifaddrs(ifap); +#else + struct if_nameindex *ifaces, *if_idx; struct ifreq ifr; int fd; - int ret = -1; memset(&mac, '\0', sizeof(mac)); /* Get the spatially unique node identifier */ @@ -180,25 +307,21 @@ getsyshwaddr(char * buf, int len) continue; if( MACADDR_IS_ZERO(ifr.ifr_hwaddr.sa_data) ) continue; + memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); ret = 0; break; } if_freenameindex(ifaces); close(fd); - +#endif if(ret == 0) { if(len > 12) - { - memmove(mac, ifr.ifr_hwaddr.sa_data, 6); sprintf(buf, "%02x%02x%02x%02x%02x%02x", mac[0]&0xFF, mac[1]&0xFF, mac[2]&0xFF, mac[3]&0xFF, mac[4]&0xFF, mac[5]&0xFF); - } else if(len == 6) - { - memmove(buf, ifr.ifr_hwaddr.sa_data, 6); - } + memmove(buf, mac, 6); } return ret; } diff --git a/src/image_utils.c b/src/image_utils.c index c6b9abd..2135e3d 100644 --- a/src/image_utils.c +++ b/src/image_utils.c @@ -26,6 +26,7 @@ * The resize functions come from the resize_image project, at http://www.golac.fr/Image-Resizer */ +#include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -33,7 +34,11 @@ #include <sys/types.h> #include <setjmp.h> #include <jpeglib.h> +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#else #include <endian.h> +#endif #include "upnpreplyparse.h" #include "image_utils.h" @@ -380,8 +385,7 @@ image_get_jpeg_date_xmp(const char * path, char ** date) } } fclose(img); - if( data ) - free(data); + free(data); return ret; } @@ -463,8 +467,7 @@ image_new_from_jpeg(const char * path, int is_file, const char * buf, int size, fclose(file); if( vimage ) { - if( vimage->buf ) - free(vimage->buf); + free(vimage->buf); free(vimage); } return NULL; diff --git a/src/inotify.c b/src/inotify.c index 3d13cb0..00a5793 100644 --- a/src/inotify.c +++ b/src/inotify.c @@ -18,6 +18,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ +#ifdef HAVE_INOTIFY #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -31,7 +32,7 @@ #include <sys/time.h> #include <sys/resource.h> #include <poll.h> -#ifdef HAVE_INOTIFY_H +#ifdef HAVE_SYS_INOTIFY_H #include <sys/inotify.h> #else #include "linux/inotify.h" @@ -218,8 +219,7 @@ inotify_remove_watches(int fd) { last_w = w; inotify_rm_watch(fd, w->wd); - if( w->path ) - free(w->path); + free(w->path); rm_watches++; w = w->next; free(last_w); @@ -736,3 +736,4 @@ quitting: return 0; } +#endif diff --git a/src/inotify.h b/src/inotify.h index 91db6f6..0f378c2 100644 --- a/src/inotify.h +++ b/src/inotify.h @@ -1,6 +1,7 @@ - +#ifdef HAVE_INOTIFY int inotify_remove_file(const char * path); void * start_inotify(); +#endif diff --git a/src/metadata.c b/src/metadata.c index d2f45c2..248868a 100644 --- a/src/metadata.c +++ b/src/metadata.c @@ -19,21 +19,61 @@ #include <ctype.h> #include <string.h> #include <stdlib.h> -#include <sys/stat.h> - +#include <libgen.h> #include <unistd.h> -#include <sys/types.h> #include <sys/stat.h> +#include <sys/types.h> +#include <sys/param.h> #include <fcntl.h> +#include "config.h" #include <libexif/exif-loader.h> #include "image_utils.h" +#include "tagutils/tagutils.h" #include <jpeglib.h> #include <setjmp.h> + +#if HAVE_FFMPEG_LIBAVUTIL_AVUTIL_H +#include <ffmpeg/libavutil/avutil.h> +#elif HAVE_LIBAV_LIBAVUTIL_AVUTIL_H +#include <libav/libavutil/avutil.h> +#elif HAVE_LIBAVUTIL_AVUTIL_H #include <libavutil/avutil.h> +#elif HAVE_FFMPEG_AVUTIL_H +#include <ffmpeg/avutil.h> +#elif HAVE_LIBAV_AVUTIL_H +#include <libav/avutil.h> +#elif HAVE_AVUTIL_H +#include <avutil.h> +#endif + +#if HAVE_FFMPEG_LIBAVCODEC_AVCODEC_H +#include <ffmpeg/libavcodec/avcodec.h> +#elif HAVE_LIBAV_LIBAVCODEC_AVCODEC_H +#include <libav/libavcodec/avcodec.h> +#elif HAVE_LIBAVCODEC_AVCODEC_H #include <libavcodec/avcodec.h> +#elif HAVE_FFMPEG_AVCODEC_H +#include <ffmpeg/avcodec.h> +#elif HAVE_LIBAV_AVCODEC_H +#include <libav/avcodec.h> +#elif HAVE_AVCODEC_H +#include <avcodec.h> +#endif + +#if HAVE_FFMPEG_LIBAVFORMAT_AVFORMAT_H +#include <ffmpeg/libavformat/avformat.h> +#elif HAVE_LIBAV_LIBAVFORMAT_AVFORMAT_H +#include <libav/libavformat/avformat.h> +#elif HAVE_LIBAVFORMAT_AVFORMAT_H #include <libavformat/avformat.h> -#include "tagutils/tagutils.h" +#elif HAVE_FFMPEG_AVFORMAT_H +#include <ffmpeg/avformat.h> +#elif HAVE_LIBAV_LIBAVFORMAT_H +#include <libav/avformat.h> +#elif HAVE_AVFORMAT_H +#include <avformat.h> +#endif #include "upnpglobalvars.h" #include "upnpreplyparse.h" @@ -150,7 +190,7 @@ is_tivo_file(const char * path) void check_for_captions(const char * path, sqlite_int64 detailID) { - char *file = malloc(PATH_MAX); + char *file = malloc(MAXPATHLEN); char *id = NULL; sprintf(file, "%s", path); @@ -655,10 +695,11 @@ GetVideoMetadata(const char * path, char * name) enum audio_profiles audio_profile = PROFILE_AUDIO_UNKNOWN; char fourcc[4]; sqlite_int64 album_art = 0; - char nfo[PATH_MAX], *ext; + char nfo[MAXPATHLEN], *ext; struct song_metadata video; metadata_t m; uint32_t free_flags = 0xFFFFFFFF; + char *path_cpy, *basepath; memset(&m, '\0', sizeof(m)); memset(&video, '\0', sizeof(video)); @@ -698,12 +739,15 @@ GetVideoMetadata(const char * path, char * name) continue; } } - /* This must not be a video file. */ + path_cpy = strdup(path); + basepath = basename(path_cpy); if( !vc ) { + /* This must not be a video file. */ 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", basepath); + free(path_cpy); return 0; } @@ -819,7 +863,7 @@ GetVideoMetadata(const char * path, char * name) int off; int duration, hours, min, sec, ms; ts_timestamp_t ts_timestamp = NONE; - 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, basepath); asprintf(&m.resolution, "%dx%d", vc->width, vc->height); if( ctx->bit_rate > 8 ) asprintf(&m.bitrate, "%u", ctx->bit_rate / 8); @@ -880,7 +924,7 @@ GetVideoMetadata(const char * path, char * name) int raw_packet_size; int dlna_ts_present = dlna_timestamp_is_present(path, &raw_packet_size); DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is %s MPEG2 TS packet size %d\n", - video_stream, basename(path), m.resolution, raw_packet_size); + video_stream, basepath, m.resolution, raw_packet_size); off += sprintf(m.dlna_pn+off, "TS_"); if( (vc->width >= 1280) && (vc->height >= 720) ) @@ -906,7 +950,7 @@ GetVideoMetadata(const char * path, char * name) else if( raw_packet_size != MPEG_TS_PACKET_LENGTH ) { DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n", - raw_packet_size, basename(path)); + raw_packet_size, basepath); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -928,7 +972,7 @@ GetVideoMetadata(const char * path, char * name) 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); + video_stream, basepath, m.resolution); off += sprintf(m.dlna_pn+off, "PS_"); if( (vc->height == 576) || (vc->height == 288) ) @@ -940,7 +984,7 @@ GetVideoMetadata(const char * path, char * name) else { DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s [%s] is %s non-DLNA MPEG2\n", - video_stream, basename(path), ctx->iformat->name, m.resolution); + video_stream, basepath, ctx->iformat->name, m.resolution); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -1019,7 +1063,7 @@ GetVideoMetadata(const char * path, char * name) vc->profile != FF_PROFILE_H264_MAIN ) { DPRINTF(E_DEBUG, L_METADATA, "Unknown AVC profile %d; assuming MP. [%s]\n", - vc->profile, basename(path)); + vc->profile, basepath); } if( vc->width <= 720 && vc->height <= 576 && @@ -1036,7 +1080,7 @@ GetVideoMetadata(const char * path, char * name) else { DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 video profile! [%s, %dx%d, %dbps : %s]\n", - m.dlna_pn, vc->width, vc->height, vc->bit_rate, basename(path)); + m.dlna_pn, vc->width, vc->height, vc->bit_rate, basepath); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -1053,7 +1097,7 @@ GetVideoMetadata(const char * path, char * name) else { DPRINTF(E_DEBUG, L_METADATA, "Unsupported h.264 HP video profile! [%dbps, %d audio : %s]\n", - vc->bit_rate, audio_profile, basename(path)); + vc->bit_rate, audio_profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -1077,7 +1121,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file [%s]\n", - m.dlna_pn, basename(path)); + m.dlna_pn, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1095,7 +1139,7 @@ GetVideoMetadata(const char * path, char * name) else if( raw_packet_size != MPEG_TS_PACKET_LENGTH ) { DPRINTF(E_DEBUG, L_METADATA, "Unsupported DLNA TS packet size [%d] (%s)\n", - raw_packet_size, basename(path)); + raw_packet_size, basepath); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -1223,7 +1267,7 @@ GetVideoMetadata(const char * path, char * name) if( strlen(m.dlna_pn) <= 11 ) { DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for %s file %s\n", - m.dlna_pn, basename(path)); + m.dlna_pn, basepath); free(m.dlna_pn); m.dlna_pn = NULL; } @@ -1239,7 +1283,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "AVC profile [%d] not recognized for file %s\n", - vc->profile, basename(path)); + vc->profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1252,7 +1296,7 @@ GetVideoMetadata(const char * path, char * name) } if( m.dlna_pn ) sprintf(m.dlna_pn+off, ";%s", dlna_no_conv); - 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, basepath); break; case CODEC_ID_MPEG4: fourcc[0] = vc->codec_tag & 0xff; @@ -1260,7 +1304,7 @@ GetVideoMetadata(const char * path, char * name) fourcc[2] = vc->codec_tag>>16 & 0xff; fourcc[3] = vc->codec_tag>>24 & 0xff; DPRINTF(E_DEBUG, L_METADATA, "Stream %d of %s is MPEG4 [%c%c%c%c/0x%X]\n", - video_stream, basename(path), + video_stream, basepath, isprint(fourcc[0]) ? fourcc[0] : '_', isprint(fourcc[1]) ? fourcc[1] : '_', isprint(fourcc[2]) ? fourcc[2] : '_', @@ -1285,7 +1329,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for MPEG4-P2 3GP/0x%X file %s\n", - ac->codec_id, basename(path)); + ac->codec_id, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1336,7 +1380,7 @@ GetVideoMetadata(const char * path, char * name) } m.dlna_pn = malloc(64); off = sprintf(m.dlna_pn, "WMV"); - 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, basepath); asprintf(&m.mime, "video/x-ms-wmv"); if( (vc->width <= 176) && (vc->height <= 144) && @@ -1353,7 +1397,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPLL/0x%X file %s\n", - audio_profile, basename(path)); + audio_profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1375,7 +1419,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVSPML/0x%X file %s\n", - audio_profile, basename(path)); + audio_profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1399,7 +1443,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVMED/0x%X file %s\n", - audio_profile, basename(path)); + audio_profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1420,7 +1464,7 @@ GetVideoMetadata(const char * path, char * name) break; default: DPRINTF(E_DEBUG, L_METADATA, "No DLNA profile found for WMVHIGH/0x%X file %s\n", - audio_profile, basename(path)); + audio_profile, basepath); free(m.dlna_pn); m.dlna_pn = NULL; break; @@ -1433,7 +1477,7 @@ GetVideoMetadata(const char * path, char * name) 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, vc->codec_id); + video_stream, basepath, m.resolution, vc->codec_id); break; } } @@ -1551,6 +1595,7 @@ video_no_dlna: check_for_captions(path, ret); } free_metadata(&m, free_flags); + free(path_cpy); return ret; } diff --git a/src/minidlna.c b/src/minidlna.c index 6974a42..0cc681d 100644 --- a/src/minidlna.c +++ b/src/minidlna.c @@ -58,15 +58,15 @@ #include <string.h> #include <stdio.h> #include <ctype.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <fcntl.h> +#include <sys/types.h> +#include <sys/socket.h> #include <sys/file.h> #include <sys/time.h> -#include <sys/stat.h> #include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <fcntl.h> #include <time.h> #include <signal.h> #include <errno.h> @@ -371,6 +371,7 @@ init(int argc, char * * argv) int i; int pid; int debug_flag = 0; + int verbose_flag = 0; int options_flag = 0; struct sigaction sa; /*const char * logfilename = 0;*/ @@ -382,6 +383,7 @@ init(int argc, char * * argv) char * path; char real_path[PATH_MAX]; char ip_addr[INET_ADDRSTRLEN + 3] = {'\0'}; + char log_str[72] = "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"; /* first check if "-f" option is used */ for(i=2; i<argc; i++) @@ -689,6 +691,11 @@ init(int argc, char * * argv) break; case 'd': debug_flag = 1; + case 'v': + verbose_flag = 1; + break; + case 'L': + SETFLAG(NO_PLAYLIST_MASK); break; case 'w': if(i+1 < argc) @@ -796,7 +803,7 @@ init(int argc, char * * argv) if( (n_lan_addr==0) || (runtime_vars.port<=0) ) { fprintf(stderr, "Usage:\n\t" - "%s [-d] [-f config_file]\n" + "%s [-d] [-v] [-f config_file]\n" "\t\t[-a listening_ip] [-p port]\n" /*"[-l logfile] " not functionnal */ "\t\t[-s serial] [-m model_number] \n" @@ -808,33 +815,29 @@ init(int argc, char * * argv) "\t-w sets the presentation url. Default is http address on port 80\n" "\t-h displays this text\n" "\t-R forces a full rescan\n" + "\t-L do note create playlists\n" "\t-V print the version number\n", argv[0], pidfilename); return 1; } + if( verbose_flag ) + strcpy(log_str+65, "debug"); if(debug_flag) { pid = getpid(); - log_init(NULL, "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=debug"); + log_init(NULL, log_str); } else { -#ifdef USE_DAEMON - if(daemon(0, 0)<0) { - perror("daemon()"); - } - pid = getpid(); -#else pid = daemonize(); -#endif #ifdef READYNAS - log_init("/var/log/upnp-av.log", "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"); + log_init("/var/log/upnp-av.log", log_str); #else if( access(db_path, F_OK) != 0 ) make_dir(db_path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); sprintf(real_path, "%s/minidlna.log", log_path); - log_init(real_path, "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn"); + log_init(real_path, log_str); #endif } @@ -875,7 +878,7 @@ init(int argc, char * * argv) /* 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)) @@ -961,7 +964,7 @@ main(int argc, char * * argv) { if( i < 0 ) { - DPRINTF(E_WARN, L_GENERAL, "Creating new database...\n"); + DPRINTF(E_WARN, L_GENERAL, "Creating new database at %s/files.db\n", db_path); } else { @@ -1009,12 +1012,13 @@ main(int argc, char * * argv) start_scanner(); #endif } +#ifdef HAVE_INOTIFY if( sqlite3_threadsafe() && sqlite3_libversion_number() >= 3005001 && GETFLAG(INOTIFY_MASK) && pthread_create(&inotify_thread, NULL, start_inotify, NULL) ) { DPRINTF(E_FATAL, L_GENERAL, "ERROR: pthread_create() failed for start_inotify.\n"); } - +#endif sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr); if(sudp < 0) { diff --git a/src/options.c b/src/options.c index 8bea46f..d34e0d6 100644 --- a/src/options.c +++ b/src/options.c @@ -76,7 +76,7 @@ readoptionsfile(const char * fname) int i; enum upnpconfigoptions id; - if(!fname || (strlen(fname) == 0)) + if(!fname || *fname == '\0') return -1; memset(buffer, 0, sizeof(buffer)); @@ -155,8 +155,17 @@ readoptionsfile(const char * fname) } else { - num_options += 1; - ary_options = (struct option *) realloc(ary_options, num_options * sizeof(struct option)); + num_options++; + t = realloc(ary_options, num_options * sizeof(struct option)); + if(!t) + { + fprintf(stderr, "memory allocation error: %s=%s\n", + name, value); + num_options--; + continue; + } + else + ary_options = (struct option *)t; ary_options[num_options-1].id = id; strncpy(ary_options[num_options-1].value, value, MAX_OPTION_VALUE_LEN); diff --git a/src/playlist.c b/src/playlist.c index 8dd3821..47a06c3 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -97,13 +97,12 @@ fill_playlists() sqlite_int64 plID, detailID; char sql_buf[] = "SELECT ID, NAME, PATH from PLAYLISTS where ITEMS > FOUND"; + DPRINTF(E_WARN, L_SCANNER, "Parsing playlists...\n"); + if( sql_get_table(db, sql_buf, &result, &rows, NULL) != SQLITE_OK ) return -1; if( !rows ) - { - sqlite3_free_table(result); - return 0; - } + goto done; rows++; for( i=3; i<rows*3; i++ ) @@ -145,7 +144,7 @@ fill_playlists() if( last_dir ) { fname = basename(plist.path); - detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%s/%s'", last_dir, fname); + detailID = sql_get_int_field(db, "SELECT ID from DETAILS where PATH = '%q/%q'", last_dir, fname); if( detailID <= 0 ) { sqlite3_free(last_dir); @@ -219,7 +218,9 @@ found: } sql_exec(db, "UPDATE PLAYLISTS set FOUND = %d where ID = %lld", found, plID); } +done: sqlite3_free_table(result); + DPRINTF(E_WARN, L_SCANNER, "Finished parsing playlists.\n"); return 0; } diff --git a/src/scanner.c b/src/scanner.c index cba696a..32e547f 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -24,6 +24,7 @@ #include <locale.h> #include <libgen.h> #include <inttypes.h> +#include <sys/param.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/resource.h> @@ -46,6 +47,12 @@ #include "albumart.h" #include "log.h" +#if SCANDIR_CONST +typedef const struct dirent scan_filter; +#else +typedef struct dirent scan_filter; +#endif + int valid_cache = 0; struct virtual_item @@ -264,7 +271,7 @@ insert_containers(const char * name, const char *path, const char * refID, const sql_exec(db, "INSERT into OBJECTS" " (OBJECT_ID, PARENT_ID, REF_ID, CLASS, DETAIL_ID, NAME) " "VALUES" - " ('%s$%"PRIX64"', '%s', '%s', '%s', %"PRId64", %Q)", + " ('%s$%llX', '%s', '%s', '%s', %lld, %Q)", last_album.parentID, last_album.objectID, last_album.parentID, refID, class, detailID, name); } if( artist ) @@ -495,8 +502,7 @@ insert_file(char * name, const char * path, const char * parentID, int object) strcpy(class, "item.audioItem.musicTrack"); detailID = GetAudioMetadata(path, name); } - if( orig_name ) - free(orig_name); + free(orig_name); if( !detailID ) { DPRINTF(E_WARN, L_SCANNER, "Unsuccessful getting details for %s!\n", path); @@ -658,7 +664,7 @@ sql_failed: } int -filter_audio(const struct dirent *d) +filter_audio(scan_filter *d) { return ( (*d->d_name != '.') && ((d->d_type == DT_DIR) || @@ -672,7 +678,7 @@ filter_audio(const struct dirent *d) } int -filter_video(const struct dirent *d) +filter_video(scan_filter *d) { return ( (*d->d_name != '.') && ((d->d_type == DT_DIR) || @@ -684,7 +690,7 @@ filter_video(const struct dirent *d) } int -filter_images(const struct dirent *d) +filter_images(scan_filter *d) { return ( (*d->d_name != '.') && ((d->d_type == DT_DIR) || @@ -696,7 +702,7 @@ filter_images(const struct dirent *d) } int -filter_media(const struct dirent *d) +filter_media(scan_filter *d) { return ( (*d->d_name != '.') && ((d->d_type == DT_DIR) || @@ -831,8 +837,16 @@ start_scanner() * client that uses UPnPSearch on large containers). */ sql_exec(db, "create INDEX IDX_SEARCH_OPT ON OBJECTS(OBJECT_ID, CLASS, DETAIL_ID);"); - fill_playlists(); + if( GETFLAG(NO_PLAYLIST_MASK) ) + { + DPRINTF(E_WARN, L_SCANNER, "Playlist creation disabled\n"); + } + else + { + fill_playlists(); + } + DPRINTF(E_DEBUG, L_SCANNER, "Initial file scan completed\n", DB_VERSION); //JM: Set up a db version number, so we know if we need to rebuild due to a new structure. sql_exec(db, "pragma user_version = %d;", DB_VERSION); } diff --git a/src/tagutils/misc.c b/src/tagutils/misc.c index 08e00ae..f439b8c 100644 --- a/src/tagutils/misc.c +++ b/src/tagutils/misc.c @@ -19,9 +19,14 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "config.h" #include <stdio.h> #include <string.h> +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#else #include <endian.h> +#endif #include "misc.h" diff --git a/src/tagutils/tagutils-asf.h b/src/tagutils/tagutils-asf.h index 5fd2942..91fcaa2 100644 --- a/src/tagutils/tagutils-asf.h +++ b/src/tagutils/tagutils-asf.h @@ -23,7 +23,11 @@ #define __PACKED__ __attribute__((packed)) +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#else #include <endian.h> +#endif typedef struct _GUID { __u32 l; diff --git a/src/tagutils/tagutils-misc.c b/src/tagutils/tagutils-misc.c index 9934e7a..eef242b 100644 --- a/src/tagutils/tagutils-misc.c +++ b/src/tagutils/tagutils-misc.c @@ -33,10 +33,10 @@ typedef enum { static iconv_result do_iconv(const char* to_ces, const char* from_ces, - char *inbuf, size_t inbytesleft, + ICONV_CONST char *inbuf, size_t inbytesleft, char *outbuf_orig, size_t outbytesleft_orig) { -#ifdef HAVE_ICONV_H +#ifdef HAVE_ICONV size_t rc; iconv_result ret = ICONV_OK; @@ -65,9 +65,9 @@ do_iconv(const char* to_ces, const char* from_ces, iconv_close(cd); return ret; -#else // HAVE_ICONV_H +#else // HAVE_ICONV return ICONV_FATAL; -#endif // HAVE_ICONV_H +#endif // HAVE_ICONV } #define N_LANG_ALT 8 diff --git a/src/tagutils/tagutils-mp3.c b/src/tagutils/tagutils-mp3.c index 643b349..6998147 100644 --- a/src/tagutils/tagutils-mp3.c +++ b/src/tagutils/tagutils-mp3.c @@ -232,8 +232,7 @@ _get_mp3tags(char *file, struct song_metadata *psong) if((utf8_text) && (strncasecmp((char*)utf8_text, "iTun", 4) != 0)) { // read comment - if(utf8_text) - free(utf8_text); + free(utf8_text); native_text = id3_field_getfullstring(&pid3frame->fields[3]); if(native_text) @@ -241,16 +240,14 @@ _get_mp3tags(char *file, struct song_metadata *psong) utf8_text = (unsigned char*)id3_ucs4_utf8duplicate(native_text); if(utf8_text) { - if (psong->comment) - free(psong->comment); + free(psong->comment); psong->comment = (char*)utf8_text; } } } else { - if(utf8_text) - free(utf8_text); + free(utf8_text); } } } diff --git a/src/tagutils/tagutils.c b/src/tagutils/tagutils.c index 7e147e7..9813bfc 100644 --- a/src/tagutils/tagutils.c +++ b/src/tagutils/tagutils.c @@ -37,7 +37,7 @@ #include <FLAC/metadata.h> #include "../config.h" -#ifdef HAVE_ICONV_H +#ifdef HAVE_ICONV #include <iconv.h> #endif diff --git a/src/tagutils/tagutils.h b/src/tagutils/tagutils.h index 0d5f362..0c884be 100644 --- a/src/tagutils/tagutils.h +++ b/src/tagutils/tagutils.h @@ -30,6 +30,7 @@ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> +#include <libgen.h> #define ROLE_NOUSE 0 #define ROLE_START 1 diff --git a/src/tivo_beacon.c b/src/tivo_beacon.c index f92fb6a..6dbc3a4 100644 --- a/src/tivo_beacon.c +++ b/src/tivo_beacon.c @@ -276,8 +276,9 @@ rcvBeaconMessage(char * beacon) if( strcasecmp(method, "broadcast") == 0 ) { - DPRINTF(E_DEBUG, L_TIVO, "Received new beacon: machine(%s) platform(%s) services(%s)\n", + DPRINTF(E_DEBUG, L_TIVO, "Received new beacon: machine(%s/%s) platform(%s) services(%s)\n", machine ? machine : "-", + identity ? identity : "-", platform ? platform : "-", services ? services : "-" ); return 1; diff --git a/src/tivo_commands.c b/src/tivo_commands.c index 90c47ef..a2156a3 100644 --- a/src/tivo_commands.c +++ b/src/tivo_commands.c @@ -24,6 +24,7 @@ #include <string.h> #include <libgen.h> #include <time.h> +#include <sys/stat.h> #include "tivo_utils.h" #include "upnpglobalvars.h" diff --git a/src/tivo_utils.c b/src/tivo_utils.c index a370f42..b481251 100644 --- a/src/tivo_utils.c +++ b/src/tivo_utils.c @@ -76,8 +76,7 @@ decodeString(char * string, int inplace) } if( inplace ) { - if( ns ) - free(ns); + free(ns); return string; } else diff --git a/src/upnpdescgen.c b/src/upnpdescgen.c index b7aed86..e6dcb03 100644 --- a/src/upnpdescgen.c +++ b/src/upnpdescgen.c @@ -586,7 +586,7 @@ static char * genXML(char * str, int * len, int * tmplen, const struct XMLElt * p) { - u_int16_t i, j, k; + uint16_t i, j, k; int top; const char * eltname, *s; char c; diff --git a/src/upnpevents.c b/src/upnpevents.c index f4c5564..51bee64 100644 --- a/src/upnpevents.c +++ b/src/upnpevents.c @@ -342,10 +342,7 @@ static void upnp_event_prepare(struct upnp_event_notify * obj) obj->sub->uuid, obj->sub->seq, l, xml); obj->buffersize = obj->tosend; - if(xml) { - free(xml); - xml = NULL; - } + free(xml); DPRINTF(E_DEBUG, L_HTTP, "Sending UPnP Event response:\n%s\n", obj->buffer); obj->state = ESending; } @@ -470,9 +467,7 @@ void upnpevents_processfds(fd_set *readset, fd_set *writeset) free(obj->sub); } #endif - if(obj->buffer) { - free(obj->buffer); - } + free(obj->buffer); LIST_REMOVE(obj, entries); free(obj); } diff --git a/src/upnpglobalvars.c b/src/upnpglobalvars.c index 9b9dda9..e7b2def 100644 --- a/src/upnpglobalvars.c +++ b/src/upnpglobalvars.c @@ -48,7 +48,7 @@ */ #include <sys/types.h> #include <netinet/in.h> -#include <linux/limits.h> +#include <sys/param.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -63,7 +63,7 @@ time_t startup_time = 0; struct runtime_vars_s runtime_vars; -int runtime_flags = INOTIFY_MASK; +uint32_t runtime_flags = INOTIFY_MASK; const char * pidfilename = "/var/run/minidlna.pid"; diff --git a/src/upnpglobalvars.h b/src/upnpglobalvars.h index 765f4e2..9fe2eda 100644 --- a/src/upnpglobalvars.h +++ b/src/upnpglobalvars.h @@ -177,10 +177,11 @@ extern time_t startup_time; extern struct runtime_vars_s runtime_vars; /* runtime boolean flags */ -extern int runtime_flags; +extern uint32_t runtime_flags; #define INOTIFY_MASK 0x0001 #define TIVO_MASK 0x0002 #define DLNA_STRICT_MASK 0x0004 +#define NO_PLAYLIST_MASK 0x0008 #define SETFLAG(mask) runtime_flags |= mask #define GETFLAG(mask) runtime_flags & mask diff --git a/src/upnphttp.c b/src/upnphttp.c index 714d34c..f72509a 100644 --- a/src/upnphttp.c +++ b/src/upnphttp.c @@ -54,6 +54,12 @@ #include <sys/socket.h> #include <sys/param.h> #include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <arpa/inet.h> + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ @@ -63,13 +69,6 @@ #include "upnpsoap.h" #include "upnpevents.h" -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/sendfile.h> -#include <arpa/inet.h> - #include "upnpglobalvars.h" #include "utils.h" #include "getifaddr.h" @@ -81,6 +80,9 @@ #include "tivo_utils.h" #include "tivo_commands.h" #endif + +#include "sendfile.h" + //#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much? #define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much? #define MIN_BUFFER_SIZE 65536 @@ -1172,14 +1174,17 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset) off_t send_size; off_t ret; char *buf = NULL; +#if HAVE_SENDFILE int try_sendfile = 1; +#endif while( offset < end_offset ) { +#if HAVE_SENDFILE if( try_sendfile ) { send_size = ( ((end_offset - offset) < MAX_BUFFER_SIZE) ? (end_offset - offset + 1) : MAX_BUFFER_SIZE); - ret = sendfile(h->socket, sendfd, &offset, send_size); + ret = sys_sendfile(h->socket, sendfd, &offset, send_size); if( ret == -1 ) { DPRINTF(E_DEBUG, L_HTTP, "sendfile error :: error no. %d [%s]\n", errno, strerror(errno)); @@ -1195,6 +1200,7 @@ send_file(struct upnphttp * h, int sendfd, off_t offset, off_t end_offset) continue; } } +#endif /* Fall back to regular I/O */ if( !buf ) buf = malloc(MIN_BUFFER_SIZE); diff --git a/src/upnphttp.h b/src/upnphttp.h index 83d5c70..4c534c3 100644 --- a/src/upnphttp.h +++ b/src/upnphttp.h @@ -121,6 +121,10 @@ struct upnphttp { #define FLAG_FREE_OBJECT_ID 0x00000001 #define FLAG_ROOT_CONTAINER 0x00000002 +#ifndef MSG_MORE +#define MSG_MORE 0 +#endif + /* New_upnphttp() */ struct upnphttp * New_upnphttp(int); diff --git a/src/upnpsoap.c b/src/upnpsoap.c index 981ded2..1329ca3 100644 --- a/src/upnpsoap.c +++ b/src/upnpsoap.c @@ -355,7 +355,7 @@ static u_int32_t set_filter_flags(char * filter, struct upnphttp *h) { char *item, *saveptr = NULL; - u_int32_t flags = 0; + uint32_t flags = 0; if( !filter || (strlen(filter) <= 1) ) return 0xFFFFFFFF; diff --git a/src/utils.c b/src/utils.c index 22fe37a..2757bf2 100644 --- a/src/utils.c +++ b/src/utils.c @@ -19,7 +19,7 @@ #include <ctype.h> #include <string.h> #include <stdlib.h> -#include <linux/limits.h> +#include <sys/param.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> @@ -193,6 +193,11 @@ make_dir(char * path, mode_t mode) do { c = '\0'; + /* Before we do anything, skip leading /'s, so we don't bother + * trying to create /. */ + while (*s == '/') + ++s; + /* Bypass leading non-'/'s and then subsequent '/'s. */ while (*s) { if (*s == '/') { @@ -28,22 +28,27 @@ #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 <errno.h> +#if HAVE_MACH_MACH_TIME_H +#include <mach/mach_time.h> +#elif HAVE_CLOCK_GETTIME_SYSCALL +#include <sys/syscall.h> +#endif #include "getifaddr.h" #include "log.h" #define ETH_ALEN 6 +#ifndef 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 uint32_t clock_seq; +static const uint32_t clock_seq_max = 0x3fff; /* 14 bits */ static int clock_seq_initialized; unsigned long long @@ -51,7 +56,17 @@ monotonic_us(void) { struct timespec ts; +#if defined(HAVE_LIBRT) + clock_gettime(CLOCK_MONOTONIC, &ts); +#elif HAVE_CLOCK_GETTIME_SYSCALL syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts); +#elif HAVE_MACH_MACH_TIME_H + return mach_absolute_time(); +#else + struct timeval tv; + gettimeofday(&tv, 0); + TIMEVAL_TO_TIMESPEC(&tv, &ts); +#endif return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000; } @@ -120,12 +135,12 @@ init_clockseq(void) int generate_uuid(unsigned char uuid_out[16]) { - static u_int64_t last_time_all; + static uint64_t last_time_all; 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; + uint64_t time_all; int inc_clock_seq = 0; unsigned char mac[6]; @@ -162,8 +177,16 @@ generate_uuid(unsigned char uuid_out[16]) * nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of * Gregorian reform to the Christian calendar). */ +#if HAVE_LIBRT + clock_gettime(CLOCK_REALTIME, &ts); +#elif HAVE_CLOCK_GETTIME_SYSCALL syscall(__NR_clock_gettime, CLOCK_REALTIME, &ts); - time_all = ((u_int64_t)ts.tv_sec) * (NSEC_PER_SEC / 100); +#else + struct timeval tv; + gettimeofday(&tv, 0); + TIMEVAL_TO_TIMESPEC(&tv, &ts); +#endif + time_all = ((uint64_t)ts.tv_sec) * (NSEC_PER_SEC / 100); time_all += ts.tv_nsec / 100; /* add offset from Gregorian Calendar to Jan 1 1970 */ @@ -192,14 +215,14 @@ generate_uuid(unsigned char uuid_out[16]) last_time_all = time_all; /* Fill in timestamp and clock_seq values */ - uuid_out[3] = (u_int8_t)time_all; - uuid_out[2] = (u_int8_t)(time_all >> 8); - uuid_out[1] = (u_int8_t)(time_all >> 16); - uuid_out[0] = (u_int8_t)(time_all >> 24); - uuid_out[5] = (u_int8_t)(time_all >> 32); - uuid_out[4] = (u_int8_t)(time_all >> 40); - uuid_out[7] = (u_int8_t)(time_all >> 48); - uuid_out[6] = (u_int8_t)(time_all >> 56); + uuid_out[3] = (uint8_t)time_all; + uuid_out[2] = (uint8_t)(time_all >> 8); + uuid_out[1] = (uint8_t)(time_all >> 16); + uuid_out[0] = (uint8_t)(time_all >> 24); + uuid_out[5] = (uint8_t)(time_all >> 32); + uuid_out[4] = (uint8_t)(time_all >> 40); + uuid_out[7] = (uint8_t)(time_all >> 48); + uuid_out[6] = (uint8_t)(time_all >> 56); uuid_out[8] = clock_seq >> 8; uuid_out[9] = clock_seq & 0xff; |