[vdr] 01/06: New upstream version 2.3.8

Tobias Grimm tiber-guest at moszumanska.debian.org
Wed Dec 27 13:02:07 UTC 2017


This is an automated email from the git hooks/post-receive script.

tiber-guest pushed a commit to annotated tag debian/2.3.8-1
in repository vdr.

commit db4e002c59e5452c2e89965325cd0c1b1dc83d49
Author: Tobias Grimm <etobi at debian.org>
Date:   Fri Jun 30 20:02:52 2017 +0200

    New upstream version 2.3.8
---
 CONTRIBUTORS |  11 ++++-
 HISTORY      |  32 ++++++++++++++
 INSTALL      |   6 +--
 MANUAL       |  12 +++++-
 ci.c         |  30 +++++++------
 config.h     |  10 ++---
 menu.c       | 137 +++++++++++++++++++++++++++++++++--------------------------
 po/ar.po     |   8 +++-
 po/ca_ES.po  |   8 +++-
 po/cs_CZ.po  |   8 +++-
 po/da_DK.po  |   8 +++-
 po/de_DE.po  |   8 +++-
 po/el_GR.po  |   8 +++-
 po/es_ES.po  |   8 +++-
 po/et_EE.po  |   8 +++-
 po/fi_FI.po  |   8 +++-
 po/fr_FR.po  |   8 +++-
 po/hr_HR.po  |   8 +++-
 po/hu_HU.po  |   8 +++-
 po/it_IT.po  |  14 ++++--
 po/lt_LT.po  |   8 +++-
 po/mk_MK.po  |   8 +++-
 po/nl_NL.po  |   8 +++-
 po/nn_NO.po  |   8 +++-
 po/pl_PL.po  |   8 +++-
 po/pt_PT.po  |   8 +++-
 po/ro_RO.po  |   8 +++-
 po/ru_RU.po  |   8 +++-
 po/sk_SK.po  |   8 +++-
 po/sl_SI.po  |   8 +++-
 po/sr_RS.po  |   8 +++-
 po/sv_SE.po  |   8 +++-
 po/tr_TR.po  |   8 +++-
 po/uk_UA.po  |   8 +++-
 po/zh_CN.po  |   8 +++-
 recording.c  |   4 +-
 skinlcars.c  |   4 +-
 skins.h      |  25 ++++++++++-
 status.h     |  15 ++++++-
 svdrp.c      |  21 ++++++++-
 svdrp.h      |  10 ++++-
 thread.c     |  33 +++++++++++---
 timers.c     |   4 +-
 tools.c      |   8 +++-
 tools.h      |   4 +-
 45 files changed, 462 insertions(+), 134 deletions(-)

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 27b0bbb..04487a6 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -2117,7 +2117,7 @@ Martin Wache <M.Wache at gmx.net>
  for suggesting to speed up anti-aliased font rendering by caching the blend indexes
  for extending the option "Setup/Miscellaneous/Show channel names with source" to
  "type" or "full"
- for making the "Channels" menu indicates whether a channel is encrypted or a radio
+ for making the "Channels" menu indicate whether a channel is encrypted or a radio
  channel
 
 Matthias Lenk <matthias.lenk at amd.com>
@@ -3037,6 +3037,8 @@ Frank Neumann <fnu at yavdr.org>
  for reporting a problem with the default return value of cEpgHandler::BeginSegmentTransfer()
  in derived classes that don't implement this function
  for reporting uninitialized variable SdWatchdog in vdr.c
+ for suggesting to use readdir() instead of readdir_r(), if GLIBC version 2.24 or
+ newer is used
 
 Gerald Dachs <vdr at dachsweb.de>
  for reporting a problem with checking for minimum line length of 21 characters in
@@ -3102,6 +3104,8 @@ Frank Niederwipper <f.niederwipper at gmail.com>
 Chris Mayo <aklhfex at gmail.com>
  for reporting a problem with detecting frames on radio channels
  for fixing the link to "svdrpsend (1)" in the vdr.1 man page
+ for updating links in the INSTALL file
+ for reporting double slashes in file names processed with AddDirectory()
 
 Dominic Evans <oldmanuk at gmail.com>
  for making the SVDRP command LSTC accepts channel IDs
@@ -3272,6 +3276,7 @@ Matthias Senzel <matthias.senzel at t-online.de>
  for reporting a bug in switching channels in the Schedule menu after going through
  various Now and Schedule menus for different channels
  for the "jumpingseconds" patch
+ for reporting a bug in drawing very long menu titles in the LCARS skin
 
 Marek Nazarko <mnazarko at gmail.com>
  for translating OSD texts to the Polish language
@@ -3502,3 +3507,7 @@ Sergey Chernyavskiy <glenvt18 at gmail.com>
 
 Frank Richter <kulpstur at t-online.de>
  for adding 'S3W ABS-3A' to sources.conf
+
+Daniel Scheller <d.scheller at gmx.net>
+ for reporting a problem with detecting whether a CAM replies to queries, which didn't
+ work on some systems since the implementation of RI_HOST_CONTROL
diff --git a/HISTORY b/HISTORY
index 45b7221..f5fea54 100644
--- a/HISTORY
+++ b/HISTORY
@@ -9129,3 +9129,35 @@ Video Disk Recorder Revision History
 - Introduced the new macro DISABLE_TEMPLATES_COLLIDING_WITH_STL, which can be defined
   before including tools.h in case some plugin needs to use the STL and gets error
   messages regarding one of the template functions defined in tools.h.
+
+2017-06-30: Version 2.3.8
+
+- Updated links in the INSTALL file (thanks to Chris Mayo).
+- Fixed detecting whether a CAM replies to queries, which didn't work on some systems
+  since the implementation of RI_HOST_CONTROL (reported by Daniel Scheller).
+- Added some missing locks when calling functions from cStatus or cSkin*, and added
+  some text to status.h and skins.h, explaining the locking situation when such
+  functions are called.
+- Fixed a possible crash in cStateLockLog.
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- Now skipping a leading '/' in AddDirectory(), to avoid double slashes (reported by
+  Chris Mayo).
+- Fixed drawing very long menu titles in the LCARS skin (reported by Matthias Senzel).
+- Timers are now linked to EPG events even if they are inactive. By default Events that
+  are linked to inactive timers are marked with 'I' and 'i', depending on whether the
+  timer would record the entire Event or only part of it.
+  The function cSkinDisplayMenu::SetItemEvent() now has an additional parameter named
+  TimerActive, which indicates whether the timer that would record this event (if any)
+  is active. A plugin may react on this when displaying a menu line for an event.
+  The old version of cSkinDisplayMenu::SetItemEvent() (without the TimerActive parameter)
+  is still there for backwards compatibility. It may be removed in a future version,
+  so plugin authors should switch to the new one.
+- Now using readdir() instead of readdir_r(), if GLIBC version 2.24 or newer is used
+  (suggested by Frank Neumann).
+- Added a note to the log, indicating that no further invalid lock sequences will be
+  reported until VDR is restarted.
+- Whenever a change is made to the recordings in the video directory, the SVDRP command
+  UPDR is now sent to all peer VDRs, so that they will update their recordings list.
+  This is especially useful if one VDR mounts the video directory of an other one into
+  a subdirectory.
+- SVDRP peering can now be limited to the default SVDRP host (see MANUAL for details).
diff --git a/INSTALL b/INSTALL
index f2218d1..74caf30 100644
--- a/INSTALL
+++ b/INSTALL
@@ -104,13 +104,13 @@ hardware in your system, for instance:
 Plugin:           Device:
 
 dvbsddevice       Full-Featured SD DVB cards (Fujitsu-Siemens Design)
-                  (comes with the VDR source)
+                  ftp://ftp.tvdr.de/vdr/Plugins
 dvbhddevice       Full-featured HD DVB cards (Technotrend TT S2-6400)
                   https://bitbucket.org/powARman/dvbhddevice
 rpihddevice       Raspberry Pi
-                  http://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
+                  https://projects.vdr-developer.org/git/vdr-plugin-rpihddevice.git
 
-See http://linuxtv.org/vdrwiki/index.php/Output_devices for more.
+See https://linuxtv.org/vdrwiki/index.php/Output_devices for more.
 
 Standard compliance
 -------------------
diff --git a/MANUAL b/MANUAL
index 0234f77..47b2fdd 100644
--- a/MANUAL
+++ b/MANUAL
@@ -1085,8 +1085,16 @@ Version 2.2
                          connection after which the connection is automatically
                          closed. Default is 300, a value of 0 means no timeout.
 
-  SVDRP peering = no     Activates automatic connections between VDRs in the same
-                         network.
+  SVDRP peering = off    Activates automatic connections between VDRs in the same
+                         network. If set to "any hosts" this VDR will establish
+                         connections with any available hosts. If set to "only
+                         default host" this VDR will only connect to the VDR with
+                         the name defined in "SVDRP default host". If no default
+                         host has been defined, the behavior is the same as with
+                         "any hosts". To switch from "off" to "only default host",
+                         you may need to select "any hosts" first and confirm the
+                         dialog by pressing "Ok" in order to be able to select a
+                         default host.
 
   SVDRP host name        The name of this VDR, which is used when connecting VDRs
                          via SVDRP. By default, the machine's host name is used.
diff --git a/ci.c b/ci.c
index edb801b..b6ea326 100644
--- a/ci.c
+++ b/ci.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: ci.c 4.17 2017/06/10 10:57:31 kls Exp $
+ * $Id: ci.c 4.18 2017/06/19 12:13:38 kls Exp $
  */
 
 #include "ci.h"
@@ -1041,8 +1041,9 @@ void cCiCaPmt::MtdMapPids(cMtdMapper *MtdMapper)
 
 #define CA_ENABLE(x) (((x) & CA_ENABLE_FLAG) ? (x) & ~CA_ENABLE_FLAG : 0)
 
-#define QUERY_WAIT_TIME      1000 // ms to wait before sending a query
+#define QUERY_WAIT_TIME       500 // ms to wait before sending a query
 #define QUERY_REPLY_TIMEOUT  2000 // ms to wait for a reply to a query
+#define QUERY_RETRIES           6 // max. number of retries to check if there is a reply to a query
 
 class cCiConditionalAccessSupport : public cCiSession {
 private:
@@ -1051,6 +1052,7 @@ private:
   int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated!
   bool repliesToQuery;
   cTimeMs timer;
+  int numRetries;
 public:
   cCiConditionalAccessSupport(uint16_t SessionId, cCiTransportConnection *Tc);
   virtual void Process(int Length = 0, const uint8_t *Data = NULL);
@@ -1069,6 +1071,7 @@ cCiConditionalAccessSupport::cCiConditionalAccessSupport(uint16_t SessionId, cCi
   state = 0; // inactive
   caSystemIds[numCaSystemIds = 0] = 0;
   repliesToQuery = false;
+  numRetries = 0;
 }
 
 void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
@@ -1098,7 +1101,8 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
             caSystemIds[numCaSystemIds] = 0;
             dbgprotocol("\n");
             if (state == 1) {
-               timer.Set(QUERY_WAIT_TIME); // WORKAROUND: Alphacrypt 3.09 doesn't reply to QUERY immediately after reset
+               timer.Set(0);
+               numRetries = QUERY_RETRIES;
                state = 2; // got ca info
                }
             dsyslog("CAM %d: system ids:%s", CamSlot()->SlotNumber(), *Ids ? *Ids : " none");
@@ -1171,15 +1175,17 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
      SendData(AOT_CA_INFO_ENQ);
      state = 1; // enquired ca info
      }
-  else if (state == 2 && timer.TimedOut()) {
-     cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL);
-     SendPMT(&CaPmt);
-     timer.Set(QUERY_REPLY_TIMEOUT);
-     state = 3; // waiting for reply
-     }
-  else if (state == 3 && timer.TimedOut()) {
-     dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber());
-     state = 4; // normal operation
+  else if ((state == 2 || state == 3) && timer.TimedOut()) {
+     if (numRetries-- > 0) {
+        cCiCaPmt CaPmt(CPCI_QUERY, 0, 0, 0, NULL);
+        SendPMT(&CaPmt);
+        timer.Set(QUERY_WAIT_TIME);
+        state = 3; // waiting for reply
+        }
+     else {
+        dsyslog("CAM %d: doesn't reply to QUERY - only a single channel can be decrypted", CamSlot()->SlotNumber());
+        state = 4; // normal operation
+        }
      }
 }
 
diff --git a/config.h b/config.h
index 4da4ae7..93488be 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: config.h 4.11 2017/06/05 11:15:37 kls Exp $
+ * $Id: config.h 4.12 2017/06/12 08:58:26 kls Exp $
  */
 
 #ifndef __CONFIG_H
@@ -22,13 +22,13 @@
 
 // VDR's own version number:
 
-#define VDRVERSION  "2.3.7"
-#define VDRVERSNUM   20307  // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION  "2.3.8"
+#define VDRVERSNUM   20308  // Version * 10000 + Major * 100 + Minor
 
 // The plugin API's version number:
 
-#define APIVERSION  "2.3.7"
-#define APIVERSNUM   20307  // Version * 10000 + Major * 100 + Minor
+#define APIVERSION  "2.3.8"
+#define APIVERSNUM   20308  // Version * 10000 + Major * 100 + Minor
 
 // When loading plugins, VDR searches them by their APIVERSION, which
 // may be smaller than VDRVERSION in case there have been no changes to
diff --git a/menu.c b/menu.c
index 2d84194..c2c12dd 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: menu.c 4.37 2017/06/10 19:19:51 kls Exp $
+ * $Id: menu.c 4.41 2017/06/30 09:49:39 kls Exp $
  */
 
 #include "menu.h"
@@ -1477,6 +1477,7 @@ public:
   const cChannel *channel;
   bool withDate;
   eTimerMatch timerMatch;
+  bool timerActive;
   cMenuScheduleItem(const cTimers *Timers, const cEvent *Event, const cChannel *Channel = NULL, bool WithDate = false);
   static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; }
   static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); }
@@ -1494,6 +1495,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cTimers *Timers, const cEvent *Event,
   channel = Channel;
   withDate = WithDate;
   timerMatch = tmNone;
+  timerActive = false;
   Update(Timers, true);
 }
 
@@ -1508,15 +1510,17 @@ int cMenuScheduleItem::Compare(const cListObject &ListObject) const
   return r;
 }
 
-static const char *TimerMatchChars = " tT";
+static const char *TimerMatchChars = " tT iI";
 
 bool cMenuScheduleItem::Update(const cTimers *Timers, bool Force)
 {
   eTimerMatch OldTimerMatch = timerMatch;
-  Timers->GetMatch(event, &timerMatch);
-  if (Force || timerMatch != OldTimerMatch) {
+  bool OldTimerActive = timerActive;
+  const cTimer *Timer = Timers->GetMatch(event, &timerMatch);
+  timerActive = Timer && Timer->HasFlags(tfActive);
+  if (Force || timerMatch != OldTimerMatch || timerActive != OldTimerActive) {
      cString buffer;
-     char t = TimerMatchChars[timerMatch];
+     char t = TimerMatchChars[timerMatch + (timerActive ? 0 : 3)];
      char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
      char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' ';
      const char *csn = channel ? channel->ShortName(true) : NULL;
@@ -1535,7 +1539,7 @@ bool cMenuScheduleItem::Update(const cTimers *Timers, bool Force)
 
 void cMenuScheduleItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable)
 {
-  if (!DisplayMenu->SetItemEvent(event, Index, Current, Selectable, channel, withDate, timerMatch))
+  if (!DisplayMenu->SetItemEvent(event, Index, Current, Selectable, channel, withDate, timerMatch, timerActive))
      DisplayMenu->SetItem(Text(), Index, Current, Selectable);
 }
 
@@ -1652,30 +1656,30 @@ eOSState cMenuWhatsOn::Switch(void)
 eOSState cMenuWhatsOn::Record(void)
 {
   if (cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current())) {
-       LOCK_TIMERS_WRITE;
-       LOCK_CHANNELS_READ;
-       LOCK_SCHEDULES_READ;
-       Timers->SetExplicitModify();
-       if (item->timerMatch == tmFull) {
-          if (cTimer *Timer = Timers->GetMatch(item->event))
-             return AddSubMenu(new cMenuEditTimer(Timer));
-          }
-       cTimer *Timer = new cTimer(item->event);
-       if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
-          Timer->SetRemote(Setup.SVDRPDefaultHost);
-       if (cTimer *t = Timers->GetTimer(Timer)) {
-          delete Timer;
-          Timer = t;
-          return AddSubMenu(new cMenuEditTimer(Timer));
-          }
-       if (Timer->Matches(0, false, NEWTIMERLIMIT))
-          return AddSubMenu(new cMenuEditTimer(Timer, true));
-       Timers->Add(Timer);
-       Timers->SetModified();
-       if (!HandleRemoteModifications(Timer)) {
-          // must add the timer before HandleRemoteModifications to get proper log messages with timer ids
-          Timers->Del(Timer);
-          }
+     LOCK_TIMERS_WRITE;
+     LOCK_CHANNELS_READ;
+     LOCK_SCHEDULES_READ;
+     Timers->SetExplicitModify();
+     if (item->timerMatch == tmFull) {
+        if (cTimer *Timer = Timers->GetMatch(item->event))
+           return AddSubMenu(new cMenuEditTimer(Timer));
+        }
+     cTimer *Timer = new cTimer(item->event);
+     if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
+        Timer->SetRemote(Setup.SVDRPDefaultHost);
+     if (cTimer *t = Timers->GetTimer(Timer)) {
+        delete Timer;
+        Timer = t;
+        return AddSubMenu(new cMenuEditTimer(Timer));
+        }
+     if (Timer->Matches(0, false, NEWTIMERLIMIT))
+        return AddSubMenu(new cMenuEditTimer(Timer, true));
+     Timers->Add(Timer);
+     Timers->SetModified();
+     if (!HandleRemoteModifications(Timer)) {
+        // must add the timer before HandleRemoteModifications to get proper log messages with timer ids
+        Timers->Del(Timer);
+        }
      if (HasSubMenu())
         CloseSubMenu();
      if (Update())
@@ -1714,7 +1718,10 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
                         for (cOsdItem *item = First(); item; item = Next(item)) {
                             if (((cMenuScheduleItem *)item)->channel->Number() == cDevice::CurrentChannel()) {
                                SetCurrent(item);
-                               Display();
+                               {
+                                 LOCK_SCHEDULES_READ;
+                                 Display();
+                               }
                                LOCK_CHANNELS_READ;
                                SetHelpKeys(Channels);
                                break;
@@ -1733,8 +1740,10 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
        }
      }
   else if (!HasSubMenu()) {
-     if (HadSubMenu && Update())
+     if (HadSubMenu && Update()) {
+        LOCK_SCHEDULES_READ;
         Display();
+        }
      if (Key != kNone) {
         LOCK_CHANNELS_READ;
         SetHelpKeys(Channels);
@@ -1953,32 +1962,30 @@ eOSState cMenuSchedule::Number(void)
 eOSState cMenuSchedule::Record(void)
 {
   if (cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current())) {
-     {
-       LOCK_TIMERS_WRITE;
-       LOCK_CHANNELS_READ;
-       LOCK_SCHEDULES_READ;
-       Timers->SetExplicitModify();
-       if (item->timerMatch == tmFull) {
-          if (cTimer *Timer = Timers->GetMatch(item->event))
-             return AddSubMenu(new cMenuEditTimer(Timer));
-          }
-       cTimer *Timer = new cTimer(item->event);
-       if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
-          Timer->SetRemote(Setup.SVDRPDefaultHost);
-       if (cTimer *t = Timers->GetTimer(Timer)) {
-          delete Timer;
-          Timer = t;
-          return AddSubMenu(new cMenuEditTimer(Timer));
-          }
-       if (Timer->Matches(0, false, NEWTIMERLIMIT))
-          return AddSubMenu(new cMenuEditTimer(Timer, true));
-       Timers->Add(Timer);
-       Timers->SetModified();
-       if (!HandleRemoteModifications(Timer)) {
-          // must add the timer before HandleRemoteModifications to get proper log messages with timer ids
-          Timers->Del(Timer);
-          }
-     }
+     LOCK_TIMERS_WRITE;
+     LOCK_CHANNELS_READ;
+     LOCK_SCHEDULES_READ;
+     Timers->SetExplicitModify();
+     if (item->timerMatch == tmFull) {
+        if (cTimer *Timer = Timers->GetMatch(item->event))
+           return AddSubMenu(new cMenuEditTimer(Timer));
+        }
+     cTimer *Timer = new cTimer(item->event);
+     if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
+        Timer->SetRemote(Setup.SVDRPDefaultHost);
+     if (cTimer *t = Timers->GetTimer(Timer)) {
+        delete Timer;
+        Timer = t;
+        return AddSubMenu(new cMenuEditTimer(Timer));
+        }
+     if (Timer->Matches(0, false, NEWTIMERLIMIT))
+        return AddSubMenu(new cMenuEditTimer(Timer, true));
+     Timers->Add(Timer);
+     Timers->SetModified();
+     if (!HandleRemoteModifications(Timer)) {
+        // must add the timer before HandleRemoteModifications to get proper log messages with timer ids
+        Timers->Del(Timer);
+        }
      if (HasSubMenu())
         CloseSubMenu();
      if (Update())
@@ -2077,8 +2084,10 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
            Set(Timers, Channels, Channel, true);
            }
         }
-     else if (HadSubMenu && Update())
+     else if (HadSubMenu && Update()) {
+        LOCK_SCHEDULES_READ;
         Display();
+        }
      if (Key != kNone)
         SetHelpKeys();
      }
@@ -3189,8 +3198,10 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
         return state; // closes all recording menus except for the top one
      Set(); // this is the top level menu, so we refresh it...
      Open(true); // ...and open any necessary submenus to show the new name
-     if (!HasSubMenu())
+     if (!HasSubMenu()) {
+        LOCK_RECORDINGS_READ;
         Display();
+        }
      path = NULL;
      fileName = NULL;
      }
@@ -4012,6 +4023,7 @@ void cMenuSetupReplay::Store(void)
 
 class cMenuSetupMisc : public cMenuSetupBase {
 private:
+  const char *svdrpPeeringModeTexts[3];
   const char *showChannelNamesWithSourceTexts[3];
   cStringList svdrpServerNames;
   void Set(void);
@@ -4023,6 +4035,9 @@ public:
 cMenuSetupMisc::cMenuSetupMisc(void)
 {
   SetMenuCategory(mcSetupMisc);
+  svdrpPeeringModeTexts[0] = tr("off");
+  svdrpPeeringModeTexts[1] = tr("any hosts");
+  svdrpPeeringModeTexts[2] = tr("only default host");
   showChannelNamesWithSourceTexts[0] = tr("off");
   showChannelNamesWithSourceTexts[1] = tr("type");
   showChannelNamesWithSourceTexts[2] = tr("full");
@@ -4037,7 +4052,7 @@ void cMenuSetupMisc::Set(void)
   Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. event timeout (min)"),   &data.MinEventTimeout));
   Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Min. user inactivity (min)"), &data.MinUserInactivity));
   Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"),          &data.SVDRPTimeout));
-  Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$SVDRP peering"),              &data.SVDRPPeering));
+  Add(new cMenuEditStraItem(tr("Setup.Miscellaneous$SVDRP peering"),              &data.SVDRPPeering, 3, svdrpPeeringModeTexts));
   if (data.SVDRPPeering) {
      Add(new cMenuEditStrItem( tr("Setup.Miscellaneous$SVDRP host name"), data.SVDRPHostName, sizeof(data.SVDRPHostName)));
      if (GetSVDRPServerNames(&svdrpServerNames)) {
diff --git a/po/ar.po b/po/ar.po
index 267d518..f8b0394 100644
--- a/po/ar.po
+++ b/po/ar.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2008-10-16 11:16-0400\n"
 "Last-Translator: Osama Alrawab <alrawab at hotmail.com>\n"
 "Language-Team: Arabic <ar at li.org>\n"
@@ -1302,6 +1302,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "رقم المواصلة"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/ca_ES.po b/po/ca_ES.po
index 42b2bc5..285f7e3 100644
--- a/po/ca_ES.po
+++ b/po/ca_ES.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2008-03-02 19:02+0100\n"
 "Last-Translator: Luca Olivetti <luca at ventoso.org>\n"
 "Language-Team: Catalan <vdr at linuxtv.org>\n"
@@ -1301,6 +1301,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID de Continuar"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 8036f12..3defcbd 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2010-05-06 11:00+0200\n"
 "Last-Translator: Aleš Juřík <ajurik at quick.cz>\n"
 "Language-Team: Czech <vdr at linuxtv.org>\n"
@@ -1301,6 +1301,12 @@ msgstr "Velikost skoku za použití tlačítek Zelená/Žlutá při opakování
 msgid "Setup.Replay$Resume ID"
 msgstr "ID obnovení"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/da_DK.po b/po/da_DK.po
index 5c3f870..906aa61 100644
--- a/po/da_DK.po
+++ b/po/da_DK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Mogens Elneff <mogens at elneff.dk>\n"
 "Language-Team: Danish <vdr at linuxtv.org>\n"
@@ -1298,6 +1298,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "Genoptagelses ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/de_DE.po b/po/de_DE.po
index 7b1ac5e..d7e6576 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-10 13:45+0100\n"
 "Last-Translator: Klaus Schmidinger <vdr at tvdr.de>\n"
 "Language-Team: German <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Sprungweite mit Taste Gr
 msgid "Setup.Replay$Resume ID"
 msgstr "Wiedergabe-ID"
 
+msgid "any hosts"
+msgstr "mit jeder Maschine"
+
+msgid "only default host"
+msgstr "nur mit der Standardmaschine"
+
 msgid "type"
 msgstr "Typ"
 
diff --git a/po/el_GR.po b/po/el_GR.po
index b64518a..db382e8 100644
--- a/po/el_GR.po
+++ b/po/el_GR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Dimitrios Dimitrakos <mail at dimitrios.de>\n"
 "Language-Team: Greek <vdr at linuxtv.org>\n"
@@ -1298,6 +1298,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID ������������"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/es_ES.po b/po/es_ES.po
index a010c3f..e61ed66 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-19 23:00+0100\n"
 "Last-Translator: Gabriel Bonich <gbonich at gmail.com>\n"
 "Language-Team: Spanish <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Saltar distancia con teclas verde/amarillo en la repetici
 msgid "Setup.Replay$Resume ID"
 msgstr "ID de continuaci�n"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/et_EE.po b/po/et_EE.po
index 4026098..e58f97e 100644
--- a/po/et_EE.po
+++ b/po/et_EE.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Arthur Konovalov <artlov at gmail.com>\n"
 "Language-Team: Estonian <vdr at linuxtv.org>\n"
@@ -1298,6 +1298,12 @@ msgstr "Klahvide Roheline/Kollane korduv hüpe (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "Taasesituse tunnus"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 6ed0af2..964d8d0 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2007-08-15 15:52+0200\n"
 "Last-Translator: Matti Lehtimäki <matti.lehtimaki at gmail.com>\n"
 "Language-Team: Finnish <vdr at linuxtv.org>\n"
@@ -1302,6 +1302,12 @@ msgstr "Toistohypyn kesto värinäppäimillä (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "Tallenteen paluutunniste"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 3a04653..e3c7e08 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -18,7 +18,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-18 20:16+0100\n"
 "Last-Translator: Bernard Jaulin <bernard.jaulin at gmail.com>\n"
 "Language-Team: French <vdr at linuxtv.org>\n"
@@ -1309,6 +1309,12 @@ msgstr "Durée du saut pour les touches Verte/Jaune en répétition (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "ID résumé"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/hr_HR.po b/po/hr_HR.po
index f7b3dd3..c70a5c3 100644
--- a/po/hr_HR.po
+++ b/po/hr_HR.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2008-03-17 19:00+0100\n"
 "Last-Translator: Adrian Caval <anrxc at sysphere.org>\n"
 "Language-Team: Croatian <vdr at linuxtv.org>\n"
@@ -1300,6 +1300,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID nastavka"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/hu_HU.po b/po/hu_HU.po
index 9174994..d1f80b7 100644
--- a/po/hu_HU.po
+++ b/po/hu_HU.po
@@ -11,7 +11,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-13 09:36+0200\n"
 "Last-Translator: István Füley <ifuley at tigercomp.ro>\n"
 "Language-Team: Hungarian <vdr at linuxtv.org>\n"
@@ -1303,6 +1303,12 @@ msgstr "Ismételt ugrástáv a Zöld/Sárga gombokkal (mp)"
 msgid "Setup.Replay$Resume ID"
 msgstr "Lejátszás azonosító"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/it_IT.po b/po/it_IT.po
index d27f1fb..5e214c5 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -11,8 +11,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
-"PO-Revision-Date: 2015-09-14 19:28+0100\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
+"PO-Revision-Date: 2017-06-23 00:00+0100\n"
 "Last-Translator: Diego Pierotto <vdr-italian at tiscali.it>\n"
 "Language-Team: Italian <vdr at linuxtv.org>\n"
 "Language: it\n"
@@ -1304,12 +1304,18 @@ msgstr "Durata spostamento con tasti Verde/Giallo in sequenza (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "ID di ripristino"
 
-msgid "type"
+msgid "any hosts"
 msgstr ""
 
-msgid "full"
+msgid "only default host"
 msgstr ""
 
+msgid "type"
+msgstr "tipo"
+
+msgid "full"
+msgstr "completo"
+
 msgid "Miscellaneous"
 msgstr "Generici"
 
diff --git a/po/lt_LT.po b/po/lt_LT.po
index 46e4618..2c1f3d7 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-11 14:02+0200\n"
 "Last-Translator: Valdemaras Pipiras <varas at ambernet.lt>\n"
 "Language-Team: Lithuanian <vdr at linuxtv.org>\n"
@@ -1298,6 +1298,12 @@ msgstr "Praleisti atkarpą pakartojime (s) su Žaliu/Geltonu mygtukais"
 msgid "Setup.Replay$Resume ID"
 msgstr "Kūrinio ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/mk_MK.po b/po/mk_MK.po
index 69cf47f..d07af18 100644
--- a/po/mk_MK.po
+++ b/po/mk_MK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-08 15:18+0100\n"
 "Last-Translator: Dimitar Petrovski <dimeptr at gmail.com>\n"
 "Language-Team: Macedonian <en at li.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Дистанца на скокање со Зелено/Жолто коп
 msgid "Setup.Replay$Resume ID"
 msgstr "ID на продолжеток"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 6a984e2..ed6223e 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -13,7 +13,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-10 19:43+0100\n"
 "Last-Translator: Erik Oomen <oomen.e at gmail.com>\n"
 "Language-Team: Dutch <vdr at linuxtv.org>\n"
@@ -1304,6 +1304,12 @@ msgstr "Spoel sprong met groene en gele toesten in repeteerstand (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "Hervattings ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/nn_NO.po b/po/nn_NO.po
index 15c25ec..37eb906 100644
--- a/po/nn_NO.po
+++ b/po/nn_NO.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2007-08-12 14:17+0200\n"
 "Last-Translator: Truls Slevigen <truls at slevigen.no>\n"
 "Language-Team: Norwegian Nynorsk <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "Resume ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/pl_PL.po b/po/pl_PL.po
index b9077a2..3a6ec65 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-12 00:59+0100\n"
 "Last-Translator: Tomasz Maciej Nowak <tmn505 at gmail.com>\n"
 "Language-Team: Polish <vdr at linuxtv.org>\n"
@@ -1301,6 +1301,12 @@ msgstr "Pomi
 msgid "Setup.Replay$Resume ID"
 msgstr "ID wznowienia"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/pt_PT.po b/po/pt_PT.po
index 972419b..ae37d28 100644
--- a/po/pt_PT.po
+++ b/po/pt_PT.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2010-03-28 22:49+0100\n"
 "Last-Translator: Cris Silva <hudokkow at gmail.com>\n"
 "Language-Team: Portuguese <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID de resumo"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/ro_RO.po b/po/ro_RO.po
index 78c4f32..69364c1 100644
--- a/po/ro_RO.po
+++ b/po/ro_RO.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-11 22:26+0100\n"
 "Last-Translator: Lucian Muresan <lucianm at users.sourceforge.net>\n"
 "Language-Team: Romanian <vdr at linuxtv.org>\n"
@@ -1300,6 +1300,12 @@ msgstr "Durata sărită cu tastele Verde/Galben la repetiție (s)"
 msgid "Setup.Replay$Resume ID"
 msgstr "Identificator continuare"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 0223d0a..f907ccc 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2016-12-27 17:13+0100\n"
 "Last-Translator: Pridvorov Andrey <ua0lnj at bk.ru>\n"
 "Language-Team: Russian <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Пропуск интервала Зелёный/Жёлтый в пов
 msgid "Setup.Replay$Resume ID"
 msgstr "ID воспроизведения"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/sk_SK.po b/po/sk_SK.po
index 8ddbeb4..d5a70e3 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-17 18:59+0100\n"
 "Last-Translator: Milan Hrala <hrala.milan at gmail.com>\n"
 "Language-Team: Slovak <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Opakovan
 msgid "Setup.Replay$Resume ID"
 msgstr "ident. ��slo obnovenia prehr�vania"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/sl_SI.po b/po/sl_SI.po
index 0a6a289..d2e4630 100644
--- a/po/sl_SI.po
+++ b/po/sl_SI.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2013-03-04 12:46+0100\n"
 "Last-Translator: Matjaz Thaler <matjaz.thaler at guest.arnes.si>\n"
 "Language-Team: Slovenian <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID za predvajanje"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/sr_RS.po b/po/sr_RS.po
index ba1fd18..069c1ec 100644
--- a/po/sr_RS.po
+++ b/po/sr_RS.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2013-03-16 15:05+0100\n"
 "Last-Translator: Zoran Turalija <zoran.turalija at gmail.com>\n"
 "Language-Team: Serbian <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "ID reprodukcije"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 78f689d..ded70cf 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -12,7 +12,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-12 21:58+0100\n"
 "Last-Translator: Magnus Sirvi� <sirwio at hotmail.com>\n"
 "Language-Team: Swedish <vdr at linuxtv.org>\n"
@@ -1303,6 +1303,12 @@ msgstr "Tid f
 msgid "Setup.Replay$Resume ID"
 msgstr "�terupptagnings-ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/tr_TR.po b/po/tr_TR.po
index 5cfac45..749ca47 100644
--- a/po/tr_TR.po
+++ b/po/tr_TR.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2008-02-28 00:33+0100\n"
 "Last-Translator: Oktay Yolge�en <oktay_73 at yahoo.de>\n"
 "Language-Team: Turkish <vdr at linuxtv.org>\n"
@@ -1298,6 +1298,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "G�steri� ID'si"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/uk_UA.po b/po/uk_UA.po
index f9b18b3..d9f15ca 100644
--- a/po/uk_UA.po
+++ b/po/uk_UA.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2015-02-13 18:14+0100\n"
 "Last-Translator: Yarema aka Knedlyk <yupadmin at gmail.com>\n"
 "Language-Team: Ukrainian <vdr at linuxtv.org>\n"
@@ -1299,6 +1299,12 @@ msgstr "Інтервал пропуску з Зеленою/Жовтою кно
 msgid "Setup.Replay$Resume ID"
 msgstr "ID продовження"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 5ae7555..dbeea3f 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: VDR 2.2.0\n"
 "Report-Msgid-Bugs-To: <vdr-bugs at tvdr.de>\n"
-"POT-Creation-Date: 2017-06-10 17:19+0200\n"
+"POT-Creation-Date: 2017-06-30 11:46+0200\n"
 "PO-Revision-Date: 2013-03-04 14:52+0800\n"
 "Last-Translator: NFVDR <nfvdr at live.com>\n"
 "Language-Team: Chinese (simplified) <nfvdr at live.com>\n"
@@ -1300,6 +1300,12 @@ msgstr ""
 msgid "Setup.Replay$Resume ID"
 msgstr "恢复 ID"
 
+msgid "any hosts"
+msgstr ""
+
+msgid "only default host"
+msgstr ""
+
 msgid "type"
 msgstr ""
 
diff --git a/recording.c b/recording.c
index 7b1d158..ca0ec79 100644
--- a/recording.c
+++ b/recording.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: recording.c 4.9 2017/05/27 15:46:57 kls Exp $
+ * $Id: recording.c 4.10 2017/06/25 12:31:46 kls Exp $
  */
 
 #include "recording.h"
@@ -27,6 +27,7 @@
 #include "remux.h"
 #include "ringbuffer.h"
 #include "skins.h"
+#include "svdrp.h"
 #include "tools.h"
 #include "videodir.h"
 
@@ -1493,6 +1494,7 @@ void cRecordings::TouchUpdate(void)
   TouchFile(UpdateFileName());
   if (!needsUpdate)
      lastUpdate = time(NULL); // make sure we don't trigger ourselves
+  BroadcastSVDRPCommand("UPDR");
 }
 
 bool cRecordings::NeedsUpdate(void)
diff --git a/skinlcars.c b/skinlcars.c
index c4278d2..a7c28f1 100644
--- a/skinlcars.c
+++ b/skinlcars.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skinlcars.c 4.4 2017/04/20 08:46:42 kls Exp $
+ * $Id: skinlcars.c 4.5 2017/06/23 15:52:03 kls Exp $
  */
 
 // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures,
@@ -1551,7 +1551,7 @@ void cSkinLCARSDisplayMenu::SetTitle(const char *Title)
 {
   if (MenuCategory() != mcMain) {
      const cFont *font = cFont::GetFont(fontOsd);
-     int w = font->Width(Title);
+     int w = min(font->Width(Title), xa07 - xa06 - Gap);
      osd->DrawRectangle(xa06, yt00, xa07 - w - Gap - 1, yt01 - 1, frameColor);
      osd->DrawText(xa07 - w - Gap, yt00, Title, Theme.Color(clrMenuTitle), Theme.Color(clrBackground), font, w + Gap, yt01 - yt00, taRight);
      }
diff --git a/skins.h b/skins.h
index 2286087..81d68ff 100644
--- a/skins.h
+++ b/skins.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: skins.h 4.1 2015/09/10 11:19:48 kls Exp $
+ * $Id: skins.h 4.4 2017/06/25 10:02:09 kls Exp $
  */
 
 #ifndef __SKINS_H
@@ -21,6 +21,19 @@
 #include "timers.h"
 #include "tools.h"
 
+// Several member functions of the following classes are called with a pointer to
+// an object from a global list (cTimer, cChannel, cRecording or cEvent). In these
+// cases the core VDR code holds a lock on the respective list. While in general a
+// plugin should only work with the objects and data that is explicitly given to it
+// in the function call, the called function may itself set a read lock (not a write
+// lock!) on this list, because read locks can be nested. It may also set read locks
+// (not write locks!) on higher order lists.
+// For instance, a function that is called with a cChannel may lock cRecordings and/or
+// cSchedules (which contains cEvent objects), but not cTimers. If a plugin needs to
+// set locks of its own (on mutexes defined inside the plugin code), it shall do so
+// after setting any locks on VDR's global lists, and it shall always set these
+// locks in the same sequence, to avoid deadlocks.
+
 enum eMessageType { mtStatus = 0, mtInfo, mtWarning, mtError }; // will be used to calculate color offsets!
 
 class cSkinDisplay {
@@ -220,16 +233,24 @@ public:
        ///< this function will be first called for the old current item
        ///< with Current set to false, and then for the new current item
        ///< with Current set to true.
-  virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch) { return false; }
+  virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch, bool TimerActive) { return false; }
        ///< Sets the item at the given Index to Event. See SetItem() for more information.
        ///< If a derived skin class implements this function, it can display an Event item
        ///< in a more elaborate way than just a simple line of text.
        ///< If Channel is not NULL, the channel's name and/or number shall be displayed.
        ///< If WithDate is true, the date of the Event shall be displayed (in addition to the time).
        ///< TimerMatch tells how much of this event will be recorded by a timer.
+       ///< TimerActive tells whether the timer that will record this event is active.
        ///< If the skin displays the Event item in its own way, it shall return true.
        ///< The default implementation does nothing and returns false, which results in
        ///< a call to SetItem() with a proper text.
+#define DEPRECATED_SKIN_SETITEMEVENT
+#ifdef DEPRECATED_SKIN_SETITEMEVENT
+  virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch) { return SetItemEvent(Event, Index, Current, Selectable, Channel, WithDate, TimerMatch, true); }
+       ///< This function is here for comaptibility with older plugins and may be removed
+       ///< in a future version. Use the above version of SetItemEvent() with the TimerActive
+       ///< parameter instead.
+#endif
   virtual bool SetItemTimer(const cTimer *Timer, int Index, bool Current, bool Selectable) { return false; }
        ///< Sets the item at the given Index to Timer. See SetItem() for more information.
        ///< If a derived skin class implements this function, it can display a Timer item
diff --git a/status.h b/status.h
index 6d1b9df..c8a9e1f 100644
--- a/status.h
+++ b/status.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: status.h 4.1 2015/08/02 10:34:44 kls Exp $
+ * $Id: status.h 4.3 2017/06/23 09:08:24 kls Exp $
  */
 
 #ifndef __STATUS_H
@@ -15,6 +15,19 @@
 #include "player.h"
 #include "tools.h"
 
+// Several member functions of the following classes are called with a pointer to
+// an object from a global list (cTimer, cChannel, cRecording or cEvent). In these
+// cases the core VDR code holds a lock on the respective list. While in general a
+// plugin should only work with the objects and data that is explicitly given to it
+// in the function call, the called function may itself set a read lock (not a write
+// lock!) on this list, because read locks can be nested. It may also set read locks
+// (not write locks!) on higher order lists.
+// For instance, a function that is called with a cChannel may lock cRecordings and/or
+// cSchedules (which contains cEvent objects), but not cTimers. If a plugin needs to
+// set locks of its own (on mutexes defined inside the plugin code), it shall do so
+// after setting any locks on VDR's global lists, and it shall always set these
+// locks in the same sequence, to avoid deadlocks.
+
 enum eTimerChange { tcMod, tcAdd, tcDel }; // tcMod is obsolete and no longer used!
 
 class cTimer;
diff --git a/svdrp.c b/svdrp.c
index 2b63c80..3769575 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
  * and interact with the Video Disk Recorder - or write a full featured
  * graphical interface that sits on top of an SVDRP connection.
  *
- * $Id: svdrp.c 4.20 2017/05/31 14:02:17 kls Exp $
+ * $Id: svdrp.c 4.22 2017/06/30 09:49:39 kls Exp $
  */
 
 #include "svdrp.h"
@@ -549,7 +549,7 @@ cSVDRPClient *cSVDRPClientHandler::GetClientForServer(const char *ServerName)
 void cSVDRPClientHandler::SendDiscover(const char *Address)
 {
   cMutexLock MutexLock(&mutex);
-  cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout);
+  cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d%s", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout, (Setup.SVDRPPeering == spmOnly && *Setup.SVDRPDefaultHost) ? *cString::sprintf(" host:%s", Setup.SVDRPDefaultHost) : "");
   udpSocket.SendDgram(Dgram, udpSocket.Port(), Address);
 }
 
@@ -580,6 +580,11 @@ void cSVDRPClientHandler::HandleClientConnection(void)
             }
         cString ServerName = strgetval(NewDiscover, "name", ':');
         if (*ServerName) {
+           if (Setup.SVDRPPeering == spmOnly && strcmp(ServerName, Setup.SVDRPDefaultHost) != 0)
+              return; // we only want to peer with the default host, but this isn't the default host
+           cString HostName = strgetval(NewDiscover, "host", ':');
+           if (*HostName && strcmp(HostName, Setup.SVDRPHostName) != 0)
+              return; // the remote VDR requests a specific host, but it's not us
            cString t = strgetval(NewDiscover, "timeout", ':');
            if (*t) {
               int Timeout = atoi(t);
@@ -2600,3 +2605,15 @@ bool ExecSVDRPCommand(const char *ServerName, const char *Command, cStringList *
      return SVDRPClientHandler->Execute(ServerName, Command, Response);
   return false;
 }
+
+void BroadcastSVDRPCommand(const char *Command)
+{
+  cMutexLock MutexLock(&SVDRPHandlerMutex);
+  cStringList ServerNames;
+  if (SVDRPClientHandler) {
+     if (SVDRPClientHandler->GetServerNames(&ServerNames)) {
+        for (int i = 0; i < ServerNames.Size(); i++)
+            ExecSVDRPCommand(ServerNames[i], Command);
+        }
+     }
+}
diff --git a/svdrp.h b/svdrp.h
index ba33fc2..e0d3616 100644
--- a/svdrp.h
+++ b/svdrp.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: svdrp.h 4.5 2015/09/09 09:44:12 kls Exp $
+ * $Id: svdrp.h 4.7 2017/06/30 09:49:39 kls Exp $
  */
 
 #ifndef __SVDRP_H
@@ -12,6 +12,12 @@
 
 #include "tools.h"
 
+enum eSvdrpPeerModes {
+  spmOff  = 0,
+  spmAny  = 1,
+  spmOnly = 2,
+  };
+
 enum eSvdrpFetchFlags {
   sffNone   = 0b0000,
   sffTimers = 0b0001,
@@ -42,6 +48,8 @@ bool ExecSVDRPCommand(const char *ServerName, const char *Command, cStringList *
      ///< resulting strings from the remote VDR, which can be accessed
      ///< through Response. If Response is given, it will be cleared before
      ///< the command is actually executed.
+void BroadcastSVDRPCommand(const char *Command);
+     ///< Sends the given SVDRP Command string to all remote VDRs.
 inline int SVDRPCode(const char *s) { return s ? atoi(s) : 0; }
      ///< Returns the value of the three digit reply code of the given
      ///< SVDRP response string.
diff --git a/thread.c b/thread.c
index 2753679..8fc2340 100644
--- a/thread.c
+++ b/thread.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: thread.c 4.9 2017/06/09 08:27:22 kls Exp $
+ * $Id: thread.c 4.11 2017/06/25 12:08:16 kls Exp $
  */
 
 #include "thread.h"
@@ -558,6 +558,7 @@ cString cBackTrace::GetCaller(int Level, bool Mangled)
 #ifdef DEBUG_LOCKSEQ
 #define SLL_SIZE     20 // the number of log entries
 #define SLL_LENGTH  512 // the maximum length of log entries
+#define SLL_THREADS  20 // the maximum number of threads holding locks at the same time (typically well below 10)
 #define SLL_MAX_LIST  9 // max. number of lists to log
 #define SLL_WRITE_FLAG 0x80000000
 #define SLL_LOCK_FLAG  0x40000000
@@ -569,7 +570,7 @@ private:
   cVector<int> flags;
   tThreadId logThreadIds[SLL_SIZE];
   int logFlags[SLL_SIZE];
-  uint8_t logCounter[SLL_SIZE][SLL_MAX_LIST];
+  uint8_t logCounter[SLL_THREADS][SLL_MAX_LIST];
 #ifdef DEBUG_LOCKCALL
   char logCaller[SLL_SIZE][SLL_LENGTH];
 #endif
@@ -633,6 +634,7 @@ void cStateLockLog::Dump(const char *Name, tThreadId ThreadId)
   dsyslog("full backtrace:");
   cBackTrace::BackTrace(NULL, 2);
   dsyslog("--- end invalid lock sequence report");
+  dsyslog("--- THERE WILL BE NO FURTHER REPORTS UNTIL VDR IS RESTARTED!");
   fprintf(stderr, "invalid lock sequence at %s\n", *DayDateTime(time(NULL)));
 }
 
@@ -644,15 +646,32 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
         int b = 1 << n;
         cMutexLock MutexLock(&mutex);
         tThreadId ThreadId = cThread::ThreadId();
-        int Index = threadIds.IndexOf(ThreadId);
+        int Index = -1;
+        int AvailableIndex = -1;
+        for (int i = 0; i < threadIds.Size(); i++) {
+            if (ThreadId == threadIds[i]) {
+               Index = i;
+               break;
+               }
+            if (threadIds[i] == 0)
+               AvailableIndex = i;
+            }
         if (Index < 0) {
-           if (Lock) {
+           if (AvailableIndex < 0) {
               Index = threadIds.Size();
               threadIds.Append(ThreadId);
               flags.Append(0);
               }
-           else
-              return;
+           else {
+              Index = AvailableIndex;
+              threadIds[Index] = ThreadId;
+              }
+           }
+        if (Index >= SLL_THREADS) {
+           // should never happen!
+           esyslog("ERROR: too many threads holding list locks at the same time - stopped logging locks!");
+           dumped = true;
+           return;
            }
         bool DoDump = false;
         if (Lock) {
@@ -667,6 +686,8 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
            flags[Index] &= ~b;
         logThreadIds[logIndex] = ThreadId;
         logFlags[logIndex] = flags[Index] | (Write ? SLL_WRITE_FLAG : 0) | (Lock ? SLL_LOCK_FLAG : 0);
+        if (flags[Index] == 0)
+           threadIds[Index] = 0;
 #ifdef DEBUG_LOCKCALL
         strn0cpy(logCaller[logIndex], cBackTrace::GetCaller(Lock ? 3 : 5, true), SLL_LENGTH);
 #endif
diff --git a/timers.c b/timers.c
index 95cb723..8987b12 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: timers.c 4.10 2017/05/26 15:43:38 kls Exp $
+ * $Id: timers.c 4.11 2017/06/25 10:02:09 kls Exp $
  */
 
 #include "timers.h"
@@ -476,7 +476,7 @@ eTimerMatch cTimer::Matches(const cEvent *Event, int *Overlap) const
   // To make sure a VPS timer can be distinguished from a plain 100% overlap,
   // it gets an additional 100 added, and a VPS event that is actually running
   // gets 200 added to the FULLMATCH.
-  if (HasFlags(tfActive) && channel->GetChannelID() == Event->ChannelID()) {
+  if (channel->GetChannelID() == Event->ChannelID()) {
      bool UseVps = HasFlags(tfVps) && Event->Vps();
      Matches(UseVps ? Event->Vps() : Event->StartTime(), true);
      int overlap = 0;
diff --git a/tools.c b/tools.c
index a8e6af1..ac2f9eb 100644
--- a/tools.c
+++ b/tools.c
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.c 4.6 2017/05/09 08:32:54 kls Exp $
+ * $Id: tools.c 4.8 2017/06/25 11:45:39 kls Exp $
  */
 
 #include "tools.h"
@@ -371,6 +371,8 @@ bool StrInArray(const char *a[], const char *s)
 
 cString AddDirectory(const char *DirName, const char *FileName)
 {
+  if (*FileName == '/')
+     FileName++;
   return cString::sprintf("%s/%s", DirName && *DirName ? DirName : ".", FileName);
 }
 
@@ -1526,7 +1528,11 @@ cReadDir::~cReadDir()
 struct dirent *cReadDir::Next(void)
 {
   if (directory) {
+#if !__GLIBC_PREREQ(2, 24) // readdir_r() is deprecated as of GLIBC 2.24
      while (readdir_r(directory, &u.d, &result) == 0 && result) {
+#else
+     while ((result = readdir(directory)) != NULL) {
+#endif
            if (strcmp(result->d_name, ".") && strcmp(result->d_name, ".."))
               return result;
            }
diff --git a/tools.h b/tools.h
index 5894a18..aaba602 100644
--- a/tools.h
+++ b/tools.h
@@ -4,7 +4,7 @@
  * See the main source file 'vdr.c' for copyright information and
  * how to reach the author.
  *
- * $Id: tools.h 4.12 2017/06/11 10:00:49 kls Exp $
+ * $Id: tools.h 4.13 2017/06/25 11:45:38 kls Exp $
  */
 
 #ifndef __TOOLS_H
@@ -400,10 +400,12 @@ class cReadDir {
 private:
   DIR *directory;
   struct dirent *result;
+#if !__GLIBC_PREREQ(2, 24) // readdir_r() is deprecated as of GLIBC 2.24
   union { // according to "The GNU C Library Reference Manual"
     struct dirent d;
     char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
     } u;
+#endif
 public:
   cReadDir(const char *Directory);
   ~cReadDir();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr.git



More information about the pkg-vdr-dvb-changes mailing list