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@gnu.ai.mit.edu.  */
+
+#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();
