diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 63c6874..6457868 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -229,3 +229,6 @@ hummel99 Henrik Niehaus for fixing replay of large TS files on 32-bit systems + +Guy Martin + for adding SVDRP commands to list and disconnect clients diff --git a/HISTORY b/HISTORY index e9abfa0..df58351 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,7 @@ VDR Plugin 'streamdev' Revision History --------------------------------------- +- added SVDRP commands to list and disconnect clients (thanks to Guy Martin) - fixed recplayer issues with large TS files (>4GB) - Don't abort externremux when internal read buffer is empty - Implemented remuxing of recordings diff --git a/server/connection.c b/server/connection.c index 764ca02..56be407 100644 --- a/server/connection.c +++ b/server/connection.c @@ -197,5 +197,7 @@ bool cServerConnection::Close() return cTBSocket::Close(); } -cString cServerConnection::ToText() const -{ return cString::sprintf("%s\t%s:%d", Protocol(), RemoteIp().c_str(), RemotePort()); } +cString cServerConnection::ToText(char Delimiter) const +{ + return cString::sprintf("%s%c%s:%d", Protocol(), Delimiter, RemoteIp().c_str(), RemotePort()); +} diff --git a/server/connection.h b/server/connection.h index e7379be..3df1148 100644 --- a/server/connection.h +++ b/server/connection.h @@ -108,8 +108,8 @@ public: /* This connections protocol name */ virtual const char* Protocol(void) const { return m_Protocol; } - /* Representation in menu */ - virtual cString ToText(void) const; + /* Text description of stream */ + virtual cString ToText(char Delimiter = ' ') const; /* std::map with additional information */ const tStrStrMap& Headers(void) const { return m_Headers; } diff --git a/server/connectionHTTP.c b/server/connectionHTTP.c index bec9bef..922bd04 100644 --- a/server/connectionHTTP.c +++ b/server/connectionHTTP.c @@ -649,8 +649,8 @@ bool cConnectionHTTP::ProcessURI(const std::string& PathInfo) return false; } -cString cConnectionHTTP::ToText() const +cString cConnectionHTTP::ToText(char Delimiter) const { - cString str = cServerConnection::ToText(); - return Streamer() ? cString::sprintf("%s\t%s", *str, *Streamer()->ToText()) : str; + cString str = cServerConnection::ToText(Delimiter); + return Streamer() ? cString::sprintf("%s%c%s", *str, Delimiter, *Streamer()->ToText()) : str; } diff --git a/server/connectionHTTP.h b/server/connectionHTTP.h index d968c3e..8772e77 100644 --- a/server/connectionHTTP.h +++ b/server/connectionHTTP.h @@ -59,7 +59,7 @@ public: cConnectionHTTP(void); virtual ~cConnectionHTTP(); - virtual cString ToText() const; + virtual cString ToText(char Delimiter = ' ') const; virtual bool CanAuthenticate(void); diff --git a/server/connectionIGMP.c b/server/connectionIGMP.c index ced2209..f2a34fc 100644 --- a/server/connectionIGMP.c +++ b/server/connectionIGMP.c @@ -66,8 +66,8 @@ bool cConnectionIGMP::Close() return cServerConnection::Close(); } -cString cConnectionIGMP::ToText() const +cString cConnectionIGMP::ToText(char Delimiter) const { - cString str = cServerConnection::ToText(); - return Streamer() ? cString::sprintf("%s\t%s", *str, *Streamer()->ToText()) : str; + cString str = cServerConnection::ToText(Delimiter); + return Streamer() ? cString::sprintf("%s%c%s", *str, Delimiter, *Streamer()->ToText()) : str; } diff --git a/server/connectionIGMP.h b/server/connectionIGMP.h index 23ca042..89292b2 100644 --- a/server/connectionIGMP.h +++ b/server/connectionIGMP.h @@ -27,7 +27,7 @@ public: bool SetChannel(cChannel *Channel, in_addr_t Dst); virtual void Welcome(void); - virtual cString ToText() const; + virtual cString ToText(char Delimiter = ' ') const; /* Not used here */ virtual bool Command(char *Cmd) { return false; } diff --git a/server/connectionVTP.c b/server/connectionVTP.c index 698d33c..05c49ee 100644 --- a/server/connectionVTP.c +++ b/server/connectionVTP.c @@ -1836,13 +1836,13 @@ bool cConnectionVTP::Respond(int Code, const char *Message, ...) Code < 0 ? '-' : ' ', *str); } -cString cConnectionVTP::ToText() const +cString cConnectionVTP::ToText(char Delimiter) const { - cString str = cServerConnection::ToText(); + cString str = cServerConnection::ToText(Delimiter); if (Streamer()) - return cString::sprintf("%s\t%s", *str, *Streamer()->ToText()); + return cString::sprintf("%s%c%s", *str, Delimiter, *Streamer()->ToText()); else if (m_RecPlayer) - return cString::sprintf("%s\t%s", *str, m_RecPlayer->getCurrentRecording()->Name()); + return cString::sprintf("%s%c%s", *str, Delimiter, m_RecPlayer->getCurrentRecording()->Name()); else return str; } diff --git a/server/connectionVTP.h b/server/connectionVTP.h index b0b5de5..447c0b9 100644 --- a/server/connectionVTP.h +++ b/server/connectionVTP.h @@ -53,7 +53,7 @@ public: virtual void Welcome(void); virtual void Reject(void); - virtual cString ToText() const; + virtual cString ToText(char Delimiter = ' ') const; virtual bool Abort(void) const; virtual void Detach(void); diff --git a/server/menu.c b/server/menu.c index d51825e..d5f0c7e 100644 --- a/server/menu.c +++ b/server/menu.c @@ -15,7 +15,7 @@ cStreamdevServerMenu::cStreamdevServerMenu(): cOsdMenu(tr("Streamdev Connections cThreadLock lock; const cList& clients = cStreamdevServer::Clients(lock); for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) - Add(new cOsdItem(s->ToText())); + Add(new cOsdItem(s->ToText('\t'))); SetHelpKeys(); Display(); } @@ -34,7 +34,7 @@ eOSState cStreamdevServerMenu::Disconnect() { const cList& clients = cStreamdevServer::Clients(lock); const char *text = item->Text(); for (cServerConnection *s = clients.First(); s; s = clients.Next(s)) { - if (!strcmp(text, s->ToText())) { + if (!strcmp(text, s->ToText('\t'))) { s->Close(); Del(Current()); SetHelpKeys(); diff --git a/server/streamdev-server.c b/server/streamdev-server.c index f3e62df..e1475da 100644 --- a/server/streamdev-server.c +++ b/server/streamdev-server.c @@ -178,4 +178,69 @@ bool cPluginStreamdevServer::SetupParse(const char *Name, const char *Value) return StreamdevServerSetup.SetupParse(Name, Value); } +const char **cPluginStreamdevServer::SVDRPHelpPages(void) +{ + static const char *HelpPages[]= + { + "LSTC\n" + " List connected clients\n", + "DISC client_id\n" + " Disconnect a client\n", + NULL + }; + return HelpPages; +} + +cString cPluginStreamdevServer::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) +{ + + cString reply = NULL; + if (!strcasecmp(Command, "LSTC")) + { + reply = ""; + cThreadLock lock; + const cList& clients = cStreamdevServer::Clients(lock); + cServerConnection *s = clients.First(); + if (!s) + { + reply = "no client connected"; + ReplyCode = 550; + } else + { + for (; s; s = clients.Next(s)) + { + reply = cString::sprintf("%s%p: %s\n", (const char*) reply, s, (const char *) s->ToText()); + } + ReplyCode = 250; + } + } else if (!strcasecmp(Command, "DISC")) + { + void *client = NULL; + if (sscanf(Option, "%p", &client) != 1 || !client) + { + reply = "invalid client handle"; + ReplyCode = 501; + } else + { + cThreadLock lock; + const cList& clients = cStreamdevServer::Clients(lock); + cServerConnection *s = clients.First(); + for (; s && s != client; s = clients.Next(s)); + + if (!s) + { + reply = "client not found"; + ReplyCode = 501; + } else + { + s->Close(); + reply = "client disconnected"; + ReplyCode = 250; + } + } + } + + return reply; +} + VDRPLUGINCREATOR(cPluginStreamdevServer); // Don't touch this! diff --git a/server/streamdev-server.h b/server/streamdev-server.h index e149fd3..0d588fc 100644 --- a/server/streamdev-server.h +++ b/server/streamdev-server.h @@ -44,6 +44,8 @@ public: virtual void MainThreadHook(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); + virtual const char **SVDRPHelpPages(void); + virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode); }; #endif // VDR_STREAMDEVSERVER_H