From 54ac5eaaab8065473fb023c713e383b7fe5d15a9 Mon Sep 17 00:00:00 2001 From: Dieter Hametner Date: Sat, 21 Jun 2008 01:22:21 +0200 Subject: Changed the definition of tntversion in the LIVE source files. Now there is a define TNTVERSION set to a number that can be compared in C oreprocessor 'if' statements. This allows for adding support for tntnet specific features with evolving tntnet version. --- Makefile | 8 +- pages/page_exit.eh | 2 +- pages/recordings.ecpp | 2 +- setup.cpp | 12 +- setup.h | 9 +- thread.cpp | 25 ++-- tntconfig.cpp | 389 ++++++++++++++++++++++++++++++++++---------------- tntconfig.h | 49 ++++--- 8 files changed, 327 insertions(+), 169 deletions(-) diff --git a/Makefile b/Makefile index baa086a..1b932e0 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,8 @@ TMPDIR ?= /tmp APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h) I18NTARG = $(shell if [ `echo $(APIVERSION) | tr [.] [0]` -ge "10507" ]; then echo "i18n"; fi) -TNTVERS7 = $(shell ver=`tntnet-config --version | sed -e's/\.//g' | awk '/^..$$/ { print $$1."00"} /^...$$/ { print $$1."0"} /^....$$/ { print $$1 }'`; if [ $$ver -ge "1606" ]; then echo "yes"; fi) +TNTVERSION = $(shell tntnet-config --version | sed -e's/\.//g' | awk '/^..$$/ { print $$1."00"} /^...$$/ { print $$1."0"} /^....$$/ { print $$1 }') +TNTVERS7 = $(shell ver=$(TNTVERSION); if [ $$ver -ge "1606" ]; then echo "yes"; fi) ### The name of the distribution archive: @@ -58,10 +59,7 @@ ifneq ($(TNTVERS7),yes) LIBS += httpd/libhttpd.a endif -DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -ifeq ($(TNTVERS7),yes) - DEFINES += -DTNTVERS7 -endif +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -DTNTVERSION=$(TNTVERSION) export DEFINES SUBDIRS = pages css javascript diff --git a/pages/page_exit.eh b/pages/page_exit.eh index 5e26a32..5101171 100644 --- a/pages/page_exit.eh +++ b/pages/page_exit.eh @@ -5,7 +5,7 @@ <%cpp> spoint.commit(); } catch ( vdrlive::HtmlError const& ex ) { -#ifdef TNTVERS7 +#if TNTVERSION >= 1606 tnt::QueryParams param = qparam; #else cxxtools::QueryParams param = qparam; diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp index e1770a6..23299bb 100644 --- a/pages/recordings.ecpp +++ b/pages/recordings.ecpp @@ -116,7 +116,7 @@ for (iter = recordingsTree->begin(path); iter != end; ++iter) {
  • <& rec_item_dir name=(recItem->Name()) level=(level) &> <%cpp> -#ifdef TNTVERS7 +#if TNTVERSION >= 1606 tnt::QueryParams recItemParams(qparam, false); #else cxxtools::QueryParams recItemParams(qparam, false); diff --git a/setup.cpp b/setup.cpp index f431842..de5bf39 100644 --- a/setup.cpp +++ b/setup.cpp @@ -23,7 +23,7 @@ using namespace std; Setup::Setup(): m_serverPort( 8008 ), -#ifdef TNTVERS7 +#if TNTSSLSUPPORT m_serverSslPort( 8443 ), m_serverSslCert(), #endif @@ -53,7 +53,7 @@ bool Setup::ParseCommandLine( int argc, char* argv[] ) { "ip", required_argument, NULL, 'i' }, { "log", required_argument, NULL, 'l' }, { "epgimages", required_argument, NULL, 'e' }, -#ifdef TNTVERS7 +#if TNTSSLSUPPORT { "sslport", required_argument, NULL, 's' }, { "cert", required_argument, NULL, 'c' }, #endif @@ -67,7 +67,7 @@ bool Setup::ParseCommandLine( int argc, char* argv[] ) case 'i': m_serverIps.push_back( optarg ); break; case 'l': m_tntnetloglevel = optarg; break; case 'e': m_epgimagedir = optarg; break; -#ifdef TNTVERS7 +#if TNTSSLSUPPORT case 's': m_serverSslPort = atoi( optarg ); break; case 'c': m_serverSslCert = optarg; break; #endif @@ -76,7 +76,7 @@ bool Setup::ParseCommandLine( int argc, char* argv[] ) } return CheckServerPort() && -#ifdef TNTVERS7 +#if TNTSSLSUPPORT CheckServerSslPort() && #endif CheckServerIps(); @@ -91,7 +91,7 @@ char const* Setup::CommandLineHelp() const << " -i IP, --ip=IP bind server only to specified IP, may appear\n" " multiple times\n" " (default: 0.0.0.0)\n" -#ifdef TNTVERS7 +#if TNTSSLSUPPORT << " -s PORT, --sslport=PORT use PORT to listen for incoming ssl connections\n" " (default: " << m_serverSslPort << ")\n" << " -c CERT, --cert=CERT full path to a custom ssl certificate file\n" @@ -137,7 +137,7 @@ bool Setup::CheckServerPort() return true; } -#ifdef TNTVERS7 +#if TNTSSLSUPPORT bool Setup::CheckServerSslPort() { if ( m_serverSslPort <= 0 || m_serverSslPort > numeric_limits< uint16_t >::max() ) { diff --git a/setup.h b/setup.h index cc1d853..c341a5e 100644 --- a/setup.h +++ b/setup.h @@ -14,6 +14,9 @@ namespace vdrlive { +// SSL-Support works from tntnet version 1.6.1 onwards. +#define TNTSSLSUPPORT TNTVERSION >= 1610 + // forward declaration, see below class cMenuSetupLive; @@ -28,7 +31,7 @@ class Setup // commandline int GetServerPort() const { return m_serverPort; } -#ifdef TNTVERS7 +#if TNTSSLSUPPORT int GetServerSslPort() const { return m_serverSslPort; } std::string GetServerSslCert() const { return m_serverSslCert; } #endif @@ -98,7 +101,7 @@ class Setup mutable std::string m_helpString; // commandline options int m_serverPort; -#ifdef TNTVERS7 +#if TNTSSLSUPPORT int m_serverSslPort; std::string m_serverSslCert; static std::string m_configDirectory; @@ -130,7 +133,7 @@ class Setup bool CheckServerPort(); bool CheckServerIps(); -#ifdef TNTVERS7 +#if TNTSSLSUPPORT bool CheckServerSslPort(); #endif }; diff --git a/thread.cpp b/thread.cpp index 24c0e12..8bd0584 100644 --- a/thread.cpp +++ b/thread.cpp @@ -11,7 +11,7 @@ namespace vdrlive { using namespace std; using namespace tnt; -#ifndef TNTVERS7 +#if TNTVERSION < 1606 class ProtectedCString { public: @@ -23,7 +23,7 @@ public: private: char* m_string; }; -#endif // TNTVERS7 +#endif // TNTVERSION < 1606 ServerThread::ServerThread() { @@ -45,24 +45,25 @@ void ServerThread::Stop() void ServerThread::Action() { try { -#ifdef TNTVERS7 - tnt::Tntconfig tntconfig; - tntconfig.load(TntConfig::Get().GetConfigPath().c_str()); +#if TNTVERSION >= 1606 + // tnt::Tntconfig tntconfig; + // tntconfig.load(TntConfig::Get().GetConfigPath().c_str()); m_server.reset(new Tntnet()); - m_server->init(tntconfig); + //m_server->init(tntconfig); + TntConfig::Get().Configure(*m_server); #else - ProtectedCString configPath( TntConfig::Get().GetConfigPath().c_str() ); + ProtectedCString configPath(TntConfig::Get().GetConfigPath().c_str()); char* argv[] = { const_cast< char* >( "tntnet" ), const_cast< char* >( "-c" ), configPath }; int argc = sizeof( argv ) / sizeof( argv[0] ); - m_server.reset( new Tntnet( argc, argv ) ); -#endif // TNTVERS7 + m_server.reset(new Tntnet( argc, argv )); +#endif // TNTVERSION m_server->run(); - m_server.reset( 0 ); - } catch ( exception const& ex ) { + m_server.reset(0); + } catch (exception const& ex) { // XXX move initial error handling to live.cpp - esyslog( "ERROR: live httpd server crashed: %s", ex.what() ); + esyslog("ERROR: live httpd server crashed: %s", ex.what()); cerr << "HTTPD FATAL ERROR: " << ex.what() << endl; //cThread::EmergencyExit(true); } diff --git a/tntconfig.cpp b/tntconfig.cpp index cdc476e..71bee4d 100644 --- a/tntconfig.cpp +++ b/tntconfig.cpp @@ -3,8 +3,12 @@ #include #include #include +#include +#include +#include #include #include +#include #include "i18n.h" #include "live.h" #include "setup.h" @@ -12,157 +16,294 @@ namespace vdrlive { -using namespace std; + using namespace std; -TntConfig::TntConfig() -{ - WriteConfig(); -} - -void TntConfig::WriteConfig() -{ - WriteProperties(); + TntConfig::TntConfig() + { +#if TNTVERSION < 1606 + WriteConfig(); +#endif + } - string const configDir(Plugin::GetConfigDirectory()); +#if TNTVERSION < 1606 + void TntConfig::WriteConfig() + { + WriteProperties(); - ostringstream builder; - builder << configDir << "/httpd.config"; - m_configPath = builder.str(); + string const configDir(Plugin::GetConfigDirectory()); - ofstream file( m_configPath.c_str(), ios::out | ios::trunc ); - if ( !file ) { ostringstream builder; - builder << "Can't open " << m_configPath << " for writing: " << strerror( errno ); - throw runtime_error( builder.str() ); - } + builder << configDir << "/httpd.config"; + m_configPath = builder.str(); + + ofstream file( m_configPath.c_str(), ios::out | ios::trunc ); + if ( !file ) { + ostringstream builder; + builder << "Can't open " << m_configPath << " for writing: " << strerror( errno ); + throw runtime_error( builder.str() ); + } + + // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ + // ------------------------------------------------------------------------ + // These MapUrl statements are very security sensitive! + // A wrong mapping to content@ may allow retrieval of arbitrary files + // from your VDR system via live. + // Two meassures are taken against this in our implementation: + // 1. The MapUrls need to be checked regulary against possible exploits + // One tool to do this can be found here: + // http://www.lumadis.be/regex/test_regex.php + // Newly inserted MapUrls should be marked with author and confirmed + // by a second party. (use source code comments for this) + // 2. content.ecpp checks the given path to be + // a. an absolute path starting at / + // b. not containing ../ paths components + // In order to do so, the MapUrl statements must create absolute + // path arguments to content@ + // ------------------------------------------------------------------------ + // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ + - // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ - // ------------------------------------------------------------------------ - // These MapUrl statements are very security sensitive! - // A wrong mapping to content@ may allow retrieval of arbitrary files - // from your VDR system via live. - // Two meassures are taken against this in our implementation: - // 1. The MapUrls need to be checked regulary against possible exploits - // One tool to do this can be found here: - // http://www.lumadis.be/regex/test_regex.php - // Newly inserted MapUrls should be marked with author and confirmed - // by a second party. (use source code comments for this) - // 2. content.ecpp checks the given path to be - // a. an absolute path starting at / - // b. not containing ../ paths components - // In order to do so, the MapUrl statements must create absolute - // path arguments to content@ - // ------------------------------------------------------------------------ - // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ - - - file << "MapUrl ^/$ login@" << endl; - - // the following redirects vdr_request URL to the component - // specified by the action parameter. - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/vdr_request/([^.]+) $1@" << endl; - - // the following selects the theme specific 'theme.css' file - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/themes/([^/]*)/css.*/(.+\\.css) content@ " << configDir << "/themes/$1/css/$2 text/css" << endl; - - // the following rules provide a search scheme for images. The first - // rule where a image is found, terminates the search. - // 1. /themes//img/. - // 2. /img/. - // deprecated: 3. . (builtin images) - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) content@ " << configDir << "/themes/$1/img/$2.$3 image/$3" << endl; - file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) content@ " << configDir << "/img/$2.$3 image/$3" << endl; - // deprecated: file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) $2@" << endl; - - // Epg images - string const epgImgPath(LiveSetup().GetEpgImageDir()); - if (!epgImgPath.empty()) { - // inserted by 'winni' -- EXPLOITABLE! (checked by tadi) - // file << "MapUrl ^/epgimages/(.*)\\.(.+) content@ " << epgImgPath << "/$1.$2 image/$2" << endl; + file << "MapUrl ^/$ login@" << endl; + // the following redirects vdr_request URL to the component + // specified by the action parameter. // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/epgimages/([^/]*)\\.([^./]+) content@ " << epgImgPath << "/$1.$2 image/$2" << endl; - } + file << "MapUrl ^/vdr_request/([^.]+) $1@" << endl; - // select additional (not build in) javascript. - // WARNING: no path components with '.' in the name are allowed. Only - // the basename may contain dots and must end with '.js' - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/js(/[^.]*)([^/]*\\.js) content@ " << configDir << "/js$1$2 text/javascript" << endl; + // the following selects the theme specific 'theme.css' file + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/themes/([^/]*)/css.*/(.+\\.css) content@ " << configDir << "/themes/$1/css/$2 text/css" << endl; - // map to 'css/basename(uri)' - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/css.*/(.+) content@ " << configDir << "/css/$1 text/css" << endl; + // the following rules provide a search scheme for images. The first + // rule where a image is found, terminates the search. + // 1. /themes//img/. + // 2. /img/. + // deprecated: 3. . (builtin images) + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) content@ " << configDir << "/themes/$1/img/$2.$3 image/$3" << endl; + file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) content@ " << configDir << "/img/$2.$3 image/$3" << endl; + // deprecated: file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) $2@" << endl; - // map to 'img/basename(uri)' - // inserted by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/img.*/(.+)\\.([^.]+) content@ " << configDir << "/img/$1.$2 image/$2" << endl; + // Epg images + string const epgImgPath(LiveSetup().GetEpgImageDir()); + if (!epgImgPath.empty()) { + // inserted by 'winni' -- EXPLOITABLE! (checked by tadi) + // file << "MapUrl ^/epgimages/(.*)\\.(.+) content@ " << epgImgPath << "/$1.$2 image/$2" << endl; - // Map favicon.ico into img directory - file << "MapUrl ^/favicon.ico$ content@ " << configDir << "/img/favicon.ico image/x-icon" << endl; + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/epgimages/([^/]*)\\.([^./]+) content@ " << epgImgPath << "/$1.$2 image/$2" << endl; + } - // insecure by default: DO NOT UNKOMMENT!!! - // file << "MapUrl /([^/]+/.+) content@ $1" << endl; + // select additional (not build in) javascript. + // WARNING: no path components with '.' in the name are allowed. Only + // the basename may contain dots and must end with '.js' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/js(/[^.]*)([^/]*\\.js) content@ " << configDir << "/js$1$2 text/javascript" << endl; - // takes first path components without 'extension' when it does not - // contain '.' - // modified by 'tadi' -- verified with above, but not counterchecked yet! - file << "MapUrl ^/([^./]+)(.*)? $1@" << endl; + // map to 'css/basename(uri)' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/css.*/(.+) content@ " << configDir << "/css/$1 text/css" << endl; - file << "PropertyFile " << m_propertiesPath << endl; - file << "SessionTimeout 86400" << endl; - file << "DefaultContentType \"text/html; charset=" << LiveI18n().CharacterEncoding() << "\"" << endl; + // map to 'img/basename(uri)' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/img.*/(.+)\\.([^.]+) content@ " << configDir << "/img/$1.$2 image/$2" << endl; - Setup::IpList const& ips = LiveSetup().GetServerIps(); - int port = LiveSetup().GetServerPort(); - for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { - file << "Listen " << *ip << " " << port << endl; - } + // Map favicon.ico into img directory + file << "MapUrl ^/favicon.ico$ content@ " << configDir << "/img/favicon.ico image/x-icon" << endl; -#ifdef TNTVERS7 - int s_port = LiveSetup().GetServerSslPort(); - string s_cert = LiveSetup().GetServerSslCert(); + // insecure by default: DO NOT UNKOMMENT!!! + // file << "MapUrl /([^/]+/.+) content@ $1" << endl; - if (s_cert.empty()) { - s_cert = configDir + "/live.pem"; - } + // takes first path components without 'extension' when it does not + // contain '.' + // modified by 'tadi' -- verified with above, but not counterchecked yet! + file << "MapUrl ^/([^./]+)(.*)? $1@" << endl; - if ( ifstream( s_cert.c_str() ) ) { + file << "PropertyFile " << m_propertiesPath << endl; + file << "SessionTimeout 86400" << endl; + file << "DefaultContentType \"text/html; charset=" << LiveI18n().CharacterEncoding() << "\"" << endl; + + Setup::IpList const& ips = LiveSetup().GetServerIps(); + int port = LiveSetup().GetServerPort(); for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { - file << "SslListen " << *ip << " " << s_port << " " << s_cert << endl; + file << "Listen " << *ip << " " << port << endl; } - } - else { - esyslog( "ERROR: %s: %s", s_cert.c_str(), strerror( errno ) ); + +// not used any more see below: #ifdef TNTVERS7 +// not used any more see below: int s_port = LiveSetup().GetServerSslPort(); +// not used any more see below: string s_cert = LiveSetup().GetServerSslCert(); +// not used any more see below: +// not used any more see below: if (s_cert.empty()) { +// not used any more see below: s_cert = configDir + "/live.pem"; +// not used any more see below: } +// not used any more see below: +// not used any more see below: if ( ifstream( s_cert.c_str() ) ) { +// not used any more see below: for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { +// not used any more see below: file << "SslListen " << *ip << " " << s_port << " " << s_cert << endl; +// not used any more see below: } +// not used any more see below: } +// not used any more see below: else { +// not used any more see below: esyslog( "ERROR: %s: %s", s_cert.c_str(), strerror( errno ) ); +// not used any more see below: } +// not used any more see below: #endif } #endif -} - -void TntConfig::WriteProperties() -{ - ostringstream builder; - builder << Plugin::GetConfigDirectory() << "/httpd.properties"; - m_propertiesPath = builder.str(); - ofstream file( m_propertiesPath.c_str(), ios::out | ios::trunc ); - if ( !file ) { +#if TNTVERSION < 1606 + void TntConfig::WriteProperties() + { ostringstream builder; - builder << "Can't open " << m_propertiesPath << " for writing: " << strerror( errno ); - throw runtime_error( builder.str() ); + builder << Plugin::GetConfigDirectory() << "/httpd.properties"; + m_propertiesPath = builder.str(); + + ofstream file( m_propertiesPath.c_str(), ios::out | ios::trunc ); + if ( !file ) { + ostringstream builder; + builder << "Can't open " << m_propertiesPath << " for writing: " << strerror( errno ); + throw runtime_error( builder.str() ); + } + + // XXX modularize + file << "rootLogger=" << LiveSetup().GetTntnetLogLevel() << endl; + file << "logger.tntnet=" << LiveSetup().GetTntnetLogLevel() << endl; } +#endif + +#if TNTVERSION >= 1606 + void TntConfig::Configure(tnt::Tntnet& app) const + { + string const configDir(Plugin::GetConfigDirectory()); - // XXX modularize - file << "rootLogger=" << LiveSetup().GetTntnetLogLevel() << endl; - file << "logger.tntnet=" << LiveSetup().GetTntnetLogLevel() << endl; -} + // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ + // ------------------------------------------------------------------------ + // These mapUrl statements are very security sensitive! + // A wrong mapping to content may allow retrieval of arbitrary files + // from your VDR system via live. + // Two meassures are taken against this in our implementation: + // 1. The MapUrls need to be checked regulary against possible exploits + // One tool to do this can be found here: + // http://www.lumadis.be/regex/test_regex.php + // Newly inserted MapUrls should be marked with author and confirmed + // by a second party. (use source code comments for this) + // 2. content.ecpp checks the given path to be + // a. an absolute path starting at / + // b. not containing ../ paths components + // In order to do so, the MapUrl statements must create absolute + // path arguments to content@ + // ------------------------------------------------------------------------ + // +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ CAUTION +++ + + app.mapUrl("^/$", "login"); + + // the following redirects vdr_request URL to the component + // specified by the action parameter. + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/vdr_request/([^.]+)", "$1"); -TntConfig const& TntConfig::Get() -{ - static TntConfig instance; - return instance; -} + // the following redirects play_video URL to the content component. + // inserted by 'tadi' -- not verified, not counterchecked yet! + //app.mapUrl("^/vlc/(.+)", "static@tntnet") + // .setPathInfo("/$1") + // .pushArg(string("DocumentRoot=") + VideoDirectory); + // the following selects the theme specific 'theme.css' file + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/themes/([^/]*)/css.*/(.+\\.css)", "content") + .setPathInfo(configDir + "/themes/$1/css/$2") + .pushArg("text/css"); + + // the following rules provide a search scheme for images. The first + // rule where a image is found, terminates the search. + // 1. /themes//img/. + // 2. /img/. + // deprecated: 3. . (builtin images) + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/themes/([^/]*)/img.*/(.+)\\.(.+)", "content") + .setPathInfo(configDir + "/themes/$1/img/$2.$3") + .pushArg("image/$3"); + app.mapUrl("^/themes/([^/]*)/img.*/(.+)\\.(.+)", "content") + .setPathInfo(configDir + "/img/$2.$3") + .pushArg("image/$3"); + // deprecated: file << "MapUrl ^/themes/([^/]*)/img.*/(.+)\\.(.+) $2@" << endl; + + // Epg images + string const epgImgPath(LiveSetup().GetEpgImageDir()); + if (!epgImgPath.empty()) { + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/epgimages/([^/]*)\\.([^./]+)", "content") + .setPathInfo(epgImgPath + "/$1.$2") + .pushArg("image/$2"); + } + + // select additional (not build in) javascript. + // WARNING: no path components with '.' in the name are allowed. Only + // the basename may contain dots and must end with '.js' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/js(/[^.]*)([^/]*\\.js)", "content") + .setPathInfo(configDir + "/js$1$2") + .pushArg("text/javascript"); + + // map to 'css/basename(uri)' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/css.*/(.+)", "content") + .setPathInfo(configDir + "/css/$1") + .pushArg("text/css"); + + // map to 'img/basename(uri)' + // inserted by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/img.*/(.+)\\.([^.]+)", "content") + .setPathInfo(configDir + "/img/$1.$2") + .pushArg("image/$2"); + + // Map favicon.ico into img directory + app.mapUrl("^/favicon.ico$", "content") + .setPathInfo(configDir + "/img/favicon.ico") + .pushArg("image/x-icon"); + + // takes first path components without 'extension' when it does not + // contain '.' + // modified by 'tadi' -- verified with above, but not counterchecked yet! + app.mapUrl("^/([^./]+)(.*)?", "$1"); + + tnt::Sessionscope::setDefaultTimeout(86400); + tnt::HttpReply::setDefaultContentType(string("text/html; charset=") + LiveI18n().CharacterEncoding()); + + Setup::IpList const& ips = LiveSetup().GetServerIps(); + int port = LiveSetup().GetServerPort(); + for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { + app.listen(*ip, port); + } + +#if TNTSSLSUPPORT + int s_port = LiveSetup().GetServerSslPort(); + string s_cert = LiveSetup().GetServerSslCert(); + + if (s_cert.empty()) { + s_cert = configDir + "/live.pem"; + } + + if ( ifstream( s_cert.c_str() ) ) { + for ( Setup::IpList::const_iterator ip = ips.begin(); ip != ips.end(); ++ip ) { + app.sslListen(s_cert, s_cert, *ip, s_port); + } + } + else { + esyslog( "ERROR: %s: %s", s_cert.c_str(), strerror( errno ) ); + } +#endif // TNTSSLSUPPORT + + std::istringstream logConf( + "rootLogger=" + LiveSetup().GetTntnetLogLevel() + "\n" + // "logger.tntnet.static=DEBUG\n" + // "logger.cxxtools.net.tcp=DEBUG\n" + ); + log_init(logConf); + } +#endif + + TntConfig const& TntConfig::Get() + { + static TntConfig instance; + return instance; + } } // namespace vdrlive diff --git a/tntconfig.h b/tntconfig.h index ba31f97..9c30e44 100644 --- a/tntconfig.h +++ b/tntconfig.h @@ -2,26 +2,41 @@ #define VDR_LIVE_TNTCONFIG_H #include +#include namespace vdrlive { -class TntConfig -{ -public: - static TntConfig const& Get(); - - std::string const& GetConfigPath() const { return m_configPath; } - -private: - std::string m_propertiesPath; - std::string m_configPath; - - TntConfig(); - TntConfig( TntConfig const& ); - - void WriteProperties(); - void WriteConfig(); -}; +#if TNTVERSION >= 1606 + class TntConfig + { + public: + static TntConfig const& Get(); + + void Configure(tnt::Tntnet& app) const; + + private: + TntConfig(); + TntConfig( TntConfig const& ); + }; +#else + class TntConfig + { + public: + static TntConfig const& Get(); + + std::string const& GetConfigPath() const { return m_configPath; } + + private: + std::string m_propertiesPath; + std::string m_configPath; + + TntConfig(); + TntConfig( TntConfig const& ); + + void WriteProperties(); + void WriteConfig(); + }; +#endif } // namespace vdrlive -- cgit v1.2.3