diff options
| author | Klaus Schmidinger <vdr@tvdr.de> | 2015-09-08 11:08:06 +0200 | 
|---|---|---|
| committer | Klaus Schmidinger <vdr@tvdr.de> | 2015-09-08 11:08:06 +0200 | 
| commit | 4e3325b7f7e30d1013798d74b8e7e0b8471813b1 (patch) | |
| tree | c5082d2ea7afddbec5cfeda720daee873d9f11aa | |
| parent | 3284e941c6ab7f59c4fbfa78d4976d756aec0731 (diff) | |
| download | vdr-4e3325b7f7e30d1013798d74b8e7e0b8471813b1.tar.gz vdr-4e3325b7f7e30d1013798d74b8e7e0b8471813b1.tar.bz2 | |
Implemented setup options for SVDRP peering
| -rw-r--r-- | HISTORY | 6 | ||||
| -rw-r--r-- | MANUAL | 9 | ||||
| -rw-r--r-- | config.c | 10 | ||||
| -rw-r--r-- | config.h | 5 | ||||
| -rw-r--r-- | menu.c | 49 | ||||
| -rw-r--r-- | menuitems.c | 22 | ||||
| -rw-r--r-- | menuitems.h | 14 | ||||
| -rw-r--r-- | svdrp.c | 65 | ||||
| -rw-r--r-- | svdrp.h | 10 | ||||
| -rw-r--r-- | timers.c | 6 | ||||
| -rw-r--r-- | tools.c | 16 | ||||
| -rw-r--r-- | tools.h | 4 | ||||
| -rw-r--r-- | vdr.c | 10 | 
13 files changed, 180 insertions, 46 deletions
| @@ -8596,7 +8596,7 @@ Video Disk Recorder Revision History  - Bumped all version numbers to 2.2.0.  - Official release. -2015-09-06: Version 2.3.1 +2015-09-08: Version 2.3.1  - The new function cOsd::MaxPixmapSize() can be called to determine the maximum size    a cPixmap may have on the current OSD. The 'osddemo' example has been modified @@ -8791,3 +8791,7 @@ Video Disk Recorder Revision History    gaps in the sequence, in case timers have been deleted.  - The Timers menu now displays the name of the remote VDR in front of the timer's    file name, if this is a remote timer. +- The new options "Setup/Miscellaneous/SVDRP peering", ".../SVDRP host name" and +  ".../SVDRP default host" can be used to configure automatic peering between VDRs +  in the same network. Peering is disabled by default and can be enabled by setting +  "SVDRP peering" to "yes". @@ -1071,6 +1071,15 @@ 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 host name        The name of this VDR, which is used when connecting VDRs +                         via SVDRP. By default, the machine's host name is used. + +  SVDRP default host     The name of the VDR to be used by default when creating a +                         new timer. +    Zap timeout = 3        The time (in seconds) until a channel counts as "previous"                           for switching with '0' @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: config.c 4.1 2015/04/18 13:09:31 kls Exp $ + * $Id: config.c 4.2 2015/09/06 13:17:19 kls Exp $   */  #include "config.h" @@ -412,6 +412,9 @@ cSetup::cSetup(void)    EPGBugfixLevel = 3;    EPGLinger = 0;    SVDRPTimeout = 300; +  SVDRPPeering = 0; +  strn0cpy(SVDRPHostName, GetHostName(), sizeof(SVDRPHostName)); +  strcpy(SVDRPDefaultHost, "");    ZapTimeout = 3;    ChannelEntryTimeout = 1000;    RcRepeatDelay = 300; @@ -635,6 +638,9 @@ bool cSetup::Parse(const char *Name, const char *Value)    else if (!strcasecmp(Name, "EPGBugfixLevel"))      EPGBugfixLevel     = atoi(Value);    else if (!strcasecmp(Name, "EPGLinger"))           EPGLinger          = atoi(Value);    else if (!strcasecmp(Name, "SVDRPTimeout"))        SVDRPTimeout       = atoi(Value); +  else if (!strcasecmp(Name, "SVDRPPeering"))        SVDRPPeering       = atoi(Value); +  else if (!strcasecmp(Name, "SVDRPHostName"))       strn0cpy(SVDRPHostName, Value, sizeof(SVDRPHostName)); +  else if (!strcasecmp(Name, "SVDRPdefaultHost"))    strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));    else if (!strcasecmp(Name, "ZapTimeout"))          ZapTimeout         = atoi(Value);    else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value);    else if (!strcasecmp(Name, "RcRepeatDelay"))       RcRepeatDelay      = atoi(Value); @@ -762,6 +768,8 @@ bool cSetup::Save(void)    Store("EPGBugfixLevel",     EPGBugfixLevel);    Store("EPGLinger",          EPGLinger);    Store("SVDRPTimeout",       SVDRPTimeout); +  Store("SVDRPPeering",       SVDRPPeering); +  Store("SVDRPDefaultHost",   SVDRPDefaultHost);    Store("ZapTimeout",         ZapTimeout);    Store("ChannelEntryTimeout",ChannelEntryTimeout);    Store("RcRepeatDelay",      RcRepeatDelay); @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: config.h 4.3 2015/08/09 09:17:46 kls Exp $ + * $Id: config.h 4.4 2015/09/06 09:50:13 kls Exp $   */  #ifndef __CONFIG_H @@ -288,6 +288,9 @@ public:    int EPGBugfixLevel;    int EPGLinger;    int SVDRPTimeout; +  int SVDRPPeering; +  char SVDRPHostName[HOST_NAME_MAX]; +  char SVDRPDefaultHost[HOST_NAME_MAX];    int ZapTimeout;    int ChannelEntryTimeout;    int RcRepeatDelay; @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: menu.c 4.4 2015/09/06 09:28:24 kls Exp $ + * $Id: menu.c 4.5 2015/09/08 11:02:52 kls Exp $   */  #include "menu.h" @@ -27,6 +27,7 @@  #include "sourceparams.h"  #include "sources.h"  #include "status.h" +#include "svdrp.h"  #include "themes.h"  #include "timers.h"  #include "transfer.h" @@ -3897,17 +3898,36 @@ void cMenuSetupReplay::Store(void)  // --- cMenuSetupMisc --------------------------------------------------------  class cMenuSetupMisc : public cMenuSetupBase { +private: +  cStringList svdrpServerNames; +  void Set(void);  public:    cMenuSetupMisc(void); +  virtual eOSState ProcessKey(eKeys Key);    };  cMenuSetupMisc::cMenuSetupMisc(void)  {    SetMenuCategory(mcSetupMisc);    SetSection(tr("Miscellaneous")); +  Set(); +} + +void cMenuSetupMisc::Set(void) +{ +  int current = Current(); +  Clear();    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)); +  if (data.SVDRPPeering) { +     Add(new cMenuEditStrItem( tr("Setup.Miscellaneous$SVDRP host name"), data.SVDRPHostName, sizeof(data.SVDRPHostName))); +     if (GetSVDRPServerNames(&svdrpServerNames)) { +        svdrpServerNames.Sort(true); +        Add(new cMenuEditStrlItem(tr("Setup.Miscellaneous$SVDRP default host"), data.SVDRPDefaultHost, sizeof(data.SVDRPDefaultHost), &svdrpServerNames)); +        } +     }    Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Zap timeout (s)"),            &data.ZapTimeout));    Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0));    Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delay (ms)"), &data.RcRepeatDelay, 0)); @@ -3919,6 +3939,33 @@ cMenuSetupMisc::cMenuSetupMisc(void)    Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Channels wrap"),              &data.ChannelsWrap));    Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Show channel names with source"), &data.ShowChannelNamesWithSource));    Add(new cMenuEditBoolItem(tr("Setup.Miscellaneous$Emergency exit"),             &data.EmergencyExit)); +  SetCurrent(Get(current)); +  Display(); +} + +eOSState cMenuSetupMisc::ProcessKey(eKeys Key) +{ +  bool OldSVDRPPeering = data.SVDRPPeering; +  bool ModifiedSVDRPSettings = false; +  if (Key == kOk) +     ModifiedSVDRPSettings = data.SVDRPPeering != Setup.SVDRPPeering | strcmp(data.SVDRPHostName, Setup.SVDRPHostName); +  eOSState state = cMenuSetupBase::ProcessKey(Key); +  if (data.SVDRPPeering != OldSVDRPPeering) +     Set(); +  if (ModifiedSVDRPSettings) { +     StopSVDRPClientHandler(); +     StopSVDRPServerHandler(); +     StartSVDRPServerHandler(); +     if (data.SVDRPPeering) +        StartSVDRPClientHandler(); +     else { +        LOCK_TIMERS_WRITE; +        Timers->SetExplicitModify(); +        if (Timers->DelRemoteTimers()) +           Timers->SetModified(); +        } +     } +  return state;  }  // --- cMenuSetupPluginItem -------------------------------------------------- diff --git a/menuitems.c b/menuitems.c index c07ad2a7..659c1a58 100644 --- a/menuitems.c +++ b/menuitems.c @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: menuitems.c 4.1 2015/07/18 10:38:31 kls Exp $ + * $Id: menuitems.c 4.2 2015/09/08 10:25:23 kls Exp $   */  #include "menuitems.h" @@ -774,6 +774,26 @@ void cMenuEditStraItem::Set(void)    SetValue(strings[*value]);  } +// --- cMenuEditStrlItem ----------------------------------------------------- + +cMenuEditStrlItem::cMenuEditStrlItem(const char *Name, char *Value, int Length, const cStringList *Strings) +:cMenuEditIntItem(Name, &index, 0, Strings->Size() - 1) +{ +  strings = Strings; +  value = Value; +  length = Length; +  index = strings->Find(value); +  if (index < 0) +     index = 0; +  Set(); +} + +void cMenuEditStrlItem::Set(void) +{ +  strn0cpy(value, strings->At(index), length); +  SetValue(value); +} +  // --- cMenuEditChanItem -----------------------------------------------------  cMenuEditChanItem::cMenuEditChanItem(const char *Name, int *Value, const char *NoneString) diff --git a/menuitems.h b/menuitems.h index 2a30b465..44f6fec5 100644 --- a/menuitems.h +++ b/menuitems.h @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: menuitems.h 3.1 2013/05/24 10:19:55 kls Exp $ + * $Id: menuitems.h 4.1 2015/09/06 10:38:37 kls Exp $   */  #ifndef __MENUITEMS_H @@ -146,6 +146,18 @@ public:    cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings);    }; +class cMenuEditStrlItem : public cMenuEditIntItem { +private: +  const cStringList *strings; +  int index; +  char *value; +  int length; +protected: +  virtual void Set(void); +public: +  cMenuEditStrlItem(const char *Name, char *Value, int Length, const cStringList *Strings); +  }; +  class cMenuEditChanItem : public cMenuEditIntItem {  protected:    const char *noneString; @@ -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.5 2015/09/06 09:25:16 kls Exp $ + * $Id: svdrp.c 4.6 2015/09/08 11:08:06 kls Exp $   */  #include "svdrp.h" @@ -45,17 +45,8 @@ static bool DumpSVDRPDataTransfer = false;  #define dbgsvdrp(a...) if (DumpSVDRPDataTransfer) fprintf(stderr, a) -const char *SVDRPHostName(void) -{ -  static char buffer[HOST_NAME_MAX] = ""; -  if (!*buffer) { -     if (gethostname(buffer, sizeof(buffer)) < 0) { -        LOG_ERROR; -        strcpy(buffer, "vdr"); -        } -     } -  return buffer; -} +static int SVDRPTcpPort = 0; +static int SVDRPUdpPort = 0;  // --- cIpAddress ------------------------------------------------------------ @@ -375,7 +366,6 @@ cSVDRPClient::cSVDRPClient(const char *Address, int Port, const char *ServerName       if (file.Open(socket.Socket())) {          SVDRPClientPoller.Add(file, false);          dsyslog("SVDRP > %s client created for '%s'", ipAddress.Connection(), *serverName); -        SendSVDRPDiscover(Address);          return;          }       } @@ -510,8 +500,8 @@ bool cSVDRPClient::HasFetchFlag(eSvdrpFetchFlags Flag)  class cSVDRPClientHandler : public cThread {  private:    cMutex mutex; -  cSocket udpSocket;    int tcpPort; +  cSocket udpSocket;    cVector<cSVDRPClient *> clientConnections;    void HandleClientConnection(void);    void ProcessConnections(void); @@ -519,7 +509,7 @@ private:  protected:    virtual void Action(void);  public: -  cSVDRPClientHandler(int UdpPort, int TcpPort); +  cSVDRPClientHandler(int TcpPort, int UdpPort);    virtual ~cSVDRPClientHandler();    void SendDiscover(const char *Address = NULL);    bool Execute(const char *ServerName, const char *Command, cStringList *Response); @@ -529,7 +519,7 @@ public:  static cSVDRPClientHandler *SVDRPClientHandler = NULL; -cSVDRPClientHandler::cSVDRPClientHandler(int UdpPort, int TcpPort) +cSVDRPClientHandler::cSVDRPClientHandler(int TcpPort, int UdpPort)  :cThread("SVDRP client handler", true)  ,udpSocket(UdpPort, false)  { @@ -555,7 +545,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", SVDRPHostName(), tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout); +  cString Dgram = cString::sprintf("SVDRP:discover name:%s port:%d vdrversion:%d apiversion:%d timeout:%d", Setup.SVDRPHostName, tcpPort, VDRVERSNUM, APIVERSNUM, Setup.SVDRPTimeout);    udpSocket.SendDgram(Dgram, udpSocket.Port(), Address);  } @@ -589,8 +579,11 @@ void cSVDRPClientHandler::HandleClientConnection(void)             cString t = strgetval(NewDiscover, "timeout", ':');             if (*t) {                int Timeout = atoi(t); -              if (Timeout > 10) // don't let it get too small -                 clientConnections.Append(new cSVDRPClient(udpSocket.LastIpAddress()->Address(), Port, ServerName, Timeout)); +              if (Timeout > 10) { // don't let it get too small +                 const char *Address = udpSocket.LastIpAddress()->Address(); +                 clientConnections.Append(new cSVDRPClient(Address, Port, ServerName, Timeout)); +                 SendDiscover(Address); +                 }                else                   esyslog("SVDRP < %s ERROR: invalid timeout (%d)", udpSocket.LastIpAddress()->Connection(), Timeout);                } @@ -999,7 +992,7 @@ cSVDRPServer::cSVDRPServer(int Socket, const char *Connection)    lastActivity = time(NULL);    if (file.Open(socket)) {       time_t now = time(NULL); -     Reply(220, "%s SVDRP VideoDiskRecorder %s; %s; %s", SVDRPHostName(), VDRVERSION, *TimeToString(now), cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8"); +     Reply(220, "%s SVDRP VideoDiskRecorder %s; %s; %s", Setup.SVDRPHostName, VDRVERSION, *TimeToString(now), cCharSetConv::SystemCharacterTable() ? cCharSetConv::SystemCharacterTable() : "UTF-8");       SVDRPServerPoller.Add(file, false);       }    dsyslog("SVDRP < %s server created", *connection); @@ -1016,7 +1009,7 @@ void cSVDRPServer::Close(bool SendReply, bool Timeout)  {    if (file.IsOpen()) {       if (SendReply) { -        Reply(221, "%s closing connection%s", SVDRPHostName(), Timeout ? " (timeout)" : ""); +        Reply(221, "%s closing connection%s", Setup.SVDRPHostName, Timeout ? " (timeout)" : "");          }       isyslog("SVDRP < %s connection closed", *connection);       SVDRPServerPoller.Del(file, false); @@ -2044,7 +2037,7 @@ void cSVDRPServer::CmdNEXT(const char *Option)  void cSVDRPServer::CmdPING(const char *Option)  { -  Reply(250, "%s is alive", SVDRPHostName()); +  Reply(250, "%s is alive", Setup.SVDRPHostName);  }  void cSVDRPServer::CmdPLAY(const char *Option) @@ -2434,6 +2427,12 @@ bool cSVDRPServer::Process(void)    return file.IsOpen();  } +void SetSVDRPPorts(int TcpPort, int UdpPort) +{ +  SVDRPTcpPort = TcpPort; +  SVDRPUdpPort = UdpPort; +} +  void SetSVDRPGrabImageDir(const char *GrabImageDir)  {    grabImageDir = GrabImageDir; @@ -2519,25 +2518,35 @@ void cSVDRPServerHandler::Action(void)  static cMutex SVDRPHandlerMutex; -void StartSVDRPHandler(int TcpPort, int UdpPort) +void StartSVDRPServerHandler(void)  {    cMutexLock MutexLock(&SVDRPHandlerMutex); -  if (TcpPort && !SVDRPServerHandler) { -     SVDRPServerHandler = new cSVDRPServerHandler(TcpPort); +  if (SVDRPTcpPort && !SVDRPServerHandler) { +     SVDRPServerHandler = new cSVDRPServerHandler(SVDRPTcpPort);       SVDRPServerHandler->Start();       SVDRPServerHandler->WaitUntilReady();       } -  if (UdpPort && !SVDRPClientHandler) { -     SVDRPClientHandler = new cSVDRPClientHandler(UdpPort, TcpPort); +} + +void StartSVDRPClientHandler(void) +{ +  cMutexLock MutexLock(&SVDRPHandlerMutex); +  if (SVDRPTcpPort && SVDRPUdpPort && !SVDRPClientHandler) { +     SVDRPClientHandler = new cSVDRPClientHandler(SVDRPTcpPort, SVDRPUdpPort);       SVDRPClientHandler->Start();       }  } -void StopSVDRPHandler(void) +void StopSVDRPServerHandler(void)  {    cMutexLock MutexLock(&SVDRPHandlerMutex);    delete SVDRPServerHandler;    SVDRPServerHandler = NULL; +} + +void StopSVDRPClientHandler(void) +{ +  cMutexLock MutexLock(&SVDRPHandlerMutex);    delete SVDRPClientHandler;    SVDRPClientHandler = NULL;  } @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: svdrp.h 4.3 2015/09/01 10:34:09 kls Exp $ + * $Id: svdrp.h 4.4 2015/09/06 12:39:24 kls Exp $   */  #ifndef __SVDRP_H @@ -57,10 +57,12 @@ enum eSvdrpFetchFlags {    sffTimers = 0b0001,    }; -const char *SVDRPHostName(void); +void SetSVDRPPorts(int TcpPort, int UdpPort);  void SetSVDRPGrabImageDir(const char *GrabImageDir); -void StartSVDRPHandler(int TcpPort, int UdpPort); -void StopSVDRPHandler(void); +void StartSVDRPServerHandler(void); +void StartSVDRPClientHandler(void); +void StopSVDRPServerHandler(void); +void StopSVDRPClientHandler(void);  void SendSVDRPDiscover(const char *Address = NULL);  bool GetSVDRPServerNames(cStringList *ServerNames, eSvdrpFetchFlags FetchFlag = sffNone);       ///< Gets a list of all available VDRs this VDR is connected to via SVDRP, @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: timers.c 4.2 2015/09/05 14:42:50 kls Exp $ + * $Id: timers.c 4.3 2015/09/08 10:01:02 kls Exp $   */  #include "timers.h" @@ -939,9 +939,9 @@ bool cTimers::DelRemoteTimers(const char *ServerName)  void cTimers::TriggerRemoteTimerPoll(const char *ServerName)  {    if (ServerName) { -     cSVDRPCommand Cmd(ServerName, cString::sprintf("POLL %s TIMERS", SVDRPHostName())); +     cSVDRPCommand Cmd(ServerName, cString::sprintf("POLL %s TIMERS", Setup.SVDRPHostName));       if (!Cmd.Execute()) -        esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", SVDRPHostName(), ServerName); +        esyslog("ERROR: can't send 'POLL %s TIMERS' to '%s'", Setup.SVDRPHostName, ServerName);       }    else {       cStringList ServerNames; @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: tools.c 4.2 2015/08/29 12:11:20 kls Exp $ + * $Id: tools.c 4.3 2015/09/06 10:47:05 kls Exp $   */  #include "tools.h" @@ -1322,6 +1322,20 @@ uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)    return jcd.mem;  } +// --- GetHostName ----------------------------------------------------------- + +const char *GetHostName(void) +{ +  static char buffer[HOST_NAME_MAX] = ""; +  if (!*buffer) { +     if (gethostname(buffer, sizeof(buffer)) < 0) { +        LOG_ERROR; +        strcpy(buffer, "vdr"); +        } +     } +  return buffer; +} +  // --- cBase64Encoder --------------------------------------------------------  const char *cBase64Encoder::b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: tools.h 4.2 2015/08/29 11:45:51 kls Exp $ + * $Id: tools.h 4.3 2015/09/06 10:45:54 kls Exp $   */  #ifndef __TOOLS_H @@ -293,6 +293,8 @@ uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality = 100      ///< resulting image, where 100 is "best". The caller takes ownership of      ///< the result and has to delete it once it is no longer needed.      ///< The result may be NULL in case of an error. +const char *GetHostName(void); +    ///< Gets the host name of this machine.  class cBase64Encoder {  private: @@ -22,7 +22,7 @@   *   * The project's page is at http://www.tvdr.de   * - * $Id: vdr.c 4.5 2015/09/01 10:33:04 kls Exp $ + * $Id: vdr.c 4.6 2015/09/08 10:00:46 kls Exp $   */  #include <getopt.h> @@ -919,7 +919,10 @@ int main(int argc, char *argv[])    // SVDRP: -  StartSVDRPHandler(SVDRPport, DEFAULTSVDRPPORT); +  SetSVDRPPorts(SVDRPport, DEFAULTSVDRPPORT); +  StartSVDRPServerHandler(); +  if (Setup.SVDRPPeering) +     StartSVDRPClientHandler();    // Main program loop: @@ -1524,7 +1527,8 @@ Exit:    signal(SIGPIPE, SIG_DFL);    signal(SIGALRM, SIG_DFL); -  StopSVDRPHandler(); +  StopSVDRPClientHandler(); +  StopSVDRPServerHandler();    PluginManager.StopPlugins();    cRecordControls::Shutdown();    RecordingsHandler.DelAll(); | 
