portability or VDR on FreeBSD

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


Hello list.

As the subject already says, this is about VDR portability, or how to get VDR up and running on a FreeBSD system. In times where we have such really nice plugins like softdevice and streamdev, we no longer need real MPEG2 or DVB hardware in a VDR system. As i want to use my FreeBSD systems to watch TV or play VDR recordings i decided to give porting VDR to FreeBSD a try.
Attached you can find the results.
In short terms: It simply works!
The only missing feature right now is, starting VDR as root and switching to another user (-u command line option). For now it is possible to watch any recording made by a VDR with real hardware if the video directory is directly accessible over the network (mountable by the client) or the use the streamdev plugin to stream VDR to VDR. All tests where done using a Linux system with two FF-DVB-S devices, streamdev-server plugin and NFS exported video directory plus a wired and a wireless FreeBSD-7.0 client running VDR with streamdev-client and softdevice plugin. As far as i could test the whole setup until now, everything works the same way on FreeBSD as it does under Linux and i now have real channel-hopping.

The patches are made in a way that a patched VDR will still compile under Linux. Every modification, to the source or to the Makefiles is ifdef'd out. So unless you say you want to compile VDR for FreeBSD you have an unmodified version of source.

In case the ML software strips the attachments, the files are also available for download at: ftp://ftp.frm2.tum.de/pub/jpulz/VDR/

Thoughts or comments from others are welcome.

regards
Joerg

- -- The beginning is the most important part of the work.
 				-Plato
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQFH0Dy8SPOsGF+KA+MRAmVBAJ9Tzfxg0zWNN/fEX8vfeMOW2muvSACgivha
raTzC4R92jZ+Petp9Mqwr9E=
=f08n
-----END PGP SIGNATURE-----
diff -urN vdr-1.5.17.orig/Make.config.template vdr-1.5.17/Make.config.template
--- vdr-1.5.17.orig/Make.config.template	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/Make.config.template	2008-03-06 18:17:31.000000000 +0100
@@ -23,20 +23,35 @@
 
 ### The directory environment:
 
-#DVBDIR   = /usr/src/v4l-dvb/linux
-MANDIR   = /usr/local/man
-BINDIR   = /usr/local/bin
+PREFIX   = /usr/local
+MANDIR   = $(PREFIX)/man
+BINDIR   = $(PREFIX)/bin
 
-LOCDIR   = ./locale
 PLUGINDIR= ./PLUGINS
-PLUGINLIBDIR= $(PLUGINDIR)/lib
 VIDEODIR = /video
+
+ifdef FREEBSD
+# you have to set DVBDIR to a valid path!!!
+# you will need extra patches for DVBDIR!!!
+DVBDIR   = /usr/src/v4l-dvb/linux
+LOCDIR   = $(PREFIX)/share/locale
+CONFDIR  = $(PREFIX)/etc/vdr
+PLUGINLIBDIR= $(PREFIX)/lib/vdr
+else
+#DVBDIR   = /usr/src/v4l-dvb/linux
+LOCDIR   = ./locale
 CONFDIR  = $(VIDEODIR)
+PLUGINLIBDIR= $(PLUGINDIR)/lib
+endif
 
 ### The remote control:
 
 LIRC_DEVICE = /dev/lircd
+ifdef FREEBSD
+RCU_DEVICE  = /dev/cuad0
+else
 RCU_DEVICE  = /dev/ttyS1
+endif
 
 ## Define if you want vdr to not run as root
 #VDR_USER = vdr
@@ -46,3 +61,8 @@
 ifdef DVBDIR
 INCLUDES += -I$(DVBDIR)/include
 endif
+
+ifdef FREEBSD
+INCLUDES += -I/usr/local/include
+DEFINES += -DFreeBSD
+endif
diff -urN vdr-1.5.17.orig/Makefile vdr-1.5.17/Makefile
--- vdr-1.5.17.orig/Makefile	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/Makefile	2008-03-06 19:08:25.000000000 +0100
@@ -20,8 +20,14 @@
 MANDIR   = $(PREFIX)/share/man
 BINDIR   = $(PREFIX)/bin
 LOCDIR   = ./locale
+ifdef FREEBSD
+INCLUDES = -I/usr/local/include/freetype2
+LDFLAGS  = -L/usr/local/lib
+LIBS     = -ljpeg -lpthread -lrt -lfreetype -lfontconfig -liconv -lintl
+else
 LIBS     = -ljpeg -lpthread -ldl -lcap -lrt -lfreetype -lfontconfig
 INCLUDES = -I/usr/include/freetype2
+endif
 
 PLUGINDIR= ./PLUGINS
 PLUGINLIBDIR= $(PLUGINDIR)/lib
@@ -43,6 +49,10 @@
        skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\
        timers.o tools.o transfer.o vdr.o videodir.o
 
+ifdef FREEBSD
+OBJS += getline.o strndup.o
+endif
+
 ifndef NO_KBD
 DEFINES += -DREMOTE_KBD
 endif
@@ -94,12 +104,16 @@
 # The main program:
 
 vdr: $(OBJS) $(SILIB)
-	$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
+	$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) $(LDFLAGS) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
 
 # The libsi library:
 
 $(SILIB):
+ifdef FREEBSD
+	$(MAKE) -C $(LSIDIR) all FREEBSD=1
+else
 	$(MAKE) -C $(LSIDIR) all
+endif
 
 # Internationalization (I18N):
 
@@ -128,7 +142,11 @@
 
 install-i18n:
 	@mkdir -p $(DESTDIR)$(LOCDIR)
+ifdef FREEBSD
+	@(cd $(LOCALEDIR); cp -R * $(DESTDIR)$(LOCDIR))
+else
 	@(cd $(LOCALEDIR); cp -r --parents * $(DESTDIR)$(LOCDIR))
+endif
 
 # The 'include' directory (for plugins):
 
@@ -167,7 +185,11 @@
 
 install-bin: vdr
 	@mkdir -p $(DESTDIR)$(BINDIR)
+ifdef FREEBSD
+	@cp -f vdr runvdr svdrpsend.pl $(DESTDIR)$(BINDIR)
+else
 	@cp --remove-destination vdr runvdr svdrpsend.pl $(DESTDIR)$(BINDIR)
+endif
 
 # Configuration files:
 
@@ -190,7 +212,11 @@
 
 install-plugins: plugins
 	@mkdir -p $(DESTDIR)$(PLUGINLIBDIR)
+ifdef FREEBSD
+	@cp -v $(PLUGINDIR)/lib/lib*-*.so.$(APIVERSION) $(DESTDIR)$(PLUGINLIBDIR)
+else
 	@cp --remove-destination $(PLUGINDIR)/lib/lib*-*.so.$(APIVERSION) $(DESTDIR)$(PLUGINLIBDIR)
+endif
 
 # Source documentation:
 
diff -urN vdr-1.5.17.orig/PLUGINS/src/hello/Makefile vdr-1.5.17/PLUGINS/src/hello/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/hello/Makefile	2008-03-06 16:57:04.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/hello/Makefile	2008-03-06 17:08:01.000000000 +0100
@@ -96,7 +96,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/osddemo/Makefile vdr-1.5.17/PLUGINS/src/osddemo/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/osddemo/Makefile	2008-03-06 16:57:04.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/osddemo/Makefile	2008-03-06 17:08:14.000000000 +0100
@@ -69,7 +69,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/pictures/Makefile vdr-1.5.17/PLUGINS/src/pictures/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/pictures/Makefile	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/pictures/Makefile	2008-03-06 17:08:26.000000000 +0100
@@ -96,7 +96,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/servicedemo/Makefile vdr-1.5.17/PLUGINS/src/servicedemo/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/servicedemo/Makefile	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/servicedemo/Makefile	2008-03-06 17:08:48.000000000 +0100
@@ -71,11 +71,19 @@
 
 libvdr-$(PLUGIN1).so: $(PLUGIN1).o
 	$(CXX) $(CXXFLAGS) -shared $(PLUGIN1).o -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 libvdr-$(PLUGIN2).so: $(PLUGIN2).o
 	$(CXX) $(CXXFLAGS) -shared $(PLUGIN2).o -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/skincurses/Makefile vdr-1.5.17/PLUGINS/src/skincurses/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/skincurses/Makefile	2008-03-06 16:57:04.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/skincurses/Makefile	2008-03-06 17:08:55.000000000 +0100
@@ -96,7 +96,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -lncursesw -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/sky/Makefile vdr-1.5.17/PLUGINS/src/sky/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/sky/Makefile	2008-03-06 16:57:04.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/sky/Makefile	2008-03-06 17:09:03.000000000 +0100
@@ -69,7 +69,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/status/Makefile vdr-1.5.17/PLUGINS/src/status/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/status/Makefile	2008-03-06 16:57:04.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/status/Makefile	2008-03-06 17:09:11.000000000 +0100
@@ -69,7 +69,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/PLUGINS/src/svdrpdemo/Makefile vdr-1.5.17/PLUGINS/src/svdrpdemo/Makefile
--- vdr-1.5.17.orig/PLUGINS/src/svdrpdemo/Makefile	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/PLUGINS/src/svdrpdemo/Makefile	2008-03-06 17:09:17.000000000 +0100
@@ -69,7 +69,11 @@
 
 libvdr-$(PLUGIN).so: $(OBJS)
 	$(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ifdef FREEBSD
+	@cp -f $@ $(LIBDIR)/$@.$(APIVERSION)
+else
 	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+endif
 
 dist: clean
 	@-rm -rf $(TMPDIR)/$(ARCHIVE)
diff -urN vdr-1.5.17.orig/channels.c vdr-1.5.17/channels.c
--- vdr-1.5.17.orig/channels.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/channels.c	2008-03-06 16:57:37.000000000 +0100
@@ -134,7 +134,12 @@
   int tid;
   int sid;
   int rid = 0;
+#ifdef FreeBSD
+  sourcebuf = MALLOC(char, 10);
+  int fields = sscanf(s, "%9[^-]-%d-%d-%d-%d", sourcebuf, &nid, &tid, &sid, &rid);
+#else
   int fields = sscanf(s, "%a[^-]-%d-%d-%d-%d", &sourcebuf, &nid, &tid, &sid, &rid);
+#endif
   if (fields == 4 || fields == 5) {
      int source = cSource::FromString(sourcebuf);
      free(sourcebuf);
@@ -720,7 +725,17 @@
      char *vpidbuf = NULL;
      char *apidbuf = NULL;
      char *caidbuf = NULL;
+#ifdef FreeBSD
+     namebuf = MALLOC(char, 256);
+     sourcebuf = MALLOC(char, 10);
+     parambuf = MALLOC(char, 256);
+     vpidbuf = MALLOC(char, 256);
+     apidbuf = MALLOC(char, 256);
+     caidbuf = MALLOC(char, 256);
+     int fields = sscanf(s, "%255[^:]:%d :%255[^:]:%9[^:] :%d :%255[^:]:%255[^:]:%d :%255[^:]:%d :%d :%d :%d ", namebuf, &frequency, parambuf, sourcebuf, &srate, vpidbuf, apidbuf, &tpid, caidbuf, &sid, &nid, &tid, &rid);
+#else
      int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid);
+#endif
      if (fields >= 9) {
         if (fields == 9) {
            // allow reading of old format
diff -urN vdr-1.5.17.orig/ci.c vdr-1.5.17/ci.c
--- vdr-1.5.17.orig/ci.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/ci.c	2008-03-06 16:57:37.000000000 +0100
@@ -10,7 +10,11 @@
 #include "ci.h"
 #include <ctype.h>
 #include <linux/dvb/ca.h>
+#ifdef FreeBSD
+#include <stdlib.h>
+#else
 #include <malloc.h>
+#endif
 #include <netinet/in.h>
 #include <poll.h>
 #include <string.h>
diff -urN vdr-1.5.17.orig/diseqc.c vdr-1.5.17/diseqc.c
--- vdr-1.5.17.orig/diseqc.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/diseqc.c	2008-03-06 16:57:37.000000000 +0100
@@ -30,7 +30,14 @@
 {
   bool result = false;
   char *sourcebuf = NULL;
+#ifdef FreeBSD
+  sourcebuf = MALLOC(char, 10);
+  if (commands == NULL)
+	commands = MALLOC(char, 256);
+  int fields = sscanf(s, "%9[^ ] %d %c %d %255[^\n]", sourcebuf, &slof, &polarization, &lof, commands);
+#else
   int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands);
+#endif
   if (fields == 4)
      commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string
   if (4 <= fields && fields <= 5) {
diff -urN vdr-1.5.17.orig/eit.c vdr-1.5.17/eit.c
--- vdr-1.5.17.orig/eit.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/eit.c	2008-03-06 16:57:37.000000000 +0100
@@ -300,10 +300,19 @@
   if (diff > 2) {
      mutex.Lock();
      if (abs(diff - lastDiff) < 3) {
+#ifdef FreeBSD
+        isyslog("System Time = %s (%d)", *TimeToString(loctim), loctim);
+        isyslog("Local Time  = %s (%d)", *TimeToString(sattim), sattim);
+#else
         isyslog("System Time = %s (%ld)", *TimeToString(loctim), loctim);
         isyslog("Local Time  = %s (%ld)", *TimeToString(sattim), sattim);
+#endif
+#ifdef FreeBSD
+        esyslog("stime() not available on FreeBSD, maybe use adjtime()?");
+#else
         if (stime(&sattim) < 0)
            esyslog("ERROR while setting system time: %m");
+#endif
         }
      lastDiff = diff;
      mutex.Unlock();
diff -urN vdr-1.5.17.orig/epg.c vdr-1.5.17/epg.c
--- vdr-1.5.17.orig/epg.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/epg.c	2008-03-06 16:57:37.000000000 +0100
@@ -258,7 +258,11 @@
 void cEvent::Dump(FILE *f, const char *Prefix, bool InfoOnly) const
 {
   if (InfoOnly || startTime + duration + Setup.EPGLinger * 60 >= time(NULL)) {
+#ifdef FreeBSD
+     fprintf(f, "%sE %u %d %d %X %X\n", Prefix, eventID, startTime, duration, tableID, version);
+#else
      fprintf(f, "%sE %u %ld %d %X %X\n", Prefix, eventID, startTime, duration, tableID, version);
+#endif
      if (!isempty(title))
         fprintf(f, "%sT %s\n", Prefix, title);
      if (!isempty(shortText))
@@ -277,7 +281,11 @@
             }
         }
      if (vps)
+#ifdef FreeBSD
+        fprintf(f, "%sV %d\n", Prefix, vps);
+#else
         fprintf(f, "%sV %ld\n", Prefix, vps);
+#endif
      if (!InfoOnly)
         fprintf(f, "%se\n", Prefix);
      }
@@ -323,7 +331,11 @@
                           int Duration;
                           unsigned int TableID = 0;
                           unsigned int Version = 0xFF; // actual value is ignored
+#ifdef FreeBSD
+                          int n = sscanf(t, "%u %d %d %X %X", &EventID, &StartTime, &Duration, &TableID, &Version);
+#else
                           int n = sscanf(t, "%u %ld %d %X %X", &EventID, &StartTime, &Duration, &TableID, &Version);
+#endif
                           if (n >= 3 && n <= 5) {
                              Event = (cEvent *)Schedule->GetEvent(EventID, StartTime);
                              cEvent *newEvent = NULL;
diff -urN vdr-1.5.17.orig/getline.c vdr-1.5.17/getline.c
--- vdr-1.5.17.orig/getline.c	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.17/getline.c	2008-03-06 16:57:37.000000000 +0100
@@ -0,0 +1,158 @@
+/* getline.c -- Replacement for GNU C library function getline
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.  */
+
+/* Written by Jan Brittenson, bson@xxxxxxxxxxxxxxx  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include "getline.h"
+#include "tools.h"
+
+#include <stdlib.h>
+
+/* Always add at least this many bytes when extending the buffer.  */
+#define MIN_CHUNK 64
+
+/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
+   + OFFSET (and null-terminate it).  If LIMIT is non-negative, then
+   read no more than LIMIT chars.
+
+   *LINEPTR is a pointer returned from malloc (or NULL), pointing to
+   *N characters of space.  It is realloc'd as necessary.  
+
+   Return the number of characters read (not including the null
+   terminator), or -1 on error or EOF.  On a -1 return, the caller
+   should check feof(), if not then errno has been set to indicate the
+   error.  */
+
+int
+getstr (char **lineptr, size_t *n, FILE *stream, int terminator, int offset, int limit)
+{
+  int nchars_avail;		/* Allocated but unused chars in *LINEPTR.  */
+  char *read_pos;		/* Where we're reading into *LINEPTR. */
+  int ret;
+
+  if (!lineptr || !n || !stream)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (!*lineptr)
+    {
+      *n = MIN_CHUNK;
+      *lineptr = MALLOC(char, *n);
+      if (!*lineptr)
+	{
+	  errno = ENOMEM;
+	  return -1;
+	}
+      *lineptr[0] = '\0';
+    }
+
+  nchars_avail = *n - offset;
+  read_pos = *lineptr + offset;
+
+  for (;;)
+    {
+      int save_errno;
+      register int c;
+
+      if (limit == 0)
+          break;
+      else
+      {
+          c = getc (stream);
+
+          /* If limit is negative, then we shouldn't pay attention to
+             it, so decrement only if positive. */
+          if (limit > 0)
+              limit--;
+      }
+
+      save_errno = errno;
+
+      /* We always want at least one char left in the buffer, since we
+	 always (unless we get an error while reading the first char)
+	 NUL-terminate the line buffer.  */
+
+      assert((*lineptr + *n) == (read_pos + nchars_avail));
+      if (nchars_avail < 2)
+	{
+	  if (*n > MIN_CHUNK)
+	    *n *= 2;
+	  else
+	    *n += MIN_CHUNK;
+
+	  nchars_avail = *n + *lineptr - read_pos;
+	  *lineptr = (char*)realloc (*lineptr, *n);
+	  if (!*lineptr)
+	    {
+	      errno = ENOMEM;
+	      return -1;
+	    }
+	  read_pos = *n - nchars_avail + *lineptr;
+	  assert((*lineptr + *n) == (read_pos + nchars_avail));
+	}
+
+      if (ferror (stream))
+	{
+	  /* Might like to return partial line, but there is no
+	     place for us to store errno.  And we don't want to just
+	     lose errno.  */
+	  errno = save_errno;
+	  return -1;
+	}
+
+      if (c == EOF)
+	{
+	  /* Return partial line, if any.  */
+	  if (read_pos == *lineptr)
+	    return -1;
+	  else
+	    break;
+	}
+
+      *read_pos++ = c;
+      nchars_avail--;
+
+      if (c == terminator)
+	/* Return the line.  */
+	break;
+    }
+
+  /* Done - NUL terminate and return the number of chars read.  */
+  *read_pos = '\0';
+
+  ret = read_pos - (*lineptr + offset);
+  return ret;
+}
+
+int
+getline (char **lineptr, size_t *n, FILE *stream)
+{
+  return getstr (lineptr, n, stream, '\n', 0, GETLINE_NO_LIMIT);
+}
+
+int
+getline_safe (char **lineptr, size_t *n, FILE *stream, int limit)
+{
+  return getstr (lineptr, n, stream, '\n', 0, limit);
+}
diff -urN vdr-1.5.17.orig/getline.h vdr-1.5.17/getline.h
--- vdr-1.5.17.orig/getline.h	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.17/getline.h	2008-03-06 16:57:37.000000000 +0100
@@ -0,0 +1,23 @@
+#ifndef _getline_h_
+#define _getline_h_ 1
+
+#include <stdio.h>
+
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __PROTO(args) args
+#else
+#define __PROTO(args) ()
+#endif  /* GCC.  */
+
+#define GETLINE_NO_LIMIT -1
+
+int
+  getline __PROTO ((char **_lineptr, size_t *_n, FILE *_stream));
+int
+  getline_safe __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
+                         int limit));
+int
+  getstr __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
+		   int _terminator, int _offset, int limit));
+
+#endif /* _getline_h_ */
diff -urN vdr-1.5.17.orig/i18n.h vdr-1.5.17/i18n.h
--- vdr-1.5.17.orig/i18n.h	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/i18n.h	2008-03-06 16:57:37.000000000 +0100
@@ -48,7 +48,11 @@
    ///< have an actual locale installed. The rest are just dummy entries
    ///< to allow having three letter language codes for other languages
    ///< that have no actual locale on this system.
+#ifdef FreeBSD
+const char *I18nTranslate(const char *s, const char *Plugin = NULL) __format_arg(1);
+#else
 const char *I18nTranslate(const char *s, const char *Plugin = NULL) __attribute_format_arg__(1);
+#endif
    ///< Translates the given string (with optional Plugin context) into
    ///< the current language. If no translation is available, the original
    ///< string will be returned.
diff -urN vdr-1.5.17.orig/libsi/Makefile vdr-1.5.17/libsi/Makefile
--- vdr-1.5.17.orig/libsi/Makefile	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/libsi/Makefile	2008-03-06 16:57:37.000000000 +0100
@@ -15,9 +15,13 @@
 
 ### The directory environment:
 
+ifdef FREEBSD
+INCLUDES += -I/usr/local/include
+DEFINES += -DFreeBSD
+else
 INCLUDES +=
-
 DEFINES +=
+endif
 
 LIBS +=
 
diff -urN vdr-1.5.17.orig/libsi/headers.h vdr-1.5.17/libsi/headers.h
--- vdr-1.5.17.orig/libsi/headers.h	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/libsi/headers.h	2008-03-06 16:57:37.000000000 +0100
@@ -17,7 +17,11 @@
 #ifndef LIBSI_HEADERS_H
 #define LIBSI_HEADERS_H
 
+#ifdef FreeBSD
+#include <sys/endian.h>
+#else
 #include <endian.h>
+#endif
 
 namespace SI {
 
diff -urN vdr-1.5.17.orig/libsi/si.c vdr-1.5.17/libsi/si.c
--- vdr-1.5.17.orig/libsi/si.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/libsi/si.c	2008-03-06 17:21:15.000000000 +0100
@@ -13,7 +13,11 @@
 #include "si.h"
 #include <errno.h>
 #include <iconv.h>
+#ifdef FreeBSD
+#include <stdlib.h>
+#else
 #include <malloc.h>
+#endif
 #include <string.h>
 #include "descriptor.h"
 
@@ -376,7 +380,11 @@
   if (SystemCharacterTable) {
      iconv_t cd = iconv_open(SystemCharacterTable, fromCode);
      if (cd != (iconv_t)-1) {
-        char *fromPtr = (char *)from;
+#ifdef FreeBSD
+        const char *fromPtr = from;
+#else
+        char *fromPtr = from;
+#endif
         while (fromLength > 0 && toLength > 1) {
            if (iconv(cd, &fromPtr, &fromLength, &to, &toLength) == size_t(-1)) {
               if (errno == EILSEQ) {
diff -urN vdr-1.5.17.orig/menu.c vdr-1.5.17/menu.c
--- vdr-1.5.17.orig/menu.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/menu.c	2008-03-06 16:57:37.000000000 +0100
@@ -29,6 +29,9 @@
 #include "timers.h"
 #include "transfer.h"
 #include "videodir.h"
+#ifdef FreeBSD
+#include "strndup.h"
+#endif
 
 #define MAXWAIT4EPGINFO   3 // seconds
 #define MODETIMEOUT       3 // seconds
diff -urN vdr-1.5.17.orig/menuitems.c vdr-1.5.17/menuitems.c
--- vdr-1.5.17.orig/menuitems.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/menuitems.c	2008-03-06 16:57:37.000000000 +0100
@@ -763,7 +763,11 @@
      struct tm tm_r;
      localtime_r(value, &tm_r);
      strftime(buf, DATEBUFFERSIZE, "%Y-%m-%d ", &tm_r);
+#ifdef FreeBSD
+     strcat(buf, WeekDayNameReal(tm_r.tm_wday));
+#else
      strcat(buf, WeekDayName(tm_r.tm_wday));
+#endif
      }
   else
      *buf = 0;
diff -urN vdr-1.5.17.orig/pat.c vdr-1.5.17/pat.c
--- vdr-1.5.17.orig/pat.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/pat.c	2008-03-06 16:57:37.000000000 +0100
@@ -8,7 +8,11 @@
  */
 
 #include "pat.h"
+#ifdef FreeBSD
+#include <stdlib.h>
+#else
 #include <malloc.h>
+#endif
 #include "channels.h"
 #include "libsi/section.h"
 #include "libsi/descriptor.h"
diff -urN vdr-1.5.17.orig/recording.c vdr-1.5.17/recording.c
--- vdr-1.5.17.orig/recording.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/recording.c	2008-03-06 16:57:37.000000000 +0100
@@ -370,7 +370,11 @@
                          int Duration;
                          unsigned int TableID = 0;
                          unsigned int Version = 0xFF;
+#ifdef FreeBSD
+                         int n = sscanf(t, "%u %d %d %X %X", &EventID, &StartTime, &Duration, &TableID, &Version);
+#else
                          int n = sscanf(t, "%u %ld %d %X %X", &EventID, &StartTime, &Duration, &TableID, &Version);
+#endif
                          if (n >= 3 && n <= 5) {
                             ownEvent->SetEventID(EventID);
                             ownEvent->SetStartTime(StartTime);
@@ -1204,7 +1208,11 @@
               delta = buf.st_size % sizeof(tIndex);
               if (delta) {
                  delta = sizeof(tIndex) - delta;
+#ifdef FreeBSD
+                 esyslog("ERROR: invalid file size (%ld) in '%s'", (long int)buf.st_size, fileName);
+#else
                  esyslog("ERROR: invalid file size (%ld) in '%s'", buf.st_size, fileName);
+#endif
                  }
               last = (buf.st_size + delta) / sizeof(tIndex) - 1;
               if (!Record && last >= 0) {
diff -urN vdr-1.5.17.orig/shutdown.c vdr-1.5.17/shutdown.c
--- vdr-1.5.17.orig/shutdown.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/shutdown.c	2008-03-06 16:57:37.000000000 +0100
@@ -116,7 +116,11 @@
      }
   else {
      // Set inactive from now on
+#ifdef FreeBSD
+     dsyslog("scheduled wakeup time in %d minutes, assuming automatic start of VDR", Delta / 60);
+#else
      dsyslog("scheduled wakeup time in %ld minutes, assuming automatic start of VDR", Delta / 60);
+#endif
      SetUserInactive();
      }
 }
@@ -130,7 +134,11 @@
 void cShutdownHandler::CallShutdownCommand(time_t WakeupTime, int Channel, const char *File, bool UserShutdown)
 {
   time_t Delta = WakeupTime ? WakeupTime - time(NULL) : 0;
+#ifdef FreeBSD
+  cString cmd = cString::sprintf("%s %d %d %d \"%s\" %d", shutdownCommand, WakeupTime, Delta, Channel, *strescape(File, "\\\"$"), UserShutdown);
+#else
   cString cmd = cString::sprintf("%s %ld %ld %d \"%s\" %d", shutdownCommand, WakeupTime, Delta, Channel, *strescape(File, "\\\"$"), UserShutdown);
+#endif
   isyslog("executing '%s'", *cmd);
   int Status = SystemExec(cmd, true);
   if (!WIFEXITED(Status) || WEXITSTATUS(Status))
@@ -180,7 +188,11 @@
      // Timer within Min Event Timeout
      if (!Interactive)
         return false;
+#ifdef FreeBSD
+     cString buf = cString::sprintf(tr("Recording in %d minutes, shut down anyway?"), Delta / 60);
+#else
      cString buf = cString::sprintf(tr("Recording in %ld minutes, shut down anyway?"), Delta / 60);
+#endif
      if (!Interface->Confirm(buf))
         return false;
      }
@@ -195,7 +207,11 @@
      // Plugin wakeup within Min Event Timeout
      if (!Interactive)
         return false;
+#ifdef FreeBSD
+     cString buf = cString::sprintf(tr("Plugin %s wakes up in %d min, continue?"), Plugin->Name(), Delta / 60);
+#else
      cString buf = cString::sprintf(tr("Plugin %s wakes up in %ld min, continue?"), Plugin->Name(), Delta / 60);
+#endif
      if (!Interface->Confirm(buf))
         return false;
      }
diff -urN vdr-1.5.17.orig/skins.c vdr-1.5.17/skins.c
--- vdr-1.5.17.orig/skins.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/skins.c	2008-03-06 16:57:37.000000000 +0100
@@ -11,6 +11,20 @@
 #include "interface.h"
 #include "status.h"
 
+#ifdef FreeBSD
+/* XXX Implement strchrnul for FreeBSD. */
+static char *
+strchrnul (const char *s, int c_in)
+{
+  char c = c_in;
+  while (*s && (*s != c))
+    s++;
+
+  return (char *) s;
+}
+#endif
+
+
 // --- cSkinQueuedMessage ----------------------------------------------------
 
 class cSkinQueuedMessage : public cListObject {
diff -urN vdr-1.5.17.orig/sources.c vdr-1.5.17/sources.c
--- vdr-1.5.17.orig/sources.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/sources.c	2008-03-06 16:57:37.000000000 +0100
@@ -26,7 +26,14 @@
 bool cSource::Parse(const char *s)
 {
   char *codeBuf = NULL;
+#ifdef FreeBSD
+  codeBuf = MALLOC(char, 10);
+  if (description == NULL)
+	description = MALLOC(char, 256);
+  if (2 == sscanf(s, "%9[^ ] %255[^\n]", codeBuf, description))
+#else
   if (2 == sscanf(s, "%a[^ ] %a[^\n]", &codeBuf, &description))
+#endif
      code = FromString(codeBuf);
   free(codeBuf);
   return code != stNone && description && *description;
diff -urN vdr-1.5.17.orig/strndup.c vdr-1.5.17/strndup.c
--- vdr-1.5.17.orig/strndup.c	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.17/strndup.c	2008-03-06 16:57:38.000000000 +0100
@@ -0,0 +1,15 @@
+/* XXX Implement strndup for FreeBSD. */
+#include <string.h>
+#include "tools.h"
+
+const char *
+strndup(const char *str, size_t len) {
+       char *ret;
+
+       if ((str == NULL || len < 0)) return(NULL);
+       ret = MALLOC(char, len + 1);
+       if (ret == NULL) return(NULL);
+       strncpy(ret, str, len);
+       ret[len] = '\0';
+       return(ret);
+}
diff -urN vdr-1.5.17.orig/strndup.h vdr-1.5.17/strndup.h
--- vdr-1.5.17.orig/strndup.h	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.5.17/strndup.h	2008-03-06 16:57:38.000000000 +0100
@@ -0,0 +1,13 @@
+#ifndef _strndup_h_
+#define _strndup_h_ 1
+
+#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
+#define __PROTO(args) args
+#else
+#define __PROTO(args) ()
+#endif  /* GCC.  */
+
+const char *
+  strndup __PROTO ((const char *str, size_t len));
+
+#endif /* _strndup_h_ */
diff -urN vdr-1.5.17.orig/svdrp.c vdr-1.5.17/svdrp.c
--- vdr-1.5.17.orig/svdrp.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/svdrp.c	2008-03-06 16:57:37.000000000 +0100
@@ -40,6 +40,12 @@
 #include "tools.h"
 #include "videodir.h"
 
+/* FreeBSD has it's own version of isnumber(),
+   but VDR's version is incompatible */
+#ifdef FreeBSD
+#undef isnumber
+#endif
+
 // --- cSocket ---------------------------------------------------------------
 
 cSocket::cSocket(int Port, int Queue)
@@ -1309,9 +1315,17 @@
      if (!*Option)
         Reply(250, "%d %s", Number, *TimeToString(Start));
      else if (strcasecmp(Option, "ABS") == 0)
+#ifdef FreeBSD
+        Reply(250, "%d %d", Number, Start);
+#else
         Reply(250, "%d %ld", Number, Start);
+#endif
      else if (strcasecmp(Option, "REL") == 0)
+#ifdef FreeBSD
+        Reply(250, "%d %d", Number, Start - time(NULL));
+#else
         Reply(250, "%d %ld", Number, Start - time(NULL));
+#endif
      else
         Reply(501, "Unknown option: \"%s\"", Option);
      }
diff -urN vdr-1.5.17.orig/themes.c vdr-1.5.17/themes.c
--- vdr-1.5.17.orig/themes.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/themes.c	2008-03-06 16:57:37.000000000 +0100
@@ -12,6 +12,9 @@
 #include <string.h>
 #include "config.h"
 #include "tools.h"
+#ifdef FreeBSD
+#include "strndup.h"
+#endif
 
 // --- cTheme ----------------------------------------------------------------
 
@@ -47,7 +50,11 @@
                     // FileName is ok
                     if (SetName) {
                        free(name);
+#ifdef FreeBSD
+                       name = (char *)strndup(n, e - n);
+#else
                        name = strndup(n, e - n);
+#endif
                        }
                     }
                  else
diff -urN vdr-1.5.17.orig/thread.c vdr-1.5.17/thread.c
--- vdr-1.5.17.orig/thread.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/thread.c	2008-03-06 16:57:37.000000000 +0100
@@ -9,8 +9,13 @@
 
 #include "thread.h"
 #include <errno.h>
+#ifdef FreeBSD
+#include <pthread_np.h>
+#include <stdlib.h>
+#else
 #include <linux/unistd.h>
 #include <malloc.h>
+#endif
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/resource.h>
@@ -141,7 +146,9 @@
 {
   pthread_rwlockattr_t attr;
   pthread_rwlockattr_init(&attr);
+#ifndef FreeBSD
   pthread_rwlockattr_setkind_np(&attr, PreferWriter ? PTHREAD_RWLOCK_PREFER_WRITER_NP : PTHREAD_RWLOCK_PREFER_READER_NP);
+#endif
   pthread_rwlock_init(&rwlock, &attr);
 }
 
@@ -177,7 +184,11 @@
   locked = 0;
   pthread_mutexattr_t attr;
   pthread_mutexattr_init(&attr);
+#ifdef FreeBSD
+  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+#else
   pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+#endif
   pthread_mutex_init(&mutex, &attr);
 }
 
@@ -322,7 +333,11 @@
 
 tThreadId cThread::ThreadId(void)
 {
+#ifdef FreeBSD
+  return reinterpret_cast<long>(::pthread_self());
+#else
   return syscall(__NR_gettid);
+#endif
 }
 
 void cThread::SetMainThreadId(void)
diff -urN vdr-1.5.17.orig/thread.h vdr-1.5.17/thread.h
--- vdr-1.5.17.orig/thread.h	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/thread.h	2008-03-06 16:57:37.000000000 +0100
@@ -13,6 +13,9 @@
 #include <pthread.h>
 #include <stdio.h>
 #include <sys/types.h>
+#ifdef FreeBSD
+#include <signal.h>
+#endif
 
 class cCondWait {
 private:
diff -urN vdr-1.5.17.orig/timers.c vdr-1.5.17/timers.c
--- vdr-1.5.17.orig/timers.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/timers.c	2008-03-06 16:57:37.000000000 +0100
@@ -23,6 +23,12 @@
 // format characters in order to allow any number of blanks after a numeric
 // value!
 
+/* FreeBSD has it's own version of isnumber(),
+   but VDR's version is incompatible */
+#ifdef FreeBSD
+#undef isnumber
+#endif
+
 // --- cTimer ----------------------------------------------------------------
 
 cTimer::cTimer(bool Instant, bool Pause, cChannel *Channel)
@@ -281,7 +287,15 @@
      s = s2;
      }
   bool result = false;
+#ifdef FreeBSD
+  channelbuffer = MALLOC(char, 256);
+  daybuffer = MALLOC(char, 256);
+  filebuffer = MALLOC(char, 256);
+  aux = MALLOC(char, 256);
+  if (8 <= sscanf(s, "%u :%255[^:]:%255[^:]:%d :%d :%d :%d :%255[^:\n]:%255[^\n]", &flags, channelbuffer, daybuffer, &start, &stop, &priority, &lifetime, filebuffer, aux)) {
+#else
   if (8 <= sscanf(s, "%u :%a[^:]:%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &flags, &channelbuffer, &daybuffer, &start, &stop, &priority, &lifetime, &filebuffer, &aux)) {
+#endif
      ClrFlags(tfRecording);
      if (aux && !*skipspace(aux)) {
         free(aux);
diff -urN vdr-1.5.17.orig/tools.c vdr-1.5.17/tools.c
--- vdr-1.5.17.orig/tools.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/tools.c	2008-03-06 16:57:37.000000000 +0100
@@ -21,13 +21,25 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <sys/time.h>
+#ifdef FreeBSD
+#include <sys/param.h>
+#include <sys/mount.h>
+#include "getline.h"
+#else
 #include <sys/vfs.h>
+#endif
 #include <time.h>
 #include <unistd.h>
 #include <utime.h>
 #include "i18n.h"
 #include "thread.h"
 
+/* FreeBSD has it's own version of isnumber(),
+   but VDR's version is incompatible */
+#ifdef FreeBSD
+#undef isnumber
+#endif
+
 int SysLogLevel = 3;
 
 #define MAXSYSLOGBUF 256
@@ -484,6 +496,18 @@
 {
   if (!FileName)
      return NULL;
+#ifdef FreeBSD
+  char *resolved_path = NULL;
+  resolved_path = MALLOC(char, PATH_MAX+1);
+  if (realpath(FileName, resolved_path) == NULL)
+  {
+        if (errno != ENOENT) // some other error occurred
+           LOG_ERROR_STR(FileName);
+        else // file doesn't exist
+           resolved_path = strdup(FileName);
+  }
+  return resolved_path;
+#else
   char *TargetName = canonicalize_file_name(FileName);
   if (!TargetName) {
      if (errno == ENOENT) // file doesn't exist
@@ -492,6 +516,7 @@
         LOG_ERROR_STR(FileName);
      }
   return TargetName;
+#endif
 }
 
 bool SpinUpDisk(const char *FileName)
@@ -508,7 +533,11 @@
          int f = open(buf, O_WRONLY | O_CREAT, DEFFILEMODE);
          // O_SYNC doesn't work on all file systems
          if (f >= 0) {
+#ifdef FreeBSD
+            if (fsync(f) < 0)
+#else
             if (fdatasync(f) < 0)
+#endif
                LOG_ERROR_STR(*buf);
             close(f);
             remove(buf);
@@ -568,7 +597,11 @@
               esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
            }
         else
+#ifdef FreeBSD
+           dsyslog("cTimeMs: not using monotonic clock - resolution is too bad (%jd s %ld ns)", (intmax_t)tp.tv_sec, tp.tv_nsec);
+#else
            dsyslog("cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
+#endif
         }
      else
         esyslog("cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
@@ -808,7 +841,11 @@
 const char *cCharSetConv::Convert(const char *From, char *To, size_t ToLength)
 {
   if (cd != (iconv_t)-1 && From && *From) {
+#ifdef FreeBSD
+     const char *FromPtr = (char *)From;
+#else
      char *FromPtr = (char *)From;
+#endif
      size_t FromLength = strlen(From);
      char *ToPtr = To;
      if (!ToPtr) {
@@ -910,7 +947,11 @@
   return cString(buffer, true);
 }
 
+#ifdef FreeBSD
+cString WeekDayNameReal(int WeekDay)
+#else
 cString WeekDayName(int WeekDay)
+#endif
 {
   char buffer[16];
   WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with Monday==0!
@@ -928,10 +969,18 @@
 cString WeekDayName(time_t t)
 {
   struct tm tm_r;
+#ifdef FreeBSD
+  return WeekDayNameReal(localtime_r(&t, &tm_r)->tm_wday);
+#else
   return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
+#endif
 }
 
+#ifdef FreeBSD
+cString WeekDayNameFullReal(int WeekDay)
+#else
 cString WeekDayNameFull(int WeekDay)
+#endif
 {
   WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with Monday==0!
   switch (WeekDay) {
@@ -949,7 +998,11 @@
 cString WeekDayNameFull(time_t t)
 {
   struct tm tm_r;
+#ifdef FreeBSD
+  return WeekDayNameFullReal(localtime_r(&t, &tm_r)->tm_wday);
+#else
   return WeekDayNameFull(localtime_r(&t, &tm_r)->tm_wday);
+#endif
 }
 
 cString DayDateTime(time_t t)
@@ -959,7 +1012,11 @@
      time(&t);
   struct tm tm_r;
   tm *tm = localtime_r(&t, &tm_r);
+#ifdef FreeBSD
+  snprintf(buffer, sizeof(buffer), "%s %02d.%02d. %02d:%02d", *WeekDayNameReal(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
+#else
   snprintf(buffer, sizeof(buffer), "%s %02d.%02d. %02d:%02d", *WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
+#endif
   return buffer;
 }
 
@@ -978,7 +1035,11 @@
   char buf[32];
   struct tm tm_r;
   tm *tm = localtime_r(&t, &tm_r);
+#ifdef FreeBSD
+  char *p = stpcpy(buf, WeekDayNameReal(tm->tm_wday));
+#else
   char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
+#endif
   *p++ = ' ';
   strftime(p, sizeof(buf) - (p - buf), "%d.%m.%Y", tm);
   return buf;
@@ -1439,7 +1500,9 @@
 
 // --- cUnbufferedFile -------------------------------------------------------
 
+#ifndef FreeBSD
 #define USE_FADVISE
+#endif
 
 #define WRITE_BUFFER KILOBYTE(800)
 
@@ -1498,11 +1561,13 @@
   readahead = ra;
 }
 
+#ifdef USE_FADVISE
 int cUnbufferedFile::FadviseDrop(off_t Offset, off_t Len)
 {
   // rounding up the window to make sure that not PAGE_SIZE-aligned data gets freed.
   return posix_fadvise(fd, Offset - (FADVGRAN - 1), Len + (FADVGRAN - 1) * 2, POSIX_FADV_DONTNEED);
 }
+#endif
 
 off_t cUnbufferedFile::Seek(off_t Offset, int Whence)
 {
diff -urN vdr-1.5.17.orig/tools.h vdr-1.5.17/tools.h
--- vdr-1.5.17.orig/tools.h	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/tools.h	2008-03-06 19:06:32.000000000 +0100
@@ -24,6 +24,12 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#ifdef FreeBSD
+#include <sys/param.h>
+typedef int (*__compar_fn_t) (__const void *, __const void *);
+#undef isnumber
+#endif
+
 typedef unsigned char uchar;
 
 extern int SysLogLevel;
@@ -205,9 +211,17 @@
 bool SpinUpDisk(const char *FileName);
 void TouchFile(const char *FileName);
 time_t LastModifiedTime(const char *FileName);
+#ifdef FreeBSD
+cString WeekDayNameReal(int WeekDay);
+#else
 cString WeekDayName(int WeekDay);
+#endif
 cString WeekDayName(time_t t);
+#ifdef FreeBSD
+cString WeekDayNameFullReal(int WeekDay);
+#else
 cString WeekDayNameFull(int WeekDay);
+#endif
 cString WeekDayNameFull(time_t t);
 cString DayDateTime(time_t t = 0);
 cString TimeToString(time_t t);
diff -urN vdr-1.5.17.orig/vdr.c vdr-1.5.17/vdr.c
--- vdr-1.5.17.orig/vdr.c	2008-03-06 16:57:05.000000000 +0100
+++ vdr-1.5.17/vdr.c	2008-03-06 17:33:41.000000000 +0100
@@ -32,8 +32,10 @@
 #include <pwd.h>
 #include <signal.h>
 #include <stdlib.h>
+#ifndef FreeBSD
 #include <sys/capability.h>
 #include <sys/prctl.h>
+#endif
 #include <termios.h>
 #include <unistd.h>
 #include "audio.h"
@@ -86,6 +88,7 @@
 
 static int LastSignal = 0;
 
+#ifndef FreeBSD
 static bool SetUser(const char *UserName, bool UserDump)//XXX name?
 {
   if (UserName) {
@@ -138,6 +141,7 @@
      }
   return true;
 }
+#endif
 
 static void SignalHandler(int signum)
 {
@@ -377,6 +381,7 @@
   if (VdrUser && geteuid() == 0) {
      StartedAsRoot = true;
      if (strcmp(VdrUser, "root")) {
+#ifndef FreeBSD
         if (!SetKeepCaps(true))
            return 2;
         if (!SetUser(VdrUser, UserDump))
@@ -385,6 +390,7 @@
            return 2;
         if (!SetCapSysTime())
            return 2;
+#endif
         }
      }
 
@@ -506,7 +512,11 @@
 
   isyslog("VDR version %s started", VDRVERSION);
   if (StartedAsRoot && VdrUser)
+#ifdef FreeBSD
+     isyslog("Unable to switch to user '%s' on FreeBSD", VdrUser);
+#else
      isyslog("switched to user '%s'", VdrUser);
+#endif
   if (DaemonMode)
      dsyslog("running as daemon (tid=%d)", cThread::ThreadId());
   cThread::SetMainThreadId();
diff -r d1fa75d44e6b linux/include/linux/dvb/dmx.h
--- a/linux/include/linux/dvb/dmx.h	Tue Mar 04 10:04:56 2008 -0300
+++ b/linux/include/linux/dvb/dmx.h	Thu Mar 06 19:21:23 2008 +0100
@@ -24,7 +24,19 @@
 #ifndef _DVBDMX_H_
 #define _DVBDMX_H_
 
+#ifdef FreeBSD
+#include <sys/types.h>
+#else
 #include <asm/types.h>
+#endif
+ 
+#ifdef FreeBSD
+typedef __uint8_t       __u8;
+typedef __uint16_t      __u16;
+typedef __uint32_t      __u32;
+typedef __uint64_t      __u64;
+#endif
+
 #ifdef __KERNEL__
 #include <linux/time.h>
 #else
diff -r d1fa75d44e6b linux/include/linux/dvb/frontend.h
--- a/linux/include/linux/dvb/frontend.h	Tue Mar 04 10:04:56 2008 -0300
+++ b/linux/include/linux/dvb/frontend.h	Thu Mar 06 19:21:23 2008 +0100
@@ -26,8 +26,16 @@
 #ifndef _DVBFRONTEND_H_
 #define _DVBFRONTEND_H_
 
+#ifdef FreeBSD
+#include <sys/types.h>
+#else
 #include <asm/types.h>
+#endif
 
+#ifdef FreeBSD
+typedef __uint8_t	__u8;
+typedef __uint32_t	__u32;
+#endif
 
 typedef enum fe_type {
 	FE_QPSK,
diff -r d1fa75d44e6b linux/include/linux/dvb/osd.h
--- a/linux/include/linux/dvb/osd.h	Tue Mar 04 10:04:56 2008 -0300
+++ b/linux/include/linux/dvb/osd.h	Thu Mar 06 19:21:23 2008 +0100
@@ -24,7 +24,9 @@
 #ifndef _DVBOSD_H_
 #define _DVBOSD_H_
 
+#ifndef FreeBSD
 #include <linux/compiler.h>
+#endif
 
 typedef enum {
   // All functions return -2 on "not open"
@@ -104,7 +106,11 @@ typedef struct osd_cmd_s {
 	int x1;
 	int y1;
 	int color;
+#ifdef FreeBSD
+	void *data;
+#else
 	void __user *data;
+#endif
 } osd_cmd_t;
 
 /* OSD_OpenRaw: set 'color' to desired window type */
diff -r d1fa75d44e6b linux/include/linux/dvb/video.h
--- a/linux/include/linux/dvb/video.h	Tue Mar 04 10:04:56 2008 -0300
+++ b/linux/include/linux/dvb/video.h	Thu Mar 06 19:21:23 2008 +0100
@@ -24,12 +24,18 @@
 #ifndef _DVBVIDEO_H_
 #define _DVBVIDEO_H_
 
+#ifndef FreeBSD
 #include <linux/compiler.h>
+#endif
 
 #ifdef __KERNEL__
 #include <linux/types.h>
 #else
+#ifdef FreeBSD
+#include <sys/types.h>
+#else
 #include <asm/types.h>
+#endif
 #include <stdint.h>
 #include <time.h>
 #endif
@@ -159,7 +165,11 @@ struct video_status {
 
 
 struct video_still_picture {
+#ifdef FreeBSD
+	char *iFrame;        /* pointer to a single iframe in memory */
+#else
 	char __user *iFrame;        /* pointer to a single iframe in memory */
+#endif
 	int32_t size;
 };
 
@@ -192,7 +202,11 @@ typedef struct video_spu {
 
 typedef struct video_spu_palette {      /* SPU Palette information */
 	int length;
+#ifdef FreeBSD
+	uint8_t *palette;
+#else
 	uint8_t __user *palette;
+#endif
 } video_spu_palette_t;
 
 
diff -r d1fa75d44e6b linux/include/linux/videodev.h
--- a/linux/include/linux/videodev.h	Tue Mar 04 10:04:56 2008 -0300
+++ b/linux/include/linux/videodev.h	Thu Mar 06 19:21:23 2008 +0100
@@ -12,8 +12,16 @@
 #ifndef __LINUX_VIDEODEV_H
 #define __LINUX_VIDEODEV_H
 
+#ifdef FreeBSD
+#include <sys/types.h>
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef uint16_t __u16;
+typedef uint8_t __u8;
+#else
 #include <linux/ioctl.h>
 #include <linux/videodev2.h>
+#endif
 
 #if defined(CONFIG_VIDEO_V4L1_COMPAT) || !defined (__KERNEL__)
 
@@ -130,7 +138,11 @@ struct video_window
 	__u32	width,height;		/* Its size */
 	__u32	chromakey;
 	__u32	flags;
+#ifdef FreeBSD
+	struct	video_clip *clips;	/* Set only */
+#else
 	struct	video_clip __user *clips;	/* Set only */
+#endif
 	int	clipcount;
 #define VIDEO_WINDOW_INTERLACE	1
 #define VIDEO_WINDOW_CHROMAKEY	16	/* Overlay by chromakey */
@@ -169,6 +181,10 @@ struct video_key
 	__u8	key[8];
 	__u32	flags;
 };
+
+#ifdef FreeBSD
+#define VIDEO_MAX_FRAME		32
+#endif
 
 struct video_mbuf
 {
Index: Makefile
===================================================================
RCS file: /cvsroot/softdevice/softdevice/Makefile,v
retrieving revision 1.41
diff -u -r1.41 Makefile
--- Makefile	3 Apr 2007 20:21:04 -0000	1.41
+++ Makefile	6 Mar 2008 17:08:20 -0000
@@ -28,7 +28,11 @@
 PLUGINLIBDIR = ./PLUGINS/lib
 
 # for older file-utils, option -f had the same effect
+ifdef FREEBSD
+CPOPTS = -f
+else
 CPOPTS = --remove-destination
+endif
 
 -include config.mak
 
Index: VideoFilter.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/VideoFilter.c,v
retrieving revision 1.10
diff -u -r1.10 VideoFilter.c
--- VideoFilter.c	20 Feb 2008 08:05:42 -0000	1.10
+++ VideoFilter.c	6 Mar 2008 17:08:20 -0000
@@ -572,7 +572,11 @@
         memcpy(avpic_dest.data,dest->pixel,sizeof(avpic_dest.data));
         memcpy(avpic_dest.linesize,dest->stride,sizeof(avpic_dest.linesize));
 
+#ifdef FreeBSD
+        pp_postprocess((uint8_t **) avpic_src.data,
+#else
         pp_postprocess((const uint8_t **) avpic_src.data,
+#endif
                         avpic_src.linesize,
                         avpic_dest.data,
                         avpic_dest.linesize,
Index: setup-softlog.c
===================================================================
RCS file: /cvsroot/softdevice/softdevice/setup-softlog.c,v
retrieving revision 1.6
diff -u -r1.6 setup-softlog.c
--- setup-softlog.c	3 Apr 2007 19:24:31 -0000	1.6
+++ setup-softlog.c	6 Mar 2008 17:08:21 -0000
@@ -216,6 +216,8 @@
 {
 #ifdef __APPLE__ 
   return getpid();
+#elif (defined FreeBSD)
+  return reinterpret_cast<long>(::pthread_self());
 #else
   return syscall(__NR_gettid);
 #endif
diff -ur streamdev-20070921.orig/Makefile streamdev-20070921/Makefile
--- streamdev-20070921.orig/Makefile	2007-09-21 13:18:40.000000000 +0200
+++ streamdev-20070921/Makefile	2008-03-06 19:12:39.000000000 +0100
@@ -86,7 +86,11 @@
 endif
 
 libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.cc libdvbmpeg/*.h libdvbmpeg/*.hh
+ifdef FREEBSD
+	gmake -C ./libdvbmpeg libdvbmpegtools.a FREEBSD=1
+else
 	make -C ./libdvbmpeg libdvbmpegtools.a
+endif
 
 ### Implicit rules:
 
@@ -132,4 +136,8 @@
 
 clean:
 	@-rm -f $(COMMONOBJS) $(CLIENTOBJS) $(SERVEROBJS) $(DEPFILE) *.so *.tgz core* *~
+ifdef FREEBSD
+	gmake -C ./libdvbmpeg clean FREEBSD=1
+else
 	make -C ./libdvbmpeg clean
+endif
diff -ur streamdev-20070921.orig/common.h streamdev-20070921/common.h
--- streamdev-20070921.orig/common.h	2007-09-21 13:18:40.000000000 +0200
+++ streamdev-20070921/common.h	2008-03-06 19:13:28.000000000 +0100
@@ -5,6 +5,12 @@
 #ifndef VDR_STREAMDEV_COMMON_H
 #define VDR_STREAMDEV_COMMON_H
 
+/* FreeBSD has it's own version of isnumber(),
+   but VDR's version is incompatible */
+#ifdef FreeBSD
+#undef isnumber
+#endif
+
 #include <vdr/tools.h>
 #include <vdr/plugin.h>
 
diff -ur streamdev-20070921.orig/libdvbmpeg/Makefile streamdev-20070921/libdvbmpeg/Makefile
--- streamdev-20070921.orig/libdvbmpeg/Makefile	2005-02-08 16:21:19.000000000 +0100
+++ streamdev-20070921/libdvbmpeg/Makefile	2008-03-06 18:38:38.000000000 +0100
@@ -5,6 +5,9 @@
 SRC  = $(wildcard *.c)
 CPPSRC = $(wildcard *.cpp)
 CSRC = $(wildcard *.cc) 
+ifdef FREEBSD
+DEFINES += -DFreeBSD
+endif
 
 DESTDIR = /usr/local
 
diff -ur streamdev-20070921.orig/libdvbmpeg/ctools.c streamdev-20070921/libdvbmpeg/ctools.c
--- streamdev-20070921.orig/libdvbmpeg/ctools.c	2007-03-19 13:05:25.000000000 +0100
+++ streamdev-20070921/libdvbmpeg/ctools.c	2008-03-06 18:29:52.000000000 +0100
@@ -2060,7 +2060,11 @@
 	if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
 
 
+#ifdef FreeBSD
+	if ( (fdin = open(name, O_RDONLY)) < 0){
+#else
 	if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
+#endif
 		fprintf(stderr,"Can't open %s\n",name);
 		exit(1);
 	}
@@ -2101,8 +2105,12 @@
 		sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
 		printf("writing %s\n",new_name);
 
+#ifdef FreeBSD
+		if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC,
+#else
 		if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
 				   |O_LARGEFILE,
+#endif
 				   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
 				   S_IROTH|S_IWOTH)) < 0){
 			fprintf(stderr,"Can't open %s\n",new_name);
@@ -2114,8 +2122,12 @@
 	sprintf(new_name,"%s-%03d.%s",base_name,i,ext);
 	printf("writing %s\n",new_name);
 
+#ifdef FreeBSD
+	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC,
+#else
 	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
 			   |O_LARGEFILE,
+#endif
 			   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
 			   S_IROTH|S_IWOTH)) < 0){
 		fprintf(stderr,"Can't open %s\n",new_name);
@@ -2144,7 +2156,11 @@
 	if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
 
 
+#ifdef FreeBSD
+	if ( (fdin = open(name, O_RDONLY)) < 0){
+#else
 	if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
+#endif
 		fprintf(stderr,"Can't open %s\n",name);
 		exit(1);
 	}
@@ -2182,8 +2198,12 @@
 	sprintf(new_name,"%s-1.%s",base_name,ext);
 	printf("writing %s\n",new_name);
 
+#ifdef FreeBSD
+	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC,
+#else
 	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
 			   |O_LARGEFILE,
+#endif
 			   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
 			   S_IROTH|S_IWOTH)) < 0){
 		fprintf(stderr,"Can't open %s\n",new_name);
@@ -2195,8 +2215,12 @@
 	sprintf(new_name,"%s-2.%s",base_name,ext);
 	printf("writing %s\n",new_name);
 
+#ifdef FreeBSD
+	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC,
+#else
 	if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC
 			   |O_LARGEFILE,
+#endif
 			   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|
 			   S_IROTH|S_IWOTH)) < 0){
 		fprintf(stderr,"Can't open %s\n",new_name);
diff -ur streamdev-20070921.orig/server/connectionVTP.c streamdev-20070921/server/connectionVTP.c
--- streamdev-20070921.orig/server/connectionVTP.c	2007-09-21 14:46:33.000000000 +0200
+++ streamdev-20070921/server/connectionVTP.c	2008-03-06 19:05:45.000000000 +0100
@@ -186,7 +186,11 @@
 	case Event:
 		if (m_Event != NULL) {
 			m_State = Title;
+#ifdef FreeBSD
+			return m_Client->Respond(-215, "E %u %d %d %X", m_Event->EventID(),
+#else
 			return m_Client->Respond(-215, "E %u %ld %d %X", m_Event->EventID(),
+#endif
 			                         m_Event->StartTime(), m_Event->Duration(), 
 			                         m_Event->TableID());
 		} else {
@@ -225,7 +229,11 @@
 	case Vps:
 		m_State = EndEvent;
 		if (m_Event->Vps())
+#ifdef FreeBSD
+			return m_Client->Respond(-215, "V %d", m_Event->Vps());
+#else
 			return m_Client->Respond(-215, "V %ld", m_Event->Vps());
+#endif
 		else
 			return Next(Last);
 		break;
diff -ur streamdev-20070921.orig/tools/socket.c streamdev-20070921/tools/socket.c
--- streamdev-20070921.orig/tools/socket.c	2007-09-21 13:18:42.000000000 +0200
+++ streamdev-20070921/tools/socket.c	2008-03-06 18:24:27.000000000 +0100
@@ -153,5 +153,9 @@
 
 bool cTBSocket::SetDSCP(void) {
 	int dscp = STREAMDEV_DSCP;
+#ifdef FreeBSD
+	return ::setsockopt(*this, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != -1;
+#else
 	return ::setsockopt(*this, SOL_IP, IP_TOS, &dscp, sizeof(dscp)) != -1;
+#endif
 }
_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux