[vdr-plugin-vdrmanager] 01/03: Imported Upstream version 0.12
Tobias Grimm
tiber-guest at moszumanska.debian.org
Mon Feb 9 22:52:12 UTC 2015
This is an automated email from the git hooks/post-receive script.
tiber-guest pushed a commit to branch master
in repository vdr-plugin-vdrmanager.
commit affe4eab8eebc48f1019f660a600e7ef32215001
Author: etobi <git at e-tobi.net>
Date: Mon Feb 9 23:49:40 2015 +0100
Imported Upstream version 0.12
---
.cproject | 90 +++++
.dependencies | 8 -
.gitignore | 10 +
.project | 84 +++++
.settings/de.loskutov.anyedit.AnyEditTools.prefs | 16 +
.settings/language.settings.xml | 11 +
.settings/org.eclipse.cdt.codan.core.prefs | 67 ++++
.settings/org.eclipse.ltk.core.refactoring.prefs | 2 +
HISTORY | 21 +-
Makefile | 23 +-
Makefile.pre.1.7.36 | 82 +++++
README | 6 +-
clientsock.cpp | 429 +++++++++++++++++++++++
clientsock.h | 74 ++++
compressor.cpp | 186 ++++++++++
compressor.h | 41 +++
examples/plugin.vdrmanager.conf | 10 +-
examples/vdr.vdrmanager | 11 +-
handler.cpp | 165 ++++-----
helpers.cpp | 268 ++++++++------
helpers.h | 9 +-
select.cpp | 117 +++++--
select.h | 8 +-
serversock.cpp | 157 +++++++++
serversock.h | 36 ++
sock.cpp | 221 +-----------
sock.h | 42 +--
vdrmanager.cpp | 116 +++++-
vdrmanagerthread.cpp | 53 ++-
vdrmanagerthread.h | 16 +-
30 files changed, 1846 insertions(+), 533 deletions(-)
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..27812e3
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.189548183">
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.189548183" moduleId="org.eclipse.cdt.core.settings" name="Default">
+ <externalSettings/>
+ <extensions>
+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+ <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <configuration artifactName="vdr-vdrmanager" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.189548183" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
+ <folderInfo id="cdt.managedbuild.toolchain.gnu.base.189548183.1555344799" name="/" resourcePath="">
+ <toolChain id="cdt.managedbuild.toolchain.gnu.base.107645851" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.229496351" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+ <builder id="cdt.managedbuild.target.gnu.builder.base.325094895" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.archiver.base.782170606" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1881829081" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+ <option id="gnu.cpp.compiler.option.include.paths.1164198959" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value="/usr/lib64/oracle/11.2.0.2/client/include"/>
+ <listOptionValue builtIn="false" value="/usr/include/vdr"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include-fixed"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/x86_64-pc-linux-gnu"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/backward"/>
+ </option>
+ <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.938487798" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+ </tool>
+ <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.2050235224" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+ <option id="gnu.c.compiler.option.include.paths.1088145882" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include-fixed"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/x86_64-pc-linux-gnu"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/backward"/>
+ </option>
+ <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2005963507" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+ </tool>
+ <tool id="cdt.managedbuild.tool.gnu.c.linker.base.410295810" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+ <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1652873432" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+ <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.45065343" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+ <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+ <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+ </inputType>
+ </tool>
+ <tool id="cdt.managedbuild.tool.gnu.assembler.base.1996757503" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+ <option id="gnu.both.asm.option.include.paths.644695978" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include-fixed"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/x86_64-pc-linux-gnu"/>
+ <listOptionValue builtIn="false" value="/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.2/include/g++-v4/backward"/>
+ </option>
+ <inputType id="cdt.managedbuild.tool.gnu.assembler.input.324509035" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+ </tool>
+ </toolChain>
+ </folderInfo>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ <storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
+ <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+ <project id="vdr-vdrmanager.null.1041659956" name="vdr-vdrmanager"/>
+ </storageModule>
+ <storageModule moduleId="refreshScope" versionNumber="2">
+ <configuration configurationName="Default">
+ <resource resourceType="PROJECT" workspacePath="/vdr-vdrmanager"/>
+ </configuration>
+ </storageModule>
+ <storageModule moduleId="scannerConfiguration">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.189548183;cdt.managedbuild.toolchain.gnu.base.189548183.1555344799;cdt.managedbuild.tool.gnu.c.compiler.base.2050235224;cdt.managedbuild.tool.gnu.c.compiler.input.2005963507">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+ </scannerConfigBuildInfo>
+ <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.189548183;cdt.managedbuild.toolchain.gnu.base.189548183.1555344799;cdt.managedbuild.tool.gnu.cpp.compiler.base.1881829081;cdt.managedbuild.tool.gnu.cpp.compiler.input.938487798">
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+ </scannerConfigBuildInfo>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+ <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cproject>
diff --git a/.dependencies b/.dependencies
deleted file mode 100644
index 4163ab6..0000000
--- a/.dependencies
+++ /dev/null
@@ -1,8 +0,0 @@
-vdrmanager.o: vdrmanager.cpp vdrmanagerthread.h
-sock.o: sock.cpp sock.h helpers.h
-vdrmanagerthread.o: vdrmanagerthread.cpp vdrmanagerthread.h select.h \
- sock.h handler.h helpers.h
-select.o: select.cpp sock.h select.h handler.h helpers.h
-handler.o: handler.cpp sock.h select.h handler.h vdrmanagerthread.h \
- helpers.h
-helpers.o: helpers.cpp helpers.h vdrmanagerthread.h
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0368644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+/clientsock.o
+/compressor.o
+/handler.o
+/helpers.o
+/libvdr-vdrmanager.so
+/select.o
+/serversock.o
+/sock.o
+/vdrmanager.o
+/vdrmanagerthread.o
diff --git a/.project b/.project
new file mode 100644
index 0000000..eb98125
--- /dev/null
+++ b/.project
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>vdr-vdrmanager</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>?name?</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildArguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.buildCommand</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.contents</key>
+ <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>de.loskutov.FileSync.FSBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.core.ccnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+</projectDescription>
diff --git a/.settings/de.loskutov.anyedit.AnyEditTools.prefs b/.settings/de.loskutov.anyedit.AnyEditTools.prefs
new file mode 100644
index 0000000..09266be
--- /dev/null
+++ b/.settings/de.loskutov.anyedit.AnyEditTools.prefs
@@ -0,0 +1,16 @@
+activeContentFilterList=*.makefile,makefile,*.Makefile,Makefile,Makefile.*,*.mk,MANIFEST.MF
+addNewLine=true
+convertActionOnSaave=AnyEdit.CnvrtTabToSpaces
+eclipse.preferences.version=1
+ignoreBlankLinesWhenTrimming=false
+inActiveContentFilterList=
+javaTabWidthForJava=true
+org.eclipse.jdt.ui.editor.tab.width=2
+projectPropsEnabled=false
+removeTrailingSpaces=true
+replaceAllSpaces=false
+replaceAllTabs=false
+saveAndAddLine=false
+saveAndConvert=false
+saveAndTrim=true
+useModulo4Tabs=false
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
new file mode 100644
index 0000000..11a2c83
--- /dev/null
+++ b/.settings/language.settings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+ <configuration id="cdt.managedbuild.toolchain.gnu.base.189548183" name="Default">
+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+ <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+ <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="(gcc)|([gc]\+\+)|(clang)" prefer-non-shared="true"/>
+ <provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>
+ <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+ </extension>
+ </configuration>
+</project>
diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..77386c2
--- /dev/null
+++ b/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,67 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..b196c64
--- /dev/null
+++ b/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/HISTORY b/HISTORY
index 34ed4d1..1a19269 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,5 +1,24 @@
VDR Plugin 'vdrmanager' Revision History
------------------------------------
+2014-05-31: Version 0.12 (http://projects.vdr-developer.org/versions/show/342)
+- Feature #1687: Enable compression as default
+- Feature #1688: Send VPS Time if presend on an schedule
+- Feature #1700: send flag IsNew to android
+
+2014-01-02: Version 0.11 (http://projects.vdr-developer.org/versions/show/339)
+- Bug #1661: Link libz (Makefile)
+
+2013-12-25: 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
+- Bug #1325: Response stream is blocked until client sends new data
+- Bug #1532: Streaming Recordings issues
+- Feature #790: use some compression (zlib, gzip) to compress responses server sides
+- Feature #1319: Recording Folders
+- Feature #1386: Add Content Flags as found in svdrp to the event line
+- Feature #1570: Support for VDR >= 2.1.2
+- Feature #1571: Transfer Recording Space Information wit recordings listing command
+
+
2013-01-xx: Version 0.9 (http://projects.vdr-developer.org/versions/show/312)
- Improved Timer/Recording deletion
- Improved recording information (recordings command)
@@ -39,7 +58,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/Makefile b/Makefile
index 4fae6b6..0e483f1 100644
--- a/Makefile
+++ b/Makefile
@@ -45,9 +45,28 @@ SOFILE = libvdr-$(PLUGIN).so
-DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+### Conditionally definitions
+
+VDRMANAGER_USE_SSL := 1
+ifneq ($(VDRMANAGER_USE_SSL), 0)
+ADDITIONAL_LIBS = $(shell pkg-config --libs openssl)
+DEFINES += -DVDRMANAGER_USE_SSL=$(VDRMANAGER_USE_SSL)
+endif
+
+VDRMANAGER_USE_ZLIB := 1
+ifneq ($(VDRMANAGER_USE_ZLIB), 0)
+ADDITIONAL_LIBS += $(shell pkg-config --libs zlib)
+DEFINES += -DVDRMANAGER_USE_ZLIB=$(VDRMANAGER_USE_ZLIB)
+endif
+
+VDRMANAGER_USE_GZIP := 1
+ifneq ($(VDRMANAGER_USE_GZIP), 0)
+DEFINES += -DVDRMANAGER_USE_GZIP=$(VDRMANAGER_USE_GZIP)
+endif
+
### The object files (add further files here):
-OBJS = $(PLUGIN).o sock.o vdrmanagerthread.o select.o handler.o helpers.o
+OBJS = $(PLUGIN).o sock.o serversock.o clientsock.o vdrmanagerthread.o select.o handler.o helpers.o compressor.o
### The main target:
@@ -96,7 +115,7 @@ install-i18n: $(I18Nmsgs)
### Targets:
$(SOFILE): $(OBJS)
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@ $(ADDITIONAL_LIBS)
install-lib: $(SOFILE)
install -D $^ $(LIBDIR)/$^.$(APIVERSION)
diff --git a/Makefile.pre.1.7.36 b/Makefile.pre.1.7.36
new file mode 100644
index 0000000..90941fb
--- /dev/null
+++ b/Makefile.pre.1.7.36
@@ -0,0 +1,82 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# $Id$
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+#
+PLUGIN = vdrmanager
+
+### The version number of this plugin (taken from the main source file):
+
+VERSION = $(shell grep 'const char \*VERSION *=' $(PLUGIN).cpp | awk '{ print $$5 }' | sed -e 's/[";]//g')
+
+### The C++ compiler and options:
+
+CXX ?= g++
+CXXFLAGS ?= -O2 -Wall -Woverloaded-virtual -fPIC -g
+
+### The directory environment:
+
+DVBDIR = ../../../../DVB
+VDRDIR = ../../..
+LIBDIR = ../../lib
+TMPDIR = /tmp
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
+### The version number of VDR (taken from VDR's "config.h"):
+
+APIVERSION = $(shell grep 'define APIVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g')
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### Includes and Defines (add further entries here):
+
+INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+
+DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = $(PLUGIN).o sock.o vdrmanagerthread.o select.o handler.o helpers.o
+
+### Implicit rules:
+
+%.o: %.cpp
+ $(CXX) -g $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+# Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.cpp) > $@
+
+-include $(DEPFILE)
+
+### Targets:
+
+all: libvdr-$(PLUGIN).so
+
+libvdr-$(PLUGIN).so: $(OBJS)
+ $(CXX) -g $(CXXFLAGS) -shared $(OBJS) -o $@
+ @cp $@ $(LIBDIR)/$@.$(APIVERSION)
+
+dist: clean
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @mkdir $(TMPDIR)/$(ARCHIVE)
+ @cp -a * $(TMPDIR)/$(ARCHIVE)
+ @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @echo Distribution package created as $(PACKAGE).tgz
+
+clean:
+ @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
diff --git a/README b/README
index 8e0ed1e..610904f 100644
--- a/README
+++ b/README
@@ -8,6 +8,6 @@ This helper plugin allows remote programming VDR using
VDR-Manager running on Android devices.
Installation:
-- It's already debianized, so it can be build just by dpkg-buildpackage -b in the source folder
-- gentoo ebuilds can also be downloaded from the download section
-- Otherwise use Makfile
+http://www.vdr-wiki.de/wiki/index.php/Plugin_Installation
+
+If you use a vdr version lower then 1.7.36, use Makefile.pre.1.7.36
diff --git a/clientsock.cpp b/clientsock.cpp
new file mode 100644
index 0000000..3f78007
--- /dev/null
+++ b/clientsock.cpp
@@ -0,0 +1,429 @@
+/*
+ * extendes sockets
+ */
+#include <unistd.h>
+#include <vdr/plugin.h>
+
+#if VDRMANAGER_USE_SSL
+#include <openssl/err.h>
+#endif
+
+#include "clientsock.h"
+#include "helpers.h"
+#include "compressor.h"
+
+static int clientno = 0;
+
+/*
+ * cVdrmonClientSocket
+ */
+cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password, int compressionMode) {
+ readbuf = "";
+ writebuf = "";
+ sendbuf = NULL;
+ sendsize = 0;
+ sendoffset = 0;
+ disconnected = false;
+ initDisconnect = false;
+ client = ++clientno;
+ this->password = password;
+ this->compressionMode = compressionMode;
+ login = false;
+ compression = false;
+ initCompression = false;
+#if VDRMANAGER_USE_SSL
+ ssl = NULL;
+ sslReadWrite = SSL_NO_RETRY;
+ sslWantsSelect = SSL_ERROR_NONE;
+#endif
+}
+
+cVdrmanagerClientSocket::~cVdrmanagerClientSocket() {
+#if VDRMANAGER_USE_SSL
+ if (ssl) {
+ SSL_free(ssl);
+ }
+#endif
+}
+
+bool cVdrmanagerClientSocket::IsLineComplete() {
+ // check a for complete line
+ string::size_type pos = readbuf.find("\r", 0);
+ if (pos == string::npos)
+ pos = readbuf.find("\n");
+ return pos != string::npos;
+}
+
+bool cVdrmanagerClientSocket::GetLine(string& line) {
+ // check the line
+ string::size_type pos = readbuf.find("\r", 0);
+ if (pos == string::npos)
+ pos = readbuf.find("\n", 0);
+ if (pos == string::npos)
+ return false;
+
+ // extract the line ...
+ line = readbuf.substr(0, pos);
+
+ // handle \r\n
+ if (readbuf[pos] == '\r' && readbuf.length() > pos
+ && readbuf[pos + 1] == '\n')
+ pos++;
+
+ // ... and move the remainder
+ readbuf = readbuf.substr(pos + 1);
+
+ return true;
+}
+
+bool cVdrmanagerClientSocket::Read() {
+
+ if (Disconnected())
+ return false;
+
+ int rc;
+ for(;;) {
+#if VDRMANAGER_USE_SSL
+ if (ssl)
+ rc = ReadSSL();
+ else
+#endif
+ rc = ReadNoSSL();
+
+ // something read?
+ if (rc <= 0)
+ break;
+
+ // command string completed?
+ if (readbuf.find("\n") != string::npos)
+ break;
+ }
+
+ // command string completed
+ if (rc > 0) {
+ return true;
+ }
+
+ // we must retry
+ if (rc == 0) {
+ return true;
+ }
+
+ // socket closed?
+ if (rc == -1) {
+ disconnected = true;
+ return true;
+ }
+
+ // real error
+ disconnected = true;
+ return false;
+}
+
+int cVdrmanagerClientSocket::ReadNoSSL() {
+
+ char buf[2001];
+ int rc = read(sock, buf, sizeof(buf) - 1);
+
+ if (rc > 0) {
+ // data read
+ buf[rc] = 0;
+ readbuf += buf;
+ return rc;
+ }
+
+ // socket closed
+ if (rc == 0) {
+ return -1;
+ }
+
+ if (errno == EAGAIN) {
+ return 0;
+ }
+
+ return -2;
+}
+
+#if VDRMANAGER_USE_SSL
+
+int cVdrmanagerClientSocket::ReadSSL() {
+
+ sslReadWrite = SSL_NO_RETRY;
+ sslWantsSelect = SSL_ERROR_NONE;
+
+ bool len = 0;
+ char buf[2001];
+
+ ERR_clear_error();
+ int rc = SSL_read(ssl, buf, sizeof(buf) - 1);
+
+ if (rc > 0) {
+ buf[rc] = 0;
+ readbuf += buf;
+ return rc;
+ }
+
+ int error = SSL_get_error(ssl, rc);
+ if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
+ // we must retry
+ sslReadWrite = SSL_RETRY_READ;
+ sslWantsSelect = error;
+ return 0;
+ }
+
+ if (error == SSL_ERROR_ZERO_RETURN) {
+ // socket closed
+ return -1;
+ }
+
+ // real error
+ long errorCode = ERR_get_error();
+ char * errorText = ERR_error_string(errorCode, NULL);
+ esyslog("[vdrmanager] error reading from SSL (%ld) %s", errorCode, errorText);
+ return -2;
+}
+#endif
+
+bool cVdrmanagerClientSocket::Disconnected() {
+ return disconnected;
+}
+
+void cVdrmanagerClientSocket::Disconnect() {
+ initDisconnect = true;
+}
+
+void cVdrmanagerClientSocket::Write(string line) {
+ writebuf += line;
+}
+
+bool cVdrmanagerClientSocket::Flush() {
+
+ if (Disconnected()) {
+ return false;
+ }
+
+ // initialize sendbuf if needed
+ if (sendbuf == NULL) {
+ if (!compression) {
+ sendbuf = (char *)malloc(writebuf.length()+1);
+ strcpy(sendbuf, writebuf.c_str());
+ sendsize = writebuf.length();
+#if VDRMANAGER_USE_GZIP || VDRMANAGER_USE_ZLIB
+ } else {
+ Compress();
+#endif
+ }
+ sendoffset = 0;
+ writebuf.clear();
+ }
+
+ // write so many bytes as possible
+ int rc;
+ for(;sendsize > 0;) {
+
+#if VDRMANAGER_USE_SSL
+ if (ssl)
+ rc = FlushSSL();
+ else
+#endif
+ rc = FlushNoSSL();
+
+ if (rc <= 0) {
+ break;
+ }
+ sendsize -= rc;
+ sendoffset += rc;
+ }
+
+ if (rc == 0) {
+ // nothing written
+ return true;
+ }
+
+ // error
+ if (rc < 0) {
+ if (sendbuf != NULL) {
+ free(sendbuf);
+ sendbuf = NULL;
+ }
+ disconnected = true;
+ return false;
+ }
+
+ // all data written?
+ if (sendsize > 0) {
+ return true;
+ }
+
+ if (sendbuf != NULL) {
+ free(sendbuf);
+ sendbuf = NULL;
+ }
+
+ if (initCompression) {
+ isyslog("Compression is activated now");
+ initCompression = false;
+ compression = true;
+ }
+
+ if (initDisconnect) {
+ initDisconnect = false;
+ disconnected = true;
+ }
+
+ return true;
+}
+
+int cVdrmanagerClientSocket::FlushNoSSL() {
+
+ // write so many bytes as possible
+ int rc = write(sock, sendbuf + sendoffset, sendsize);
+ if (rc >= 0) {
+ return rc;
+ }
+
+ if (errno == EAGAIN) {
+ return 0;
+ }
+
+ LOG_ERROR;
+ return -1;
+}
+
+#if VDRMANAGER_USE_SSL
+
+int cVdrmanagerClientSocket::FlushSSL() {
+
+ sslReadWrite = SSL_NO_RETRY;
+ sslWantsSelect = SSL_ERROR_NONE;
+
+ ERR_clear_error();
+ int rc = SSL_write(ssl, sendbuf + sendoffset, sendsize);
+ if (rc > 0) {
+ return rc;
+ }
+
+ int error = SSL_get_error(ssl, rc);
+ if (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) {
+ // we must retry after the wanted operation is possible
+ sslReadWrite = SSL_RETRY_WRITE;
+ sslWantsSelect = error;
+ return 0;
+ }
+
+ if (error == SSL_ERROR_ZERO_RETURN) {
+ // the socket was closed
+ return -1;
+ }
+
+ // real error
+ long errorCode = ERR_get_error();
+ char * errorText = ERR_error_string(errorCode, NULL);
+ esyslog("[vdrmanager] error writing to SSL (%ld) %s", errorCode, errorText);
+ return -1;
+}
+
+#endif
+
+bool cVdrmanagerClientSocket::Attach(int fd, SSL_CTX * sslCtx) {
+ sock = fd;
+ if (!MakeDontBlock()) {
+ return false;
+ }
+
+#if VDRMANAGER_USE_SSL
+ if (sslCtx) {
+ ssl = SSL_new(sslCtx);
+ SSL_set_accept_state(ssl);
+ BIO *bio = BIO_new_socket(sock, BIO_NOCLOSE);
+ SSL_set_bio(ssl, bio, bio);
+ BIO_set_nbio(bio, 1);
+ }
+#endif
+
+ return true;
+}
+
+int cVdrmanagerClientSocket::GetClientId() {
+ return client;
+}
+
+bool cVdrmanagerClientSocket::WritePending() {
+ return sendsize > 0;
+}
+
+bool cVdrmanagerClientSocket::IsLoggedIn() {
+ return login || !password || !*password;
+}
+
+void cVdrmanagerClientSocket::SetLoggedIn() {
+ login = true;
+}
+
+void cVdrmanagerClientSocket::ActivateCompression() {
+
+ string mode = "NONE";
+
+ switch (compressionMode) {
+#if VDRMANAGER_USE_GZIP
+ case COMPRESSION_GZIP:
+ mode = "GZIP";
+ initCompression = true;
+ break;
+#endif
+#if VDRMANAGER_USE_ZLIB
+ case COMPRESSION_ZLIB:
+ mode = "ZLIB";
+ initCompression = true;
+ break;
+#endif
+ default:
+ mode = "NONE";
+ break;
+ }
+
+ Write("!OK " + mode + "\r\n");
+}
+
+#if VDRMANAGER_USE_GZIP || VDRMANAGER_USE_ZLIB
+
+void cVdrmanagerClientSocket::Compress() {
+ cCompressor compressor = cCompressor();
+
+ switch (compressionMode) {
+#if VDRMANAGER_USE_GZIP
+ case COMPRESSION_GZIP:
+ compressor.CompressGzip(writebuf);
+ break;
+#endif
+#if VDRMANAGER_USE_ZLIB
+ case COMPRESSION_ZLIB:
+ compressor.CompressZlib(writebuf);
+ break;
+#endif
+ }
+
+ sendbuf = compressor.GetData();
+ sendsize = compressor.getDataSize();
+
+ double ratio = 1.0 * writebuf.length() / sendsize;
+ dsyslog("[vdrmanager] Compression stats: raw %ld, compressed %ld, ratio %f:1", writebuf.length(), sendsize, ratio);
+}
+
+#endif
+
+#if VDRMANAGER_USE_SSL
+
+int cVdrmanagerClientSocket::GetSslReadWrite() {
+ return sslReadWrite;
+}
+
+int cVdrmanagerClientSocket::GetSslWantsSelect() {
+ return sslWantsSelect;
+}
+
+bool cVdrmanagerClientSocket::IsSSL() {
+ return ssl != NULL;
+}
+
+#endif
diff --git a/clientsock.h b/clientsock.h
new file mode 100644
index 0000000..6c3fba3
--- /dev/null
+++ b/clientsock.h
@@ -0,0 +1,74 @@
+/*
+ * extendes sockets
+ */
+
+#ifndef _VDRMON_CLIENTSOCK
+#define _VDRMON_CLIENTSOCK
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#if VDRMANAGER_USE_SSL
+#include <openssl/ssl.h>
+#else
+#define SSL_CTX void
+#endif
+
+#include <string>
+
+#include "sock.h"
+
+using namespace std;
+
+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;
+#if VDRMANAGER_USE_SSL
+ SSL * ssl;
+ int sslReadWrite;
+ int sslWantsSelect;
+#endif
+public:
+ cVdrmanagerClientSocket(const char * password, int compressionMode);
+ virtual ~cVdrmanagerClientSocket();
+ bool Attach(int fd, SSL_CTX * sslCtx);
+ bool IsLineComplete();
+ bool GetLine(string& line);
+ void Write(string line);
+ bool Read();
+ int ReadNoSSL();
+ bool Flush();
+ int FlushNoSSL();
+#if VDRMANAGER_USE_SSL
+ int ReadSSL();
+ int FlushSSL();
+ int GetSslReadWrite();
+ int GetSslWantsSelect();
+ bool IsSSL();
+#endif
+ bool Disconnected();
+ void Disconnect();
+ int GetClientId();
+ bool WritePending();
+ bool IsLoggedIn();
+ void SetLoggedIn();
+ void ActivateCompression();
+#if VDRMANAGER_USE_GZIP || VDRMANAGER_USE_ZLIB
+ void Compress();
+#endif
+};
+
+#endif
diff --git a/compressor.cpp b/compressor.cpp
new file mode 100644
index 0000000..b4c9051
--- /dev/null
+++ b/compressor.cpp
@@ -0,0 +1,186 @@
+/*
+ * compressor.cpp
+ *
+ * Created on: 23.03.2013
+ * Author: bju
+ */
+
+#if VDRMANAGER_USE_ZLIB || VDRMANAGER_USE_GZIP
+
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "compressor.h"
+
+#if VDRMANAGER_USE_ZLIB
+#include <zlib.h>
+
+#define CHUNK 16384
+#endif
+
+
+cCompressor::cCompressor() {
+ size = 0;
+ data = NULL;
+}
+
+cCompressor::~cCompressor() {
+
+}
+
+#if VDRMANAGER_USE_GZIP
+
+bool cCompressor::CompressGzip(string text) {
+
+ int in_fd[2];
+ if (pipe(in_fd) < 0) {
+ return false;
+ }
+
+ int out_fd[2];
+ if (pipe(out_fd) < 0) {
+ return false;
+ }
+
+ int pid = fork();
+ if (pid < 0) {
+ return false;
+ }
+
+ if (pid == 0) {
+ // child
+ close(in_fd[1]);
+ close(out_fd[0]);
+ dup2(in_fd[0], 0);
+ dup2(out_fd[1], 1);
+
+ execlp("gzip", "gzip", "-c", "-9", NULL);
+
+ exit(-1);
+
+ } else {
+ // parent
+ close(in_fd[0]);
+ close(out_fd[1]);
+
+ if (write(in_fd[1], text.c_str(), text.length()) != text.length())
+ {
+ close(in_fd[1]);
+ close(out_fd[0]);
+ return false;
+ }
+
+ close(in_fd[1]);
+
+ char buf[32*1024];
+
+ for(;;) {
+ int count = read(out_fd[0], buf, sizeof(buf));
+ if (count < 0) {
+ close(out_fd[0]);
+ return false;
+ }
+ if (count == 0)
+ break;
+
+ char * newdata = (char *)malloc(size + count);
+ if (data != NULL) {
+ memcpy(newdata, data, size);
+ }
+ memcpy(newdata + size, buf, count);
+ if (data != NULL) {
+ free(data);
+ }
+ data = newdata;
+ size += count;
+ }
+
+ close(out_fd[0]);
+ }
+
+ return true;
+}
+
+#endif
+
+#if VDRMANAGER_USE_ZLIB
+
+bool cCompressor::CompressZlib(string text) {
+
+ int ret, flush;
+ unsigned have;
+ z_stream strm;
+ unsigned char in[CHUNK];
+ unsigned char out[CHUNK];
+ int level = 9;
+
+ strm.zalloc = Z_NULL;
+ strm.zfree = Z_NULL;
+ strm.opaque = Z_NULL;
+ ret = deflateInit(&strm, level);
+ if (ret != Z_OK)
+ return false;
+
+ string input = text;
+ uInt len;
+
+ do {
+ len = input.length();
+ if (len > CHUNK) {
+ len = CHUNK;
+ }
+ flush = len > 0 ? Z_NO_FLUSH : Z_FINISH;
+
+ strm.avail_in = len;
+ strm.next_in = (unsigned char *)input.c_str();
+
+ do {
+ strm.avail_out = CHUNK;
+ strm.next_out = out;
+
+ ret = deflate(&strm, flush);
+ if (ret < 0) {
+ if (data != NULL) {
+ free(data);
+ }
+ return false;
+ }
+
+ have = CHUNK - strm.avail_out;
+
+ char * newdata = (char *)malloc(size + have);
+ if (data != NULL) {
+ memcpy(newdata, data, size);
+ }
+ memcpy(newdata + size, out, have);
+ if (data != NULL) {
+ free(data);
+ }
+ data = newdata;
+ size += have;
+
+ } while (strm.avail_out == 0);
+
+ input = input.substr(len);
+
+ } while (flush != Z_FINISH);
+
+ // clean up and return
+ (void)deflateEnd(&strm);
+
+ return true;
+}
+
+#endif
+
+char * cCompressor::GetData() {
+ return data;
+}
+
+size_t cCompressor::getDataSize() {
+ return size;
+}
+
+#endif
diff --git a/compressor.h b/compressor.h
new file mode 100644
index 0000000..933d4c0
--- /dev/null
+++ b/compressor.h
@@ -0,0 +1,41 @@
+/*
+ * compressor.h
+ *
+ * Created on: 23.03.2013
+ * Author: bju
+ */
+#ifndef COMPRESSOR_H_
+#define COMPRESSOR_H_
+
+#include <string>
+
+#define COMPRESSION_NONE 0
+
+#if VDRMANAGER_USE_ZLIB || VDRMANAGER_USE_GZIP
+
+#define COMPRESSION_ZLIB 1
+#define COMPRESSION_GZIP 2
+
+using namespace std;
+
+class cCompressor {
+private:
+ char * data;
+ size_t size;
+public:
+ cCompressor();
+ virtual ~cCompressor();
+#if VDRMANAGER_USE_GZIP
+ bool CompressGzip(string text);
+#endif
+#if VDRMANAGER_USE_ZLIB
+ bool CompressZlib(string text);
+#endif
+ char * GetData();
+ size_t getDataSize();
+};
+
+#endif
+
+#endif /* COMPRESSOR_H_ */
+
diff --git a/examples/plugin.vdrmanager.conf b/examples/plugin.vdrmanager.conf
index ec4cad3..4a1db3f 100644
--- a/examples/plugin.vdrmanager.conf
+++ b/examples/plugin.vdrmanager.conf
@@ -2,8 +2,12 @@
#
# For more details see:
# http://projects.vdr-developer.org/projects/vdr-manager/wiki
-# -p port port number to listen to\n"
-# -P password password (none if not given)"
-# -s force check against svdrphosts.conf even if -P option was given (password)";
+# -p port port number to listen to"
+# -P password password (none if not given). No password forces check against svdrphosts.conf."
+# -s force check against svdrphosts.conf, even if a password was given"
+# -c compression selects the compression mode to use ('z' for zlib or 'g' for gzip and 'n' for none)."
+# Zlib compression is enabled as default or is default compression if youf specify -c without arguments";
+# -k certfile[,keyfile] cert and key file for SSL (or one file for both)";
-p 6420
-P change
+-c
diff --git a/examples/vdr.vdrmanager b/examples/vdr.vdrmanager
index e1d1ddb..eafab35 100644
--- a/examples/vdr.vdrmanager
+++ b/examples/vdr.vdrmanager
@@ -2,7 +2,10 @@
#
# For more details see:
# http://projects.vdr-developer.org/projects/vdr-manager/wiki
-# -p port port number to listen to\n"
-# -P password password (none if not given)"
-# -s force check against svdrphosts.conf";
-_EXTRAOPTS="-p 6420 -P change"
+# -p port port number to listen to"
+# -P password password (none if not given). No password forces check against svdrphosts.conf."
+# -s force check against svdrphosts.conf, even if a password was given"
+# -c compression selects the compression mode to use ('z' for zlib or 'g' for gzip and 'n' for none)."
+# Zlib compression is enabled as default or is default compression if youf specify -c without arguments";
+# -k certfile[,keyfile] cert and key file for SSL (or one file for both)";
+_EXTRAOPTS="-p 6420 -P change -c"
diff --git a/handler.cpp b/handler.cpp
index 43b500a..610eda5 100644
--- a/handler.cpp
+++ b/handler.cpp
@@ -17,90 +17,95 @@ bool cHandler::HandleNewClient(cVdrmanagerClientSocket * sock)
bool cHandler::HandleClientRequest(cVdrmanagerClientSocket * sock)
{
- while(sock->Read())
- {
- // get lines
- while (sock->IsLineComplete())
- {
- string line;
- sock->GetLine(line);
+ while (!sock->IsLineComplete() && sock->Read())
+ ;
- // parse request
- size_t space = line.find(' ');
- string cmd;
- string args;
- if (space != string::npos) {
- cmd = cHelpers::ToUpper(line.substr(0, space));
- args = cHelpers::Trim(line.substr(space+1));
- } else {
- cmd = cHelpers::ToUpper(line);
- args = "";
- }
+ if (sock->IsLineComplete()) {
- if (!sock->IsLoggedIn() && cmd != "PASSWD") {
- sock->PutLine("!ERROR\r\n");
- }
- else if (cmd == "PASSWD")
- {
- if (args != sock->GetPassword()) {
- sock->PutLine("!ERROR\r\n");
- } else {
- sock->SetLoggedIn();
- sock->PutLine("!OK\r\n");
- }
- }
- else if (cmd == "TIMERS")
- {
- string text = cHelpers::GetTimers(args);
- sock->PutLine(text);
- }
- else if (cmd == "CHANNELS")
- {
- string text = cHelpers::GetChannels(args);
- sock->PutLine(text);
- }
- else if (cmd == "TEVENTS")
- {
- string text = cHelpers::GetTimeEvents(args);
- sock->PutLine(text);
- }
- else if (cmd == "CEVENTS")
- {
- string text = cHelpers::GetChannelEvents(args);
- sock->PutLine(text);
- }
- else if (cmd == "TIMER")
- {
- string text = cHelpers::SetTimer(args);
- sock->PutLine(text);
- }
- else if (cmd == "SEARCH")
- {
- string text = cHelpers::SearchEvents(args);
- sock->PutLine(text);
- }
- else if(cmd == "RECORDINGS")
- {
- string text = cHelpers::GetRecordings(args);
- sock->PutLine(text);
- }
- else if(cmd == "DRECORDING")
- {
- string text = cHelpers::DelRecording(args);
- sock->PutLine(text);
- }
- else if (cmd == "SETCHANNEL")
- {
- string text = cHelpers::SetChannel(args);
- sock->PutLine(text);
- }
- else if (cmd == "QUIT")
- {
- // close socket
- sock->PutLine(string("Good bye! :-)\n"));
- sock->Disconnect();
+ string line;
+ sock->GetLine(line);
+
+ // parse request
+ size_t space = line.find(' ');
+ string cmd;
+ string args;
+ if (space != string::npos) {
+ cmd = cHelpers::ToUpper(line.substr(0, space));
+ args = cHelpers::Trim(line.substr(space+1));
+ } else {
+ cmd = cHelpers::ToUpper(line);
+ args = "";
+ }
+
+ if (!sock->IsLoggedIn() && cmd != "PASSWD") {
+ sock->Write("!ERROR\r\n");
+ }
+ else if (cmd == "PASSWD")
+ {
+ if (args != sock->GetPassword()) {
+ sock->Write("!ERROR\r\n");
+ } else {
+ sock->SetLoggedIn();
+ sock->Write("!OK\r\n");
}
}
+ else if (cmd == "COMPRESS")
+ {
+ sock->ActivateCompression();
+ }
+ else if (cmd == "TIMERS")
+ {
+ string text = cHelpers::GetTimers(args);
+ sock->Write(text);
+ }
+ else if (cmd == "CHANNELS")
+ {
+ string text = cHelpers::GetChannels(args);
+ sock->Write(text);
+ }
+ else if (cmd == "TEVENTS")
+ {
+ string text = cHelpers::GetTimeEvents(args);
+ sock->Write(text);
+ }
+ else if (cmd == "CEVENTS")
+ {
+ string text = cHelpers::GetChannelEvents(args);
+ sock->Write(text);
+ }
+ else if (cmd == "TIMER")
+ {
+ string text = cHelpers::SetTimer(args);
+ sock->Write(text);
+ }
+ else if (cmd == "SEARCH")
+ {
+ string text = cHelpers::SearchEvents(args);
+ sock->Write(text);
+ }
+ else if(cmd == "RECORDINGS")
+ {
+ string text = cHelpers::GetRecordings(args);
+ sock->Write(text);
+ }
+ else if(cmd == "DRECORDING")
+ {
+ string text = cHelpers::DelRecording(args);
+ sock->Write(text);
+ }
+ else if (cmd == "SETCHANNEL")
+ {
+ string text = cHelpers::SetChannel(args);
+ sock->Write(text);
+ }
+ else if (cmd == "QUIT")
+ {
+ // close socket
+ sock->Write(string("Good bye! :-)\r\n"));
+ sock->Disconnect();
+ }
+
+ sock->Flush();
}
return true;
diff --git a/helpers.cpp b/helpers.cpp
index 80721f3..c6d819d 100644
--- a/helpers.cpp
+++ b/helpers.cpp
@@ -18,18 +18,21 @@
#include <vdr/cutter.h>
#include <vdr/sources.h>
#include <fstream>
+#include "epgsearch/services.h"
#define TIMER_SEP "#|#|#"
// Taken from vdr-ive
#define INDEXFILESUFFIX "/index.vdr"
#define LENGTHFILESUFFIX "/length.vdr"
+static char ServiceInterface[] = "Epgsearch-services-v1.1";
+
string cHelpers::GetRecordings(string args) {
return SafeCall(GetRecordingsIntern);
}
string cHelpers::GetTimers(string args) {
- return SafeCall(GetTimersIntern);
+ return SafeCall(GetTimersIntern, args);
}
string cHelpers::GetChannels(string args) {
@@ -86,13 +89,22 @@ string cHelpers::SearchEvents(string args) {
return SafeCall(SearchEventsIntern, Trim(wantedChannels), Trim(pattern));
}
-string cHelpers::GetTimersIntern() {
+string cHelpers::GetTimersIntern(string options) {
+
+ // timer conflicts wanted?
+ set<string> conflicts;
+ if (options.find("conflicts") != string::npos) {
+ conflicts = GetTimerConflicts();
+ if (conflicts.empty()) {
+ conflicts.insert("");
+ }
+ }
string result = "START\r\n";
// iterate through all timers
for (cTimer * timer = Timers.First(); timer; timer = Timers.Next(timer)) {
- result += ToText(timer);
+ result += ToText(timer, conflicts);
}
return result + "END\r\n";
@@ -100,7 +112,20 @@ string cHelpers::GetTimersIntern() {
string cHelpers::GetRecordingsIntern() {
- string result = "START\r\n";
+ int FreeMB, UsedMB;
+#if APIVERSNUM < 20102
+ int Percent = VideoDiskSpace(&FreeMB, &UsedMB);
+#else
+ int Percent = cVideoDirectory::VideoDiskSpace(&FreeMB, &UsedMB);
+#endif
+
+ std::stringstream sstm;
+
+ sstm << "START|" << (FreeMB + UsedMB) << ":" << FreeMB << ":" << Percent
+ << "\r\n";
+
+ string result = sstm.str();
+
//iterate through all recordings
cRecording* recording = NULL;
for (int i = 0; i < Recordings.Count(); i++) {
@@ -139,9 +164,9 @@ string cHelpers::GetChannelsIntern(string wantedChannels) {
snprintf(number, sizeof(number) - 1, "C%d", channel->Number());
result += number;
result += ":";
- result += channel->Name();
+ result += MapSpecialChars(channel->Name());
result += ":";
- result += channel->Provider();
+ result += MapSpecialChars(channel->Provider());
result += ":";
result += channel->GetChannelID().ToString();
result += ":";
@@ -272,12 +297,21 @@ string cHelpers::DelRecording(cRecording * recording) {
cString FileName = recording->FileName();
+#if VDRVERSNUM < 20102
if (cCutter::Active(recording->FileName())) {
cCutter::Stop();
recording = Recordings.GetByName(FileName); // cCutter::Stop() might have deleted it if it was the edited version
// we continue with the code below even if recording is NULL,
// in order to have the menu updated etc.
}
+#else
+ if (RecordingsHandler.GetUsage(FileName)) {
+ RecordingsHandler.Del(FileName);
+ recording = Recordings.GetByName(FileName); // RecordingsHandler.Del() might have deleted it if it was the edited version
+ // we continue with the code below even if recording is NULL,
+ // in order to have the menu updated etc.
+ }
+#endif
if (cReplayControl::NowReplaying()
&& strcmp(cReplayControl::NowReplaying(), FileName) == 0) {
@@ -287,7 +321,9 @@ string cHelpers::DelRecording(cRecording * recording) {
if (!recording || recording->Delete()) {
cReplayControl::ClearLastReplayed(FileName);
Recordings.DelByName(FileName);
+#if VDRVERSNUM > 10727
cVideoDiskUsage::ForceCheck();
+#endif
}
return "START\r\nEND\r\n";
@@ -368,7 +404,7 @@ string cHelpers::SetTimerIntern(char op, string param) {
Timers.Add(newTimer.get());
Timers.SetModified();
- dsyslog( "[vdrmanager] timer %s added", *newTimer->ToDescr());
+ dsyslog("[vdrmanager] timer %s added", *newTimer->ToDescr());
newTimer.release();
break;
}
@@ -446,8 +482,8 @@ string cHelpers::SetTimerIntern(char op, string param) {
*oldTimer = copy;
Timers.SetModified();
- dsyslog(
- "[vdrmanager] timer %s modified (%s)", *oldTimer->ToDescr(), oldTimer->HasFlags(tfActive) ? "active" : "inactive");
+ dsyslog("[vdrmanager] timer %s modified (%s)", *oldTimer->ToDescr(),
+ oldTimer->HasFlags(tfActive) ? "active" : "inactive");
break;
}
@@ -469,8 +505,8 @@ string cHelpers::SetTimerIntern(char op, string param) {
toggleTimer->OnOff();
Timers.SetModified();
- dsyslog(
- "[vdrmanager] timer %s toggled %s", *toggleTimer->ToDescr(), toggleTimer->HasFlags(tfActive) ? "on" : "off");
+ dsyslog("[vdrmanager] timer %s toggled %s", *toggleTimer->ToDescr(),
+ toggleTimer->HasFlags(tfActive) ? "on" : "off");
break;
}
default:
@@ -544,20 +580,19 @@ string cHelpers::SearchEventsIntern(string wantedChannels, string pattern) {
return result + "END\r\n";
}
-
//copied from vdr-live
-long cHelpers::Duration(cRecording* recording)
-{
+long cHelpers::Duration(cRecording* recording) {
long RecLength = 0;
- if (!recording->FileName()) return 0;
+ if (!recording->FileName())
+ return 0;
#if VDRVERSNUM < 10704
cString filename = cString::sprintf("%s%s", recording->FileName(), INDEXFILESUFFIX);
if (*filename) {
if (access(filename, R_OK) == 0) {
struct stat buf;
if (stat(filename, &buf) == 0) {
- struct tIndex { int offset; uchar type; uchar number; short reserved; };
+ struct tIndex {int offset; uchar type; uchar number; short reserved;};
int delta = buf.st_size % sizeof(tIndex);
if (delta) {
delta = sizeof(tIndex) - delta;
@@ -578,17 +613,16 @@ long cHelpers::Duration(cRecording* recording)
return recording->LengthInSeconds() / 60;
#endif
if (RecLength == 0) {
- cString lengthFile = cString::sprintf("%s%s", recording->FileName(), LENGTHFILESUFFIX);
+ cString lengthFile = cString::sprintf("%s%s", recording->FileName(),
+ LENGTHFILESUFFIX);
ifstream length(*lengthFile);
- if(length)
+ if (length)
length >> RecLength;
}
return RecLength;
}
-
-
string cHelpers::ToText(cRecording * recording) {
const cRecordingInfo * info = recording->Info();
#if APIVERSNUM >= 10705
@@ -653,7 +687,7 @@ string cHelpers::ToText(cRecording * recording) {
}
result += ":";
- if (info->Title()) {
+ if(info->Title()){
result += MapSpecialChars(info->Title());
#if APIVERSNUM >= 10705
} else if (event->Title()) {
@@ -691,7 +725,8 @@ string cHelpers::ToText(cRecording * recording) {
struct stat st;
if (stat(recording->FileName(), &st) == 0) {
result += MapSpecialChars(
- cString::sprintf("%lu:%lu.rec", st.st_dev, st.st_ino));
+ cString::sprintf("%lu:%llu.rec", (unsigned long) st.st_dev,
+ (unsigned long long) st.st_ino));
} else {
result += "";
}
@@ -699,21 +734,28 @@ string cHelpers::ToText(cRecording * recording) {
result += ":";
cRecordControl *rc = cRecordControls::GetRecordControl(
- recording->FileName());
- if(rc){
+ recording->FileName());
+ if (rc) {
cTimer *timer = rc->Timer();
- if(timer){
+ if (timer) {
char buf[100];
snprintf(buf, sizeof(buf) - 1, "%lu", timer->StopTime());
result += buf;
}
}
+ result += ":";
+ //Feature #1319
+ result += MapSpecialChars(recording->Name());
+ //Feature #1699
+ result += ":";
+ snprintf(buf, sizeof(buf) - 1, "%d", recording -> IsNew());
+ result += buf;
result += "\r\n";
return result;
}
-string cHelpers::ToText(cTimer * timer) {
+string cHelpers::ToText(cTimer * timer, set<string> conflicts) {
const cChannel * channel = timer->Channel();
const char * channelName = channel->Name();
@@ -764,8 +806,8 @@ string cHelpers::ToText(cTimer * timer) {
result += ":";
result += MapSpecialChars(timer->Aux() ? timer->Aux() : "");
const cEvent * event = timer->Event();
- dsyslog("[vdrmanager] timer's event is NULL. Try find it");
if (!event) {
+ dsyslog("[vdrmanager] timer's event is NULL. Try find it");
cChannel * channel = Channels.GetByChannelID(
timer->Channel()->GetChannelID());
if (channel) {
@@ -808,6 +850,22 @@ string cHelpers::ToText(cTimer * timer) {
result += ConvertWeekdays(timer->WeekDays());
+ if (!conflicts.empty()) {
+ ostringstream index;
+ index << timer->Index() + 1;
+ if (conflicts.find(index.str()) != conflicts.end()) {
+ result += ":1";
+ } else {
+ result += ":0";
+ }
+ }
+
+ result += ":";
+ if (event && event->Vps()) {
+ snprintf(buf, sizeof(buf) - 1, "%lu", event->Vps());
+ result += buf;
+ }
+
result += "\r\n";
return result;
@@ -819,8 +877,9 @@ string cHelpers::ToText(const cEvent * event) {
event->Schedule()->ChannelID());
// search assigned timer
- eTimerMatch TimerMatch = tmNone;
- cTimer * eventTimer = Timers.GetMatch(event, &TimerMatch);
+
+ //eTimerMatch TimerMatch = tmNone;
+
// if(eventTimer){
//
// for (cTimer * timer = Timers.First(); timer; timer = Timers.Next(timer)) {
@@ -856,10 +915,31 @@ string cHelpers::ToText(const cEvent * event) {
result += MapSpecialChars(channel->GetChannelID().ToString());
result += ":";
result += GetAudioTracks(channel);
+ result += ":";
+
+ if (event->Contents(0)) {
+ string sep = "";
+ for (int i = 0; event->Contents(i); i++) {
+ uchar c = event->Contents(i);
+ result += sep;
+ snprintf(buf, sizeof(buf) - 1, "%u", c);
+ result += buf;
+ sep = " ";
+ }
+ }
+
+ result += ":";
+ if (event->Vps()) {
+ snprintf(buf, sizeof(buf) - 1, "%lu", event->Vps());
+ result += buf;
+ }
+
result += "\r\n";
+ cTimer * eventTimer = Timers.GetMatch(event);
+
if (eventTimer) {
- result += ToText(eventTimer);
+ result += ToText(eventTimer, set<string>());
}
return result;
@@ -1066,86 +1146,6 @@ 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;
@@ -1217,3 +1217,51 @@ int cHelpers::ConvertWeekdays(std::string v) {
res += 1;
return res;
}
+
+set<string> cHelpers::GetTimerConflicts() {
+
+ Epgsearch_services_v1_1 service;
+ set<string> timers;
+ if (cPluginManager::CallFirstService(ServiceInterface, &service)) {
+ cServiceHandler_v1_1* handler =
+ dynamic_cast<cServiceHandler_v1_1*>(service.handler.get());
+ if (handler) {
+ list<string> conflicts = service.handler->TimerConflictList();
+ for (list<string>::iterator it = conflicts.begin();
+ it != conflicts.end(); it++) {
+ string line = *it;
+ size_t sep = line.find(':');
+ line = line.substr(sep + 1);
+
+ while (!line.empty()) {
+ sep = line.find(':');
+ string conflict;
+ if (sep == string::npos) {
+ conflict = line;
+ line = "";
+ } else {
+ conflict = line.substr(0, sep);
+ line = line.substr(sep + 1);
+ }
+
+ sep = conflict.rfind('|');
+ conflict = conflict.substr(sep + 1);
+ while (!conflict.empty()) {
+ sep = conflict.find('#');
+ string timer;
+ if (sep == string::npos) {
+ timer = conflict;
+ conflict = "";
+ } else {
+ timer = conflict.substr(0, sep);
+ conflict = conflict.substr(sep + 1);
+ }
+ timers.insert(timer);
+ }
+ }
+ }
+ }
+ }
+
+ return timers;
+}
diff --git a/helpers.h b/helpers.h
index b9ebee5..d6e2a14 100644
--- a/helpers.h
+++ b/helpers.h
@@ -12,6 +12,7 @@
#include <iomanip>
#include <sstream>
#include <queue>
+#include <set>
using namespace std;
@@ -31,14 +32,12 @@ 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 (*)());
static string SafeCall(string (*)(string), string arg);
static string SafeCall(string (*)(string, string), string arg1, string arg2);
- static string GetTimersIntern();
+ static string GetTimersIntern(string options);
static string GetRecordingsIntern();
static string GetChannelsIntern(string wantedChannels);
static string SetChannelIntern(string wantedChannel);
@@ -53,7 +52,7 @@ private:
static string MapSpecialChars(const cString text);
static string MapSpecialChars(const string text);
static string ToText(const cEvent * event);
- static string ToText(cTimer * timer);
+ static string ToText(cTimer * timer, set<string> conflicts);
static string ToText(cRecording * recording);
static string GetAudioTracks(const cChannel* channel);
static string replaceAll(const string& where, const string& what, const string& replacement);
@@ -65,5 +64,5 @@ private:
static int ConvertWeekdays(string v);
static queue<int> ConvertToBinary(int v);
static string DelRecording(cRecording * r);
-
+ static set<string> GetTimerConflicts();
};
diff --git a/select.cpp b/select.cpp
index 06d9103..5e78584 100644
--- a/select.cpp
+++ b/select.cpp
@@ -17,6 +17,7 @@ struct node {
cSelect::cSelect() {
serversocket = NULL;
+ sslServersocket = NULL;
clientsockets = NULL;
clientsocketcount = 0;
handler = new cHandler;
@@ -29,6 +30,8 @@ cSelect::cSelect() {
cSelect::~cSelect() {
if (serversocket)
delete serversocket;
+ if (sslServersocket)
+ delete sslServersocket;
while (clientsockets) {
node * next = clientsockets->next;
@@ -44,8 +47,9 @@ cSelect::~cSelect() {
delete pollfds;
}
-void cSelect::SetServerSocket(cVdrmanagerServerSocket * sock) {
+void cSelect::SetServerSockets(cVdrmanagerServerSocket * sock, cVdrmanagerServerSocket * sslSock) {
serversocket = sock;
+ sslServersocket = sslSock;
}
void cSelect::AddClientSocket(cVdrmanagerClientSocket * sock) {
@@ -107,31 +111,62 @@ bool cSelect::Action() {
return true;
}
-void cSelect::CreatePollfds() {
- // construct pollfd array
- // we need one pollfd for the eventpipe,
- // the serversocket and each clientsocket
- pollfds = new struct pollfd[clientsocketcount + 1];
- pollfds[0].fd = serversocket->GetSocket();
- pollfds[0].events = POLLIN;
+int cSelect::CreatePollfds() {
+
+ int i = 0;
+
+ int count = clientsocketcount + (sslServersocket ? 2 : 1);
+
+ // we poll for the server socket and for each client socket
+ pollfds = new struct pollfd[count];
+
+ pollfds[i].fd = serversocket->GetSocket();
+ pollfds[i].revents = 0;
+ pollfds[i++].events = POLLIN;
+
+ if (sslServersocket) {
+ pollfds[i].fd = sslServersocket->GetSocket();
+ pollfds[i].revents = 0;
+ pollfds[i++].events = POLLIN;
+ }
node * curnode = clientsockets;
- int i = 1;
while (curnode) {
- pollfds[i].fd = curnode->socket->GetSocket();
- pollfds[i].events = POLLIN;
- if (curnode->socket->WritePending())
- pollfds[i].events |= POLLOUT;
+ cVdrmanagerClientSocket * sock = curnode->socket;
+ pollfds[i].fd = sock->GetSocket();
+#if VDRMANAGER_USE_SSL
+ if (sock->IsSSL()) {
+ if (sock->GetSslWantsSelect() == SSL_ERROR_WANT_READ) {
+ pollfds[i].events = POLLIN | POLLHUP;
+ } else if (sock->GetSslWantsSelect() == SSL_ERROR_WANT_WRITE) {
+ pollfds[i].events = POLLOUT;
+ } else {
+ pollfds[i].events = POLLIN | POLLHUP;
+ if (sock->WritePending())
+ pollfds[i].events |= POLLOUT;
+ }
+ } else {
+#endif
+ pollfds[i].events = POLLIN | POLLHUP;
+ if (curnode->socket->WritePending())
+ pollfds[i].events |= POLLOUT;
+#if VDRMANAGER_USE_SSL
+ }
+#endif
pollfds[i++].revents = 0;
curnode = curnode->next;
}
+
+ return count;
}
bool cSelect::Poll() {
+
// poll for events
- CreatePollfds();
+ int count = CreatePollfds();
+
int rc = 0;
- while ((rc = poll(pollfds, clientsocketcount + 1, -1)) < 0) {
+ while ((rc = poll(pollfds, count, -1)) < 0) {
if (errno != EINTR)
break;
}
@@ -146,34 +181,50 @@ bool cSelect::Poll() {
return true;
// client requests or outstanding writes
- for (int i = 1; i < clientsocketcount + 1; i++) {
+ for (int i = (sslServersocket ? 2 : 1); i < count; i++) {
cVdrmanagerClientSocket * sock = GetClientSocket(pollfds[i].fd);
if (sock) {
- if (pollfds[i].revents & (POLLIN | POLLHUP)) {
+#if VDRMANAGER_USE_SSL
+ if ((pollfds[i].revents & (POLLIN|POLLOUT)) && sock->GetSslReadWrite() != SSL_NO_RETRY) {
+ if (sock->GetSslReadWrite() == SSL_RETRY_READ) {
+ handler->HandleClientRequest(sock);
+ } else {
+ sock->Flush();
+ }
+ } else
+#endif
+ 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);
}
}
}
// new client?
- if (pollfds[0].revents & POLLIN) {
- // get client socket
- cVdrmanagerClientSocket * sock = serversocket->Accept();
- if (sock) {
- // Add client socket
- AddClientSocket(sock);
- // Send current data
- handler->HandleNewClient(sock);
- }
+ for(int i = 0; i < (sslServersocket ? 2 : 1); i++) {
+ if (pollfds[i].revents & POLLIN) {
+ // get client socket
+ cVdrmanagerClientSocket * sock;
+ if (i == 0)
+ sock = serversocket->Accept();
+ else
+ sock = sslServersocket->Accept();
+
+ if (sock) {
+ // Add client socket
+ AddClientSocket(sock);
+ // Send current data
+ handler->HandleNewClient(sock);
+ }
+ }
}
delete pollfds;
diff --git a/select.h b/select.h
index fbdeb02..2a7f5ba 100644
--- a/select.h
+++ b/select.h
@@ -7,7 +7,8 @@
#include <string>
#include <sys/select.h>
-#include "sock.h"
+#include "clientsock.h"
+#include "serversock.h"
#include "handler.h"
struct node;
@@ -17,6 +18,7 @@ private:
node * clientsockets;
int clientsocketcount;
cVdrmanagerServerSocket * serversocket;
+ cVdrmanagerServerSocket * sslServersocket;
cHandler * handler;
struct pollfd * pollfds;
bool stopped;
@@ -26,13 +28,13 @@ public:
cSelect();
virtual ~cSelect();
void DispatchVdrEvent(string event);
- void SetServerSocket(cVdrmanagerServerSocket * sock);
+ void SetServerSockets(cVdrmanagerServerSocket * sock, cVdrmanagerServerSocket * sslSock);
void AddClientSocket(cVdrmanagerClientSocket * sock);
void RemoveClientSocket(cVdrmanagerClientSocket * sock);
bool Action();
bool Stop();
private:
- void CreatePollfds();
+ int CreatePollfds();
cVdrmanagerClientSocket * GetClientSocket(int fd);
bool Poll();
void NotifyClients(string event);
diff --git a/serversock.cpp b/serversock.cpp
new file mode 100644
index 0000000..e118b0b
--- /dev/null
+++ b/serversock.cpp
@@ -0,0 +1,157 @@
+/*
+ * extendes sockets
+ */
+#include <unistd.h>
+#include <vdr/plugin.h>
+
+#if VDRMANAGER_USE_SSL
+#include <openssl/err.h>
+#endif
+
+#include "serversock.h"
+#include "helpers.h"
+#include "compressor.h"
+
+static int clientno = 0;
+
+/*
+ * cVdrmonServerSocket
+ */
+cVdrmanagerServerSocket::cVdrmanagerServerSocket() : cVdrmanagerSocket() {
+ port = -1;
+ sslCtx = NULL;
+}
+
+cVdrmanagerServerSocket::~cVdrmanagerServerSocket() {
+#if VDRMANAGER_USE_SSL
+ if (sslCtx)
+ SSL_CTX_free(sslCtx);
+#endif
+}
+
+bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp, int compressionMode,
+ const char * certFile, const char * keyFile) {
+
+ this->port = port;
+ this->password = password;
+ this->forceCheckSvdrp = forceCheckSvrp;
+ this->compressionMode = compressionMode;
+
+ // create socket
+ sock = socket(PF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ LOG_ERROR;
+ return false;
+ }
+
+ isyslog("[vdrmanager] created %sSSL server socket on port %d", certFile ? "" : "non ", port);
+
+ // allow it to always reuse the same port:
+ int ReUseAddr = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr));
+
+ // bind to address
+ struct sockaddr_in name;
+ name.sin_family = AF_INET;
+ name.sin_port = htons(port);
+ name.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
+ LOG_ERROR;
+ Close();
+ return false;
+ }
+
+ // make it non-blocking:
+ if (!MakeDontBlock()) {
+ Close();
+ return false;
+ }
+
+ // listen to the socket:
+ if (listen(sock, 100) < 0) {
+ LOG_ERROR;
+ Close();
+ return false;
+ }
+
+#if VDRMANAGER_USE_SSL
+
+ if (certFile) {
+ isyslog("[vdrmanager] initialize SSL");
+
+ OpenSSL_add_all_algorithms();
+ OpenSSL_add_all_ciphers();
+ OpenSSL_add_all_digests();
+ OpenSSL_add_ssl_algorithms();
+
+ SSL_load_error_strings();
+ SSL_library_init();
+
+ const SSL_METHOD * method = SSLv23_server_method();
+ sslCtx = SSL_CTX_new(method);
+ if (sslCtx == NULL) {
+ long errorCode = ERR_get_error();
+ char * error = ERR_error_string(errorCode, NULL);
+ esyslog("[vdrmanager] Error initializing SSL context: %s", error);
+ Close();
+ return false;
+ }
+
+ /* set the local certificate from CertFile */
+ SSL_CTX_use_certificate_file(sslCtx, certFile, SSL_FILETYPE_PEM);
+ /* set the private key from KeyFile */
+ SSL_CTX_use_PrivateKey_file(sslCtx, keyFile, SSL_FILETYPE_PEM);
+ /* verify private key */
+ if (!SSL_CTX_check_private_key(sslCtx)) {
+ long errorCode = ERR_get_error();
+ char * error = ERR_error_string(errorCode, NULL);
+ esyslog("[vdrmanager] Error checking SSL keys: %s", error);
+ Close();
+ return false;
+ }
+
+ SSL_CTX_set_mode(sslCtx, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ }
+#endif
+
+ return true;
+}
+
+cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
+ cVdrmanagerClientSocket * newsocket = NULL;
+
+ isyslog("[vdrmanager] new %sclient on port %d", sslCtx ? "SSL " : "", port);
+
+ // accept the connection
+ struct sockaddr_in clientname;
+ uint size = sizeof(clientname);
+ int newsock = accept(sock, (struct sockaddr *) &clientname, &size);
+ if (newsock > 0) {
+ // create client socket
+ newsocket = new cVdrmanagerClientSocket(password, compressionMode);
+ if (!newsocket->Attach(newsock, sslCtx)) {
+ delete newsocket;
+ return NULL;
+ }
+
+ if (!IsPasswordSet() || forceCheckSvdrp == true) {
+ bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
+ if (!accepted) {
+ newsocket->Write(string("NACC Access denied.\n"));
+ newsocket->Flush();
+ delete newsocket;
+ newsocket = NULL;
+ }
+ dsyslog(
+ "[vdrmanager] connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
+ }
+ } else if (errno != EINTR && errno != EAGAIN
+ )
+ LOG_ERROR;
+
+ return newsocket;
+}
+
+int cVdrmanagerServerSocket::GetPort() {
+ return port;
+}
diff --git a/serversock.h b/serversock.h
new file mode 100644
index 0000000..e8c939e
--- /dev/null
+++ b/serversock.h
@@ -0,0 +1,36 @@
+/*
+ * extendes sockets
+ */
+
+#ifndef _VDRMON_SERVERSOCK
+#define _VDRMON_SERVERSOCK
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string>
+
+#include "clientsock.h"
+
+#if VDRMANAGER_USE_SSL
+#define SSL_NO_RETRY 0
+#define SSL_RETRY_READ 1
+#define SSL_RETRY_WRITE 2
+#endif
+
+using namespace std;
+
+class cVdrmanagerServerSocket : public cVdrmanagerSocket
+{
+private:
+ int port;
+ SSL_CTX * sslCtx;
+public:
+ cVdrmanagerServerSocket();
+ virtual ~cVdrmanagerServerSocket();
+ bool Create(int port, const char * password, bool forceCheckSvdrp, int compressionMode, const char * certFile, const char * keyFile);
+ cVdrmanagerClientSocket * Accept();
+ int GetPort();
+};
+
+#endif
diff --git a/sock.cpp b/sock.cpp
index 1d17ee2..fbd8499 100644
--- a/sock.cpp
+++ b/sock.cpp
@@ -5,8 +5,7 @@
#include <vdr/plugin.h>
#include "sock.h"
#include "helpers.h"
-
-static int clientno = 0;
+#include "compressor.h"
/*
* cVdrmonSocket
@@ -50,223 +49,7 @@ const char * cVdrmanagerSocket::GetPassword() {
return password;
}
-/*
- * cVdrmonServerSocket
- */
-cVdrmanagerServerSocket::cVdrmanagerServerSocket() :
- cVdrmanagerSocket() {
-}
-
-cVdrmanagerServerSocket::~cVdrmanagerServerSocket() {
-}
-
-bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp) {
- // save password
- this->password = password;
- this->forceCheckSvdrp = forceCheckSvrp;
- // create socket
- sock = socket(PF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- LOG_ERROR;
- return false;
- }
-
- // allow it to always reuse the same port:
- int ReUseAddr = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr));
-
- // bind to address
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- name.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) {
- LOG_ERROR;
- Close();
- return false;
- }
-
- // make it non-blocking:
- if (!MakeDontBlock()) {
- Close();
- return false;
- }
-
- // listen to the socket:
- if (listen(sock, 100) < 0) {
- LOG_ERROR;
- Close();
- return false;
- }
-
- return true;
-}
-
-cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
- cVdrmanagerClientSocket * newsocket = NULL;
-
- // accept the connection
- struct sockaddr_in clientname;
- uint size = sizeof(clientname);
- int newsock = accept(sock, (struct sockaddr *) &clientname, &size);
- if (newsock > 0) {
- // create client socket
- newsocket = new cVdrmanagerClientSocket(password);
- if (!newsocket->Attach(newsock)) {
- delete newsocket;
- return NULL;
- }
-
- if (!IsPasswordSet() || forceCheckSvdrp == true) {
- bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
- if (!accepted) {
- newsocket->PutLine(string("NACC Access denied.\n"));
- newsocket->Flush();
- delete newsocket;
- newsocket = NULL;
- }
- dsyslog(
- "[vdrmanager] connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
- }
- } else if (errno != EINTR && errno != EAGAIN
- )
- LOG_ERROR;
-
- return newsocket;
-}
-
-/*
- * cVdrmonClientSocket
- */
-cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password) {
- readbuf = writebuf = "";
- disconnected = false;
- client = ++clientno;
- this->password = password;
- login = false;
-}
-
-cVdrmanagerClientSocket::~cVdrmanagerClientSocket() {
-}
-
-bool cVdrmanagerClientSocket::IsLineComplete() {
- // check a for complete line
- string::size_type pos = readbuf.find("\r", 0);
- if (pos == string::npos)
- pos = readbuf.find("\n");
- return pos != string::npos;
-}
-
bool cVdrmanagerSocket::IsPasswordSet(){
- return strcmp(password, "");
+ return strcmp(password, "");
}
-bool cVdrmanagerClientSocket::GetLine(string& line) {
- // check the line
- string::size_type pos = readbuf.find("\r", 0);
- if (pos == string::npos)
- pos = readbuf.find("\n", 0);
- if (pos == string::npos)
- return false;
-
- // extract the line ...
- line = readbuf.substr(0, pos);
-
- // handle \r\n
- if (readbuf[pos] == '\r' && readbuf.length() > pos
- && readbuf[pos + 1] == '\n')
- pos++;
-
- // ... and move the remainder
- readbuf = readbuf.substr(pos + 1);
-
- return true;
-}
-
-bool cVdrmanagerClientSocket::Read() {
- if (Disconnected())
- return false;
-
- int rc;
- bool len = 0;
- char buf[2001];
- while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) {
- buf[rc] = 0;
- readbuf += buf;
- len += rc;
- }
-
- if (rc < 0 && errno != EAGAIN)
- {
- LOG_ERROR;
- return false;
- } else if (rc == 0) {
- disconnected = true;
- }
-
- return len > 0;
-}
-
-bool cVdrmanagerClientSocket::Disconnected() {
- return disconnected;
-}
-
-void cVdrmanagerClientSocket::Disconnect() {
- disconnected = true;
-}
-
-bool cVdrmanagerClientSocket::PutLine(string line) {
- //TODO http://projects.vdr-developer.org/issues/790
- //string line2 = cHelpers::compress_string(line);
- //unsigned long l = line.size();
- //unsigned long l2 = line2.size();
- //if(l2 == 0){
- //l2 = 1;
- //}
- //dsyslog("[vdrmanager] PutLine, line size is %lu, with zlib it would be %lu (factor %lu)", l, l2, l/l2);
- // add line to write buffer
- writebuf += line;
-
- // data present?
- if (writebuf.length() > 0) {
- // write so many bytes as possible
- int rc = write(sock, writebuf.c_str(), writebuf.length());
- if (rc < 0 && errno != EAGAIN)
- {
- LOG_ERROR;
- return false;
- }
-
- // move the remainder
- if (rc > 0)
- writebuf = writebuf.substr(rc, writebuf.length() - rc);
- }
-
- return true;
-}
-
-bool cVdrmanagerClientSocket::Flush() {
- string empty = "";
- return PutLine(empty);
-}
-
-bool cVdrmanagerClientSocket::Attach(int fd) {
- sock = fd;
- return MakeDontBlock();
-}
-
-int cVdrmanagerClientSocket::GetClientId() {
- return client;
-}
-
-bool cVdrmanagerClientSocket::WritePending() {
- return writebuf.length() > 0;
-}
-
-bool cVdrmanagerClientSocket::IsLoggedIn() {
- return login || !password || !*password;
-}
-
-void cVdrmanagerClientSocket::SetLoggedIn() {
- login = true;
-}
diff --git a/sock.h b/sock.h
index 0234afc..bc19d6d 100644
--- a/sock.h
+++ b/sock.h
@@ -5,10 +5,17 @@
#ifndef _VDRMON_SOCK
#define _VDRMON_SOCK
+#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
+#if VDRMANAGER_USE_SSL
+#define SSL_NO_RETRY 0
+#define SSL_RETRY_READ 1
+#define SSL_RETRY_WRITE 2
+#endif
+
using namespace std;
class cVdrmanagerSocket
@@ -17,6 +24,7 @@ protected:
int sock;
const char * password;
bool forceCheckSvdrp;
+ int compressionMode;
protected:
cVdrmanagerSocket();
bool IsPasswordSet();
@@ -28,38 +36,4 @@ public:
const char * GetPassword();
};
-class cVdrmanagerClientSocket : public cVdrmanagerSocket
-{
-private:
- string readbuf;
- string writebuf;
- bool disconnected;
- int client;
- bool login;
-public:
- cVdrmanagerClientSocket(const char * password);
- virtual ~cVdrmanagerClientSocket();
- bool Attach(int fd);
- bool IsLineComplete();
- bool GetLine(string& line);
- bool PutLine(string line);
- bool Read();
- bool Disconnected();
- void Disconnect();
- bool Flush();
- int GetClientId();
- bool WritePending();
- bool IsLoggedIn();
- void SetLoggedIn();
-};
-
-class cVdrmanagerServerSocket : public cVdrmanagerSocket
-{
-public:
- cVdrmanagerServerSocket();
- virtual ~cVdrmanagerServerSocket();
- bool Create(int port, const char * password, bool forceCheckSvdrp);
- cVdrmanagerClientSocket * Accept();
-};
-
#endif
diff --git a/vdrmanager.cpp b/vdrmanager.cpp
index 2b81464..10dc2b5 100644
--- a/vdrmanager.cpp
+++ b/vdrmanager.cpp
@@ -12,10 +12,30 @@
#include <vdr/device.h>
#include <vdr/player.h>
#include "vdrmanagerthread.h"
-
-#define VDRMANAGER_PORT 6420
-
-static const char *VERSION = "0.9";
+#include "compressor.h"
+
+#define VDRMANAGER_PORT 6420
+
+#if VDRMANAGER_USE_SSL
+#define VDRMANAGER_SSL_PORT 6421
+#define VDRMANAGER_CRT_FILE "/etc/vdr/plugins/vdrmanager/vdrmanager.pem"
+#define VDRMANAGER_KEY_FILE "/etc/vdr/plugins/vdrmanager/vdrmanager.pem"
+#endif
+
+#define VDRMANAGER_ARGS_COMMON "p:P:s"
+#if VDRMANAGER_USE_SSL
+#define VDRMANAGER_ARGS_SSL "k:"
+#else
+#define VDRMANAGER_ARGS_SSL
+#endif
+#if VDRMNAGER_USE_GZIP || VDRMANAGER_USE_ZLIB
+#define VDRMANAGER_ARGS_COMPRESS "c::"
+#else
+#define VDRMANAGER_ARGS_COMPRESS
+#endif
+#define VDRMANAGER_ARGS VDRMANAGER_ARGS_COMMON VDRMANAGER_ARGS_SSL VDRMANAGER_ARGS_COMPRESS
+
+static const char *VERSION = "0.12";
static const char *DESCRIPTION = "VDR-Manager support plugin";
class cVdrManager: public cPlugin {
@@ -25,7 +45,12 @@ private:
int port;
const char * password;
bool forceCheckSvdrp;
- bool forceDelete;
+ int compressionMode;
+#if VDRMANAGER_USE_SSL
+ int sslport;
+ const char * certFile;
+ const char * keyFile;
+#endif
protected:
public:
cVdrManager(void);
@@ -57,7 +82,12 @@ cVdrManager::cVdrManager(void) {
port = VDRMANAGER_PORT;
password = "";
forceCheckSvdrp = false;
- forceDelete = false;
+ compressionMode = COMPRESSION_NONE;
+#if VDRMANAGER_USE_SSL
+ sslport = VDRMANAGER_SSL_PORT;
+ certFile = VDRMANAGER_CRT_FILE;
+ keyFile = VDRMANAGER_KEY_FILE;
+#endif
}
cVdrManager::~cVdrManager() {
@@ -73,15 +103,32 @@ 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 -f force delete of a timer or a recording even if they are active\n";
+ 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 ('z' for zlib or 'g' for gzip and 'n' for none).\n"
+ " Zlib compression is enabled as default or is default compression if youf specify -c without arguments";
+#if VDRMANAGER_USE_SSL
+ " -k certfile[,keyfile] cert and key file for SSL (or one file for both)"
+#endif
+ ;
}
bool cVdrManager::ProcessArgs(int argc, char *argv[]) {
int c;
- while ((c = getopt(argc, argv, "p:P:s:f")) != -1)
+ while ((c = getopt(argc, argv, VDRMANAGER_ARGS)) != -1)
switch (c) {
case 'p':
port = atoi(optarg);
+#if VDRMANAGER_USE_SSL
+ {
+ const char * sep = strchr(optarg, ',');
+ if (sep)
+ sslport = atoi(sep + 1);
+ else
+ sslport = port + 1;
+ }
+#endif
break;
case 'P':
password = optarg;
@@ -89,25 +136,49 @@ bool cVdrManager::ProcessArgs(int argc, char *argv[]) {
case 's':
forceCheckSvdrp = true;
break;
- case 'f':
- forceDelete = true;
+#if VDRMANAGER_USE_GZIP || VDRMANAGER_USE_ZLIB
+ case 'c':
+ if (!optarg) {
+ compressionMode = COMPRESSION_ZLIB;
+ } else if (optarg[0] == 'g') {
+ compressionMode = COMPRESSION_GZIP;
+ } else if (optarg[0] == 'z') {
+ compressionMode = COMPRESSION_ZLIB;
+ } else if (optarg[0] == 'n') {
+ compressionMode = COMPRESSION_NONE;
+ } else {
+ return false;
+ }
break;
+#endif
+#if VDRMANAGER_USE_SSL
+ case 'k':
+ {
+ const char * sep = strchr(optarg, ',');
+ if (sep == NULL) {
+ certFile = keyFile = optarg;
+ } else {
+ certFile = strndup(optarg, sep - optarg);
+ keyFile = sep;
+ }
+ }
+ break;
+#endif
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;
}
-// default port
+ // default port
if (port <= 0)
port = VDRMANAGER_PORT;
+#if VDRMANAGER_USE_SSL
+ if (sslport <= 0)
+ sslport = port + 1;
+#endif
+
return true;
}
@@ -115,7 +186,16 @@ 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);
+ Thread = new cVdrManagerThread(port,
+#if VDRMANAGER_USE_SSL
+ sslport,
+#endif
+ password, forceCheckSvdrp
+ , compressionMode
+#if VDRMANAGER_USE_SSL
+ , certFile, keyFile
+#endif
+ );
return Thread != NULL;
}
diff --git a/vdrmanagerthread.cpp b/vdrmanagerthread.cpp
index 2a4ca64..b0c37ba 100644
--- a/vdrmanagerthread.cpp
+++ b/vdrmanagerthread.cpp
@@ -8,12 +8,27 @@
#include "select.h"
#include "helpers.h"
-cVdrManagerThread::cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp)
+cVdrManagerThread::cVdrManagerThread(int port,
+#if VDRMANAGER_USE_SSL
+ int sslPort,
+#endif
+ const char * password, bool forceCheckSvdrp,
+ int compressionMode
+#if VDRMANAGER_USE_SSL
+ , const char * certFile, const char * keyFile
+#endif
+ )
{
select = NULL;
- this -> port = port;
- this -> password = password;
- this -> forceCheckSvdrp = forceCheckSvdrp;
+ this->port = port;
+ this->password = password;
+ this->forceCheckSvdrp = forceCheckSvdrp;
+ this->compressionMode = compressionMode;
+#if VDRMANAGER_USE_SSL
+ this->sslPort = sslPort;
+ this->certFile = certFile;
+ this->keyFile = keyFile;
+#endif
}
cVdrManagerThread::~cVdrManagerThread()
@@ -24,8 +39,10 @@ cVdrManagerThread::~cVdrManagerThread()
void cVdrManagerThread::Action(void)
{
// create listener socket
- if (!Init())
+ if (!Init()) {
+ Cleanup();
return;
+ }
// do processing
select->Action();
@@ -43,19 +60,37 @@ bool cVdrManagerThread::Init()
// create server socket
cVdrmanagerServerSocket * sock = new cVdrmanagerServerSocket();
- if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp))
+ if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp, compressionMode, NULL, NULL))
return false;
- // register server socket
- select->SetServerSocket(sock);
+ // register server sockets
+ select->SetServerSockets(sock, NULL);
+
+#if VDRMANAGER_USE_SSL
+ cVdrmanagerServerSocket * sslSock;
+ if (!access(certFile, R_OK) && !access(keyFile, R_OK)) {
+ sslSock = new cVdrmanagerServerSocket();
+ if (sslSock == NULL || !sslSock->Create(sslPort, password, forceCheckSvdrp, compressionMode, certFile, keyFile)) {
+ return false;
+ }
+ } else {
+ sslSock = NULL;
+ esyslog("[vdrmanager] SSL key files %s and %s can't be read. SSL disabled.", certFile, keyFile);
+ }
+
+ // register server sockets
+ select->SetServerSockets(sock, sslSock);
+#endif
return true;
}
void cVdrManagerThread::Cleanup()
{
- if (select)
+ if (select) {
delete select;
+ select = NULL;
+ }
}
void cVdrManagerThread::Shutdown()
diff --git a/vdrmanagerthread.h b/vdrmanagerthread.h
index 83f5f31..96866b7 100644
--- a/vdrmanagerthread.h
+++ b/vdrmanagerthread.h
@@ -22,8 +22,22 @@ private:
int port;
const char * password;
bool forceCheckSvdrp;
+ int compressionMode;
+#if VDRMANAGER_USE_SSL
+ int sslPort;
+ const char * certFile;
+ const char * keyFile;
+#endif
public:
- cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp);
+ cVdrManagerThread(int port,
+#if VDRMANAGER_USE_SSL
+ int sslPort,
+#endif
+ const char * password, bool forceCheckSvdrp, int compressionMode
+#if VDRMANAGER_USE_SSL
+ , const char * certFile, const char * keyFile
+#endif
+ );
virtual void Action(void);
void Shutdown();
private:
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-vdrmanager.git
More information about the pkg-vdr-dvb-changes
mailing list