diff options
-rw-r--r-- | vdr-vdrmanager/HISTORY | 8 | ||||
-rw-r--r-- | vdr-vdrmanager/Makefile | 2 | ||||
-rw-r--r-- | vdr-vdrmanager/handler.cpp | 16 | ||||
-rw-r--r-- | vdr-vdrmanager/helpers.cpp | 84 | ||||
-rw-r--r-- | vdr-vdrmanager/helpers.h | 2 | ||||
-rw-r--r-- | vdr-vdrmanager/select.cpp | 26 | ||||
-rw-r--r-- | vdr-vdrmanager/sock.cpp | 2 | ||||
-rw-r--r-- | vdr-vdrmanager/sock.h | 15 | ||||
-rw-r--r-- | vdr-vdrmanager/vdrmanager.cpp | 34 | ||||
-rw-r--r-- | vdr-vdrmanager/vdrmanagerthread.cpp | 5 | ||||
-rw-r--r-- | vdr-vdrmanager/vdrmanagerthread.h | 3 |
11 files changed, 118 insertions, 79 deletions
diff --git a/vdr-vdrmanager/HISTORY b/vdr-vdrmanager/HISTORY index e62cb01..34ed4d1 100644 --- a/vdr-vdrmanager/HISTORY +++ b/vdr-vdrmanager/HISTORY @@ -1,11 +1,5 @@ VDR Plugin 'vdrmanager' Revision History ------------------------------------ - -2013-04-xx: Version 0.10 (http://projects.vdr-developer.org/versions/show/328) -- Bug #1314: -f has not function, remove it. Deleting timers is always beeing forced -- Feature #790: use some compression (zlib, gzip) to compress responses server sides -- Feature #1319: Recording Folders - 2013-01-xx: Version 0.9 (http://projects.vdr-developer.org/versions/show/312) - Improved Timer/Recording deletion - Improved recording information (recordings command) @@ -45,7 +39,7 @@ VDR Plugin 'vdrmanager' Revision History 2011-11-06: Version 0.3 - Check against svdrphosts.conf file only if a) forced via command line argument -s or no password was specified via -P -- arguments parsing by getopts +- arguments parsing by getopts 2011-10-12: Version 0.2 - Recording Info via recordings command diff --git a/vdr-vdrmanager/Makefile b/vdr-vdrmanager/Makefile index c43fa6a..4fae6b6 100644 --- a/vdr-vdrmanager/Makefile +++ b/vdr-vdrmanager/Makefile @@ -47,7 +47,7 @@ SOFILE = libvdr-$(PLUGIN).so ### The object files (add further files here): -OBJS = $(PLUGIN).o sock.o vdrmanagerthread.o select.o handler.o helpers.o compressor.o +OBJS = $(PLUGIN).o sock.o vdrmanagerthread.o select.o handler.o helpers.o ### The main target: diff --git a/vdr-vdrmanager/handler.cpp b/vdr-vdrmanager/handler.cpp index ea15296..43b500a 100644 --- a/vdr-vdrmanager/handler.cpp +++ b/vdr-vdrmanager/handler.cpp @@ -17,8 +17,6 @@ bool cHandler::HandleNewClient(cVdrmanagerClientSocket * sock) bool cHandler::HandleClientRequest(cVdrmanagerClientSocket * sock) { - bool closeSocket = true; - while(sock->Read()) { // get lines @@ -50,12 +48,6 @@ bool cHandler::HandleClientRequest(cVdrmanagerClientSocket * sock) sock->SetLoggedIn(); sock->PutLine("!OK\r\n"); } - closeSocket = false; - } - else if (cmd == "COMPRESS") - { - sock->ActivateCompression(); - closeSocket = false; } else if (cmd == "TIMERS") { @@ -105,15 +97,9 @@ bool cHandler::HandleClientRequest(cVdrmanagerClientSocket * sock) else if (cmd == "QUIT") { // close socket - sock->PutLine(string("Good bye! :-)\r\n")); + sock->PutLine(string("Good bye! :-)\n")); sock->Disconnect(); } - - if (closeSocket) { - sock->Disconnect(); - } - - sock->Flush(); } } diff --git a/vdr-vdrmanager/helpers.cpp b/vdr-vdrmanager/helpers.cpp index 7dcef54..80721f3 100644 --- a/vdr-vdrmanager/helpers.cpp +++ b/vdr-vdrmanager/helpers.cpp @@ -709,10 +709,6 @@ string cHelpers::ToText(cRecording * recording) { } } - result += ":"; - //Feature #1319 - result += recording->Name(); - result += "\r\n"; return result; } @@ -1070,6 +1066,86 @@ int cHelpers::RecordingLengthInSeconds(cRecording* recording) { return Duration(recording) * 60; } +/** Compress a STL string using zlib with given compression level and return + * the binary data. */ +string cHelpers::compress_string(const string& str, int compressionlevel) { + z_stream zs; // z_stream is zlib's control structure + memset(&zs, 0, sizeof(zs)); + + if (deflateInit(&zs, compressionlevel) != Z_OK) + throw(runtime_error("deflateInit failed while compressing.")); + + zs.next_in = (Bytef*) str.data(); + zs.avail_in = str.size(); // set the z_stream's input + + int ret; + char outbuffer[32768]; + string outstring; + +// retrieve the compressed bytes blockwise + do { + zs.next_out = reinterpret_cast<Bytef*>(outbuffer); + zs.avail_out = sizeof(outbuffer); + + ret = deflate(&zs, Z_FINISH); + + if (outstring.size() < zs.total_out) { + // append the block to the output string + outstring.append(outbuffer, zs.total_out - outstring.size()); + } + } while (ret == Z_OK); + + deflateEnd(&zs); + + if (ret != Z_STREAM_END) { // an error occurred that was not EOF + ostringstream oss; + oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; + throw(runtime_error(oss.str())); + } + + return outstring; +} + +/** Decompress an STL string using zlib and return the original data. */ +string cHelpers::decompress_string(const string& str) { + z_stream zs; // z_stream is zlib's control structure + memset(&zs, 0, sizeof(zs)); + + if (inflateInit(&zs) != Z_OK) + throw(runtime_error("inflateInit failed while decompressing.")); + + zs.next_in = (Bytef*) str.data(); + zs.avail_in = str.size(); + + int ret; + char outbuffer[32768]; + string outstring; + +// get the decompressed bytes blockwise using repeated calls to inflate + do { + zs.next_out = reinterpret_cast<Bytef*>(outbuffer); + zs.avail_out = sizeof(outbuffer); + + ret = inflate(&zs, 0); + + if (outstring.size() < zs.total_out) { + outstring.append(outbuffer, zs.total_out - outstring.size()); + } + + } while (ret == Z_OK); + + inflateEnd(&zs); + + if (ret != Z_STREAM_END) { // an error occurred that was not EOF + ostringstream oss; + oss << "Exception during zlib decompression: (" << ret << ") " + << zs.msg; + throw(runtime_error(oss.str())); + } + + return outstring; +} + //These three methodes were stolen from vdr-restfulapi project. Thanks! std::queue<int> cHelpers::ConvertToBinary(int v) { int b; diff --git a/vdr-vdrmanager/helpers.h b/vdr-vdrmanager/helpers.h index 18576be..b9ebee5 100644 --- a/vdr-vdrmanager/helpers.h +++ b/vdr-vdrmanager/helpers.h @@ -31,6 +31,8 @@ public: static string ToUpper(string text); static string ToLower(string text); static string Trim(string text); + static string decompress_string(const string& str); + static string compress_string(const string& str, int compressionlevel = Z_BEST_COMPRESSION); static long Duration(cRecording* recording); private: static string SafeCall(string (*)()); diff --git a/vdr-vdrmanager/select.cpp b/vdr-vdrmanager/select.cpp index 06d9103..c569f42 100644 --- a/vdr-vdrmanager/select.cpp +++ b/vdr-vdrmanager/select.cpp @@ -108,9 +108,8 @@ bool cSelect::Action() { } void cSelect::CreatePollfds() { - // construct pollfd array - // we need one pollfd for the eventpipe, - // the serversocket and each clientsocket + + // we poll for the server socket and for each client socket pollfds = new struct pollfd[clientsocketcount + 1]; pollfds[0].fd = serversocket->GetSocket(); pollfds[0].events = POLLIN; @@ -119,9 +118,10 @@ void cSelect::CreatePollfds() { int i = 1; while (curnode) { pollfds[i].fd = curnode->socket->GetSocket(); - pollfds[i].events = POLLIN; - if (curnode->socket->WritePending()) + pollfds[i].events = POLLIN | POLLHUP; + if (curnode->socket->WritePending()) { pollfds[i].events |= POLLOUT; + } pollfds[i++].revents = 0; curnode = curnode->next; } @@ -149,17 +149,17 @@ bool cSelect::Poll() { for (int i = 1; i < clientsocketcount + 1; i++) { cVdrmanagerClientSocket * sock = GetClientSocket(pollfds[i].fd); if (sock) { - if (pollfds[i].revents & (POLLIN | POLLHUP)) { + if (pollfds[i].revents & POLLOUT) { + // possibly outstanding writes + sock->Flush(); + } else if (pollfds[i].revents & (POLLIN | POLLHUP)) { // client request handler->HandleClientRequest(sock); + } - // disconnect? - if (sock->Disconnected()) { - RemoveClientSocket(sock); - } - } else if (pollfds[i].revents & POLLOUT) { - // possibly outstanding writes - sock->Flush(); + // disconnect? + if (sock->Disconnected()) { + RemoveClientSocket(sock); } } } diff --git a/vdr-vdrmanager/sock.cpp b/vdr-vdrmanager/sock.cpp index 2102c36..a860b53 100644 --- a/vdr-vdrmanager/sock.cpp +++ b/vdr-vdrmanager/sock.cpp @@ -303,7 +303,7 @@ int cVdrmanagerClientSocket::GetClientId() { } bool cVdrmanagerClientSocket::WritePending() { - return sendoffset < sendsize; + return sendsize > 0; } bool cVdrmanagerClientSocket::IsLoggedIn() { diff --git a/vdr-vdrmanager/sock.h b/vdr-vdrmanager/sock.h index 25a7b83..0234afc 100644 --- a/vdr-vdrmanager/sock.h +++ b/vdr-vdrmanager/sock.h @@ -5,7 +5,6 @@ #ifndef _VDRMON_SOCK #define _VDRMON_SOCK -#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <string> @@ -18,7 +17,6 @@ protected: int sock; const char * password; bool forceCheckSvdrp; - int compressionMode; protected: cVdrmanagerSocket(); bool IsPasswordSet(); @@ -35,18 +33,11 @@ class cVdrmanagerClientSocket : public cVdrmanagerSocket private: string readbuf; string writebuf; - char * sendbuf; - size_t sendsize; - size_t sendoffset; bool disconnected; - bool initDisconnect; int client; bool login; - bool compression; - bool initCompression; - int compressionMode; public: - cVdrmanagerClientSocket(const char * password, int compressionMode); + cVdrmanagerClientSocket(const char * password); virtual ~cVdrmanagerClientSocket(); bool Attach(int fd); bool IsLineComplete(); @@ -60,8 +51,6 @@ public: bool WritePending(); bool IsLoggedIn(); void SetLoggedIn(); - void ActivateCompression(); - void Compress(); }; class cVdrmanagerServerSocket : public cVdrmanagerSocket @@ -69,7 +58,7 @@ class cVdrmanagerServerSocket : public cVdrmanagerSocket public: cVdrmanagerServerSocket(); virtual ~cVdrmanagerServerSocket(); - bool Create(int port, const char * password, bool forceCheckSvdrp, int compressionMode); + bool Create(int port, const char * password, bool forceCheckSvdrp); cVdrmanagerClientSocket * Accept(); }; diff --git a/vdr-vdrmanager/vdrmanager.cpp b/vdr-vdrmanager/vdrmanager.cpp index 6542c89..2b81464 100644 --- a/vdr-vdrmanager/vdrmanager.cpp +++ b/vdr-vdrmanager/vdrmanager.cpp @@ -12,11 +12,10 @@ #include <vdr/device.h> #include <vdr/player.h> #include "vdrmanagerthread.h" -#include "compressor.h" #define VDRMANAGER_PORT 6420 -static const char *VERSION = "0.10"; +static const char *VERSION = "0.9"; static const char *DESCRIPTION = "VDR-Manager support plugin"; class cVdrManager: public cPlugin { @@ -26,7 +25,7 @@ private: int port; const char * password; bool forceCheckSvdrp; - int compressionMode; + bool forceDelete; protected: public: cVdrManager(void); @@ -58,6 +57,7 @@ cVdrManager::cVdrManager(void) { port = VDRMANAGER_PORT; password = ""; forceCheckSvdrp = false; + forceDelete = false; } cVdrManager::~cVdrManager() { @@ -73,15 +73,12 @@ cMenuSetupPage * cVdrManager::SetupMenu(void) { } const char * cVdrManager::CommandLineHelp(void) { - return " -p port port number to listen to\n" - " -P password password (none if not given). No password forces check against svdrphosts.conf.\n" - " -s force check against svdrphosts.conf, even if a password was given\n" - " -c compression selects the compression mode to use (zlib or gzip). Default is zlib"; + return " -p port port number to listen to\n -P password password (none if not given). No password forces check against svdrphosts.conf.\n -s force check against svdrphosts.conf, even if a password was given\n -f force delete of a timer or a recording even if they are active\n"; } bool cVdrManager::ProcessArgs(int argc, char *argv[]) { int c; - while ((c = getopt(argc, argv, "c::p:P:s")) != -1) + while ((c = getopt(argc, argv, "p:P:s:f")) != -1) switch (c) { case 'p': port = atoi(optarg); @@ -92,18 +89,16 @@ bool cVdrManager::ProcessArgs(int argc, char *argv[]) { case 's': forceCheckSvdrp = true; break; - case 'c': - if (!optarg) { - compressionMode = COMPRESSION_ZLIB; - } else if (optarg[0] == 'g') { - compressionMode = COMPRESSION_GZIP; - } else if (optarg[0] == 'z') { - compressionMode = COMPRESSION_ZLIB; - } else { - return false; - } + case 'f': + forceDelete = true; break; case '?': + if (optopt == 'c') { + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + } else if (isprint(optopt)) + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); return false; default: return false; @@ -120,8 +115,7 @@ bool cVdrManager::Initialize(void) { // Initialize any background activities the plugin shall perform. // Start any background activities the plugin shall perform. - Thread = new cVdrManagerThread(port, password, forceCheckSvdrp, - compressionMode); + Thread = new cVdrManagerThread(port, password, forceCheckSvdrp); return Thread != NULL; } diff --git a/vdr-vdrmanager/vdrmanagerthread.cpp b/vdr-vdrmanager/vdrmanagerthread.cpp index 51301e5..2a4ca64 100644 --- a/vdr-vdrmanager/vdrmanagerthread.cpp +++ b/vdr-vdrmanager/vdrmanagerthread.cpp @@ -8,13 +8,12 @@ #include "select.h" #include "helpers.h" -cVdrManagerThread::cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp, int compressionMode) +cVdrManagerThread::cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp) { select = NULL; this -> port = port; this -> password = password; this -> forceCheckSvdrp = forceCheckSvdrp; - this -> compressionMode = compressionMode; } cVdrManagerThread::~cVdrManagerThread() @@ -44,7 +43,7 @@ bool cVdrManagerThread::Init() // create server socket cVdrmanagerServerSocket * sock = new cVdrmanagerServerSocket(); - if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp, compressionMode)) + if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp)) return false; // register server socket diff --git a/vdr-vdrmanager/vdrmanagerthread.h b/vdr-vdrmanager/vdrmanagerthread.h index 0dd3646..83f5f31 100644 --- a/vdr-vdrmanager/vdrmanagerthread.h +++ b/vdr-vdrmanager/vdrmanagerthread.h @@ -22,9 +22,8 @@ private: int port; const char * password; bool forceCheckSvdrp; - int compressionMode; public: - cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp, int compressionMode); + cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp); virtual void Action(void); void Shutdown(); private: |