summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorgeronimo <geronimo013@gmx.de>2012-07-13 02:26:40 (GMT)
committergeronimo <geronimo013@gmx.de>2012-07-13 02:26:40 (GMT)
commit2d48ae784ea6828e8626c32c848f64232d8f35c0 (patch)
treefab114b03e91125783a778b835dd1913b039cebe /libs
downloadcmp-2d48ae784ea6828e8626c32c848f64232d8f35c0.tar.gz
cmp-2d48ae784ea6828e8626c32c848f64232d8f35c0.tar.bz2
initial import
Diffstat (limited to 'libs')
-rw-r--r--libs/fsScan/.dep.inc5
-rw-r--r--libs/fsScan/Makefile128
-rw-r--r--libs/fsScan/fsScan.cbp73
-rw-r--r--libs/fsScan/fsScan.depend1
-rw-r--r--libs/fsScan/fsScan.layout14
-rw-r--r--libs/fsScan/fsScan.layout.save14
-rw-r--r--libs/fsScan/include/AbstractMedia.h84
-rw-r--r--libs/fsScan/include/AbstractMultiFileMovie.h48
-rw-r--r--libs/fsScan/include/Audio.h43
-rw-r--r--libs/fsScan/include/DVDImage.h45
-rw-r--r--libs/fsScan/include/FilesystemScanner.h59
-rw-r--r--libs/fsScan/include/LegacyVdrRecording.h42
-rw-r--r--libs/fsScan/include/MediaFactory.h49
-rw-r--r--libs/fsScan/include/Movie.h43
-rw-r--r--libs/fsScan/include/Picture.h43
-rw-r--r--libs/fsScan/include/VdrRecording.h42
-rw-r--r--libs/fsScan/nbproject/Makefile-Debug.mk139
-rw-r--r--libs/fsScan/nbproject/Makefile-Release.mk139
-rw-r--r--libs/fsScan/nbproject/Makefile-impl.mk133
-rw-r--r--libs/fsScan/nbproject/Makefile-variables.mk35
-rw-r--r--libs/fsScan/nbproject/Package-Debug.bash75
-rw-r--r--libs/fsScan/nbproject/Package-Release.bash75
-rw-r--r--libs/fsScan/nbproject/configurations.xml97
-rw-r--r--libs/fsScan/nbproject/private/Makefile-variables.mk7
-rw-r--r--libs/fsScan/nbproject/private/configurations.xml72
-rw-r--r--libs/fsScan/nbproject/private/private.xml8
-rw-r--r--libs/fsScan/nbproject/project.xml25
-rw-r--r--libs/fsScan/src/AbstractMedia.cc92
-rw-r--r--libs/fsScan/src/AbstractMultiFileMovie.cc111
-rw-r--r--libs/fsScan/src/Audio.cc65
-rw-r--r--libs/fsScan/src/DVDImage.cc100
-rw-r--r--libs/fsScan/src/FilesystemScanner.cc166
-rw-r--r--libs/fsScan/src/LegacyVdrRecording.cc91
-rw-r--r--libs/fsScan/src/MediaFactory.cc137
-rw-r--r--libs/fsScan/src/Movie.cc61
-rw-r--r--libs/fsScan/src/Picture.cc69
-rw-r--r--libs/fsScan/src/VdrRecording.cc91
-rw-r--r--libs/fsScan/summary.txt1
-rw-r--r--libs/networking/.dep.inc5
-rw-r--r--libs/networking/Makefile128
-rw-r--r--libs/networking/include/AbstractSocket.h63
-rw-r--r--libs/networking/include/Authorization.h115
-rw-r--r--libs/networking/include/ClientSocket.h39
-rw-r--r--libs/networking/include/ConnectionHandler.h77
-rw-r--r--libs/networking/include/ConnectionPoint.h60
-rw-r--r--libs/networking/include/Credentials.h61
-rw-r--r--libs/networking/include/HTTPAuthorizationRequest.h41
-rw-r--r--libs/networking/include/HTTPFileResponse.h48
-rw-r--r--libs/networking/include/HTTPMessage.h92
-rw-r--r--libs/networking/include/HTTPParser.h47
-rw-r--r--libs/networking/include/HTTPRequest.h62
-rw-r--r--libs/networking/include/HTTPRequestHandler.h48
-rw-r--r--libs/networking/include/HTTPResponse.h73
-rw-r--r--libs/networking/include/HTTPServer.h61
-rw-r--r--libs/networking/include/HTTPStatus.h74
-rw-r--r--libs/networking/include/Principal.h64
-rw-r--r--libs/networking/include/ServerConfig.h56
-rw-r--r--libs/networking/include/ServerSocket.h52
-rw-r--r--libs/networking/include/Url.h67
-rw-r--r--libs/networking/nbproject/Makefile-Debug.mk193
-rw-r--r--libs/networking/nbproject/Makefile-Release.mk193
-rw-r--r--libs/networking/nbproject/Makefile-impl.mk133
-rw-r--r--libs/networking/nbproject/Makefile-variables.mk35
-rw-r--r--libs/networking/nbproject/Package-Debug.bash75
-rw-r--r--libs/networking/nbproject/Package-Release.bash75
-rw-r--r--libs/networking/nbproject/configurations.xml114
-rw-r--r--libs/networking/nbproject/private/Makefile-variables.mk7
-rw-r--r--libs/networking/nbproject/private/configurations.xml72
-rw-r--r--libs/networking/nbproject/private/private.xml8
-rw-r--r--libs/networking/nbproject/project.xml25
-rw-r--r--libs/networking/networking.cbp88
-rw-r--r--libs/networking/networking.depend1
-rw-r--r--libs/networking/networking.layout44
-rw-r--r--libs/networking/networking.layout.save44
-rw-r--r--libs/networking/poll.sample53
-rw-r--r--libs/networking/src/AbstractSocket.cc290
-rw-r--r--libs/networking/src/Authorization.cc469
-rw-r--r--libs/networking/src/ClientSocket.cc45
-rw-r--r--libs/networking/src/ConnectionHandler.cc393
-rw-r--r--libs/networking/src/ConnectionPoint.cc89
-rw-r--r--libs/networking/src/Credentials.cc171
-rw-r--r--libs/networking/src/HTTPAuthorizationRequest.cc47
-rw-r--r--libs/networking/src/HTTPFileResponse.cc102
-rw-r--r--libs/networking/src/HTTPMessage.cc165
-rw-r--r--libs/networking/src/HTTPParser.cc42
-rw-r--r--libs/networking/src/HTTPRequest.cc171
-rw-r--r--libs/networking/src/HTTPRequestHandler.cc43
-rw-r--r--libs/networking/src/HTTPResponse.cc183
-rw-r--r--libs/networking/src/HTTPServer.cc156
-rw-r--r--libs/networking/src/HTTPStatus.cc121
-rw-r--r--libs/networking/src/Principal.cc105
-rw-r--r--libs/networking/src/ServerConfig.cc60
-rw-r--r--libs/networking/src/ServerSocket.cc84
-rw-r--r--libs/networking/src/Url.cc229
-rw-r--r--libs/networking/summary.txt1
-rw-r--r--libs/util/.dep.inc5
-rw-r--r--libs/util/Makefile128
-rw-r--r--libs/util/include/AbstractListAssembler.h49
-rw-r--r--libs/util/include/Codec.h92
-rw-r--r--libs/util/include/JSonWriter.h64
-rw-r--r--libs/util/include/MD5Calculator.h45
-rw-r--r--libs/util/include/ManagedMap.h55
-rw-r--r--libs/util/include/ManagedVector.h49
-rw-r--r--libs/util/include/NamedValue.h51
-rw-r--r--libs/util/include/StringBuilder.h60
-rw-r--r--libs/util/include/util.h38
-rw-r--r--libs/util/nbproject/Makefile-Debug.mk133
-rw-r--r--libs/util/nbproject/Makefile-Release.mk133
-rw-r--r--libs/util/nbproject/Makefile-impl.mk133
-rw-r--r--libs/util/nbproject/Makefile-variables.mk35
-rw-r--r--libs/util/nbproject/Package-Debug.bash75
-rw-r--r--libs/util/nbproject/Package-Release.bash75
-rw-r--r--libs/util/nbproject/configurations.xml93
-rw-r--r--libs/util/nbproject/private/Makefile-variables.mk7
-rw-r--r--libs/util/nbproject/private/configurations.xml72
-rw-r--r--libs/util/nbproject/private/private.xml8
-rw-r--r--libs/util/nbproject/project.xml25
-rw-r--r--libs/util/src/AbstractListAssembler.cc57
-rw-r--r--libs/util/src/Codec.cc248
-rw-r--r--libs/util/src/JSonWriter.cc178
-rw-r--r--libs/util/src/MD5Calculator.cc57
-rw-r--r--libs/util/src/ManagedMap.cc73
-rw-r--r--libs/util/src/ManagedVector.cc51
-rw-r--r--libs/util/src/NamedValue.cc67
-rw-r--r--libs/util/src/StringBuilder.cc178
-rw-r--r--libs/util/src/util.cc61
-rw-r--r--libs/util/summary.txt1
-rw-r--r--libs/util/util.cbp69
-rw-r--r--libs/util/util.depend1
-rw-r--r--libs/util/util.layout44
-rw-r--r--libs/util/util.layout.save44
-rw-r--r--libs/vdr/.dep.inc5
-rw-r--r--libs/vdr/Makefile128
-rw-r--r--libs/vdr/doc/Legal.Note27
-rw-r--r--libs/vdr/include/CharsetConv.h115
-rw-r--r--libs/vdr/include/CondWait.h61
-rw-r--r--libs/vdr/include/FileNameList.h41
-rw-r--r--libs/vdr/include/Logging.h45
-rw-r--r--libs/vdr/include/Mutex.h63
-rw-r--r--libs/vdr/include/ReadDir.h53
-rw-r--r--libs/vdr/include/String.h85
-rw-r--r--libs/vdr/include/StringList.h61
-rw-r--r--libs/vdr/include/Thread.h101
-rw-r--r--libs/vdr/include/TimeMs.h50
-rw-r--r--libs/vdr/include/Vector.h119
-rw-r--r--libs/vdr/include/i18n.h108
-rw-r--r--libs/vdr/include/tools.h49
-rw-r--r--libs/vdr/nbproject/Makefile-Debug.mk145
-rw-r--r--libs/vdr/nbproject/Makefile-Release.mk145
-rw-r--r--libs/vdr/nbproject/Makefile-impl.mk133
-rw-r--r--libs/vdr/nbproject/Makefile-variables.mk35
-rw-r--r--libs/vdr/nbproject/Package-Debug.bash75
-rw-r--r--libs/vdr/nbproject/Package-Release.bash75
-rw-r--r--libs/vdr/nbproject/configurations.xml101
-rw-r--r--libs/vdr/nbproject/private/Makefile-variables.mk7
-rw-r--r--libs/vdr/nbproject/private/configurations.xml72
-rw-r--r--libs/vdr/nbproject/private/private.xml8
-rw-r--r--libs/vdr/nbproject/project.xml25
-rw-r--r--libs/vdr/src/CharsetConv.cc294
-rw-r--r--libs/vdr/src/CondWait.cc101
-rw-r--r--libs/vdr/src/FileNameList.cc70
-rw-r--r--libs/vdr/src/Logging.cc46
-rw-r--r--libs/vdr/src/Mutex.cc81
-rw-r--r--libs/vdr/src/ReadDir.cc53
-rw-r--r--libs/vdr/src/String.cc379
-rw-r--r--libs/vdr/src/StringList.cc50
-rw-r--r--libs/vdr/src/Thread.cc209
-rw-r--r--libs/vdr/src/TimeMs.cc101
-rw-r--r--libs/vdr/src/i18n.cc324
-rw-r--r--libs/vdr/summary.txt1
-rw-r--r--libs/vdr/vdr.cbp83
-rw-r--r--libs/vdr/vdr.depend1
-rw-r--r--libs/vdr/vdr.layout24
-rw-r--r--libs/vdr/vdr.layout.save24
174 files changed, 14308 insertions, 0 deletions
diff --git a/libs/fsScan/.dep.inc b/libs/fsScan/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/libs/fsScan/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/libs/fsScan/Makefile b/libs/fsScan/Makefile
new file mode 100644
index 0000000..ec9de69
--- /dev/null
+++ b/libs/fsScan/Makefile
@@ -0,0 +1,128 @@
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# Available make variables:
+#
+# CND_BASEDIR base directory for relative paths
+# CND_DISTDIR default top distribution directory (build artifacts)
+# CND_BUILDDIR default top build directory (object files, ...)
+# CONF name of current configuration
+# CND_PLATFORM_${CONF} platform name (current configuration)
+# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
+# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
+# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
+# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
+# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
+# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
+#
+# NOCDDL
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+
+
+# build
+build: .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post: .build-impl
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post: .clean-impl
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+# build tests
+build-tests: .build-tests-post
+
+.build-tests-pre:
+# Add your pre 'build-tests' code here...
+
+.build-tests-post: .build-tests-impl
+# Add your post 'build-tests' code here...
+
+
+# run tests
+test: .test-post
+
+.test-pre:
+# Add your pre 'test' code here...
+
+.test-post: .test-impl
+# Add your post 'test' code here...
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
+
+# include project make variables
+include nbproject/Makefile-variables.mk
diff --git a/libs/fsScan/fsScan.cbp b/libs/fsScan/fsScan.cbp
new file mode 100644
index 0000000..bef32fe
--- /dev/null
+++ b/libs/fsScan/fsScan.cbp
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="CMP.libs.fsScan" />
+ <Option pch_mode="2" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Debug">
+ <Option output="libfsScan" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Debug/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-g" />
+ </Compiler>
+ </Target>
+ <Target title="Release">
+ <Option output="libfsScan" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Release/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-O2" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ </Linker>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi" />
+ <Add option="-D_REENTRANT" />
+ <Add option="-D_GNU_SOURCE=1" />
+ <Add directory="../vdr/include" />
+ <Add directory="../util/include" />
+ <Add directory="../networking/include" />
+ <Add directory="include" />
+ </Compiler>
+ <Unit filename="include/AbstractMedia.h" />
+ <Unit filename="include/AbstractMultiFileMovie.h" />
+ <Unit filename="include/Audio.h" />
+ <Unit filename="include/DVDImage.h" />
+ <Unit filename="include/FilesystemScanner.h" />
+ <Unit filename="include/LegacyVdrRecording.h" />
+ <Unit filename="include/MediaFactory.h" />
+ <Unit filename="include/Movie.h" />
+ <Unit filename="include/Picture.h" />
+ <Unit filename="include/VdrRecording.h" />
+ <Unit filename="src/AbstractMedia.cc" />
+ <Unit filename="src/AbstractMultiFileMovie.cc" />
+ <Unit filename="src/Audio.cc" />
+ <Unit filename="src/DVDImage.cc" />
+ <Unit filename="src/FilesystemScanner.cc" />
+ <Unit filename="src/LegacyVdrRecording.cc" />
+ <Unit filename="src/MediaFactory.cc" />
+ <Unit filename="src/Movie.cc" />
+ <Unit filename="src/Picture.cc" />
+ <Unit filename="src/VdrRecording.cc" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <lib_finder disable_auto="1" />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/libs/fsScan/fsScan.depend b/libs/fsScan/fsScan.depend
new file mode 100644
index 0000000..c4ac310
--- /dev/null
+++ b/libs/fsScan/fsScan.depend
@@ -0,0 +1 @@
+# depslib dependency file v1.0
diff --git a/libs/fsScan/fsScan.layout b/libs/fsScan/fsScan.layout
new file mode 100644
index 0000000..f1a8eb2
--- /dev/null
+++ b/libs/fsScan/fsScan.layout
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/MediaFactory.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/AbstractMedia.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/fsScan/fsScan.layout.save b/libs/fsScan/fsScan.layout.save
new file mode 100644
index 0000000..f1a8eb2
--- /dev/null
+++ b/libs/fsScan/fsScan.layout.save
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/MediaFactory.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/AbstractMedia.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/fsScan/include/AbstractMedia.h b/libs/fsScan/include/AbstractMedia.h
new file mode 100644
index 0000000..4b8fedd
--- /dev/null
+++ b/libs/fsScan/include/AbstractMedia.h
@@ -0,0 +1,84 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMedia.h
+ * Created: 2. Juli 2012, 14:33
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef ABSTRACTMEDIA_H
+#define ABSTRACTMEDIA_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <vector>
+
+typedef struct {
+ const char *extension;
+ const char *mimeType;
+} SupportedExtension;
+
+class cAbstractMedia {
+public:
+ typedef enum {
+ Invalid,
+ Audio,
+ Movie,
+ DVDImage,
+ LegacyVdrRecording,
+ VdrRecording,
+ Picture,
+ Unknown
+ } SupportedMediaType;
+
+ virtual ~cAbstractMedia();
+
+ virtual void Refresh(void);
+ ///< will be called right before start streaming, so this call is used to
+ ///< determine the real size, number of files, etc.
+ virtual size_t ReadChunk(char *buf, size_t bufSize);
+ ///< used to hide the differences between single- and multi-file media.
+
+ SupportedMediaType MediaType(void) const { return mediaType; }
+ const char *LogicalPath(void) const { return logicalPath; }
+ const char *RealPath(void) const { return realPath; }
+ const char *Name(void) const { return name; }
+ const char *MimeType(void) const { return mimeType; }
+ time_t LastModified(void) const { return lastModified; }
+ void SetLastModified(time_t when) { lastModified = when; }
+ size_t Size(void) const { return size; }
+ void SetSize(size_t Size) { size = Size; }
+ static const char *MediaType2Text(int Type);
+
+protected:
+ cAbstractMedia(SupportedMediaType Type, const char *Name, const char *Logical, const char *Path, const char *Mime);
+ int fd;
+
+private:
+ SupportedMediaType mediaType;
+ char *logicalPath;
+ char *realPath;
+ char *name;
+ char *mimeType;
+ time_t lastModified;
+ size_t size;
+ };
+
+#endif /* ABSTRACTMEDIA_H */
+
diff --git a/libs/fsScan/include/AbstractMultiFileMovie.h b/libs/fsScan/include/AbstractMultiFileMovie.h
new file mode 100644
index 0000000..e3bd520
--- /dev/null
+++ b/libs/fsScan/include/AbstractMultiFileMovie.h
@@ -0,0 +1,48 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMultiFileMovie.h
+ * Created: 3. Juli 2012, 07:39
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef ABSTRACTMULTIFILEMOVIE_H
+#define ABSTRACTMULTIFILEMOVIE_H
+
+#include <Movie.h>
+
+class cAbstractMultiFileMovie : public cMovie {
+public:
+ virtual ~cAbstractMultiFileMovie();
+
+ virtual size_t ReadChunk(char *buf, size_t bufSize);
+
+ virtual const char *FirstFile(void) = 0;
+ virtual const char *NextFile(void) = 0;
+
+protected:
+ cAbstractMultiFileMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type);
+ int movieFiles;
+ int curFileNo;
+ char *fileNameBuf; // this class does not need it, but all subclasses do ...
+ size_t bufSize;
+ };
+
+#endif /* ABSTRACTMULTIFILEMOVIE_H */
+
diff --git a/libs/fsScan/include/Audio.h b/libs/fsScan/include/Audio.h
new file mode 100644
index 0000000..d1a784a
--- /dev/null
+++ b/libs/fsScan/include/Audio.h
@@ -0,0 +1,43 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Audio.h
+ * Created: 2. Juli 2012, 15:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include <AbstractMedia.h>
+
+class cAudio : public cAbstractMedia {
+public:
+ cAudio(const char *Name, const char *Logical, const char *Path, const char *Mime);
+ virtual ~cAudio();
+
+private:
+ static const char *ContentType(const char *Extension);
+ static SupportedExtension knownExtensions[];
+ friend class cMediaFactory;
+ friend class FScanTest;
+ };
+
+#endif /* AUDIO_H */
+
diff --git a/libs/fsScan/include/DVDImage.h b/libs/fsScan/include/DVDImage.h
new file mode 100644
index 0000000..e773e72
--- /dev/null
+++ b/libs/fsScan/include/DVDImage.h
@@ -0,0 +1,45 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: DVDImage.h
+ * Created: 3. Juli 2012, 08:34
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef DVDIMAGE_H
+#define DVDIMAGE_H
+
+#include <AbstractMultiFileMovie.h>
+
+class cDVDImage : public cAbstractMultiFileMovie {
+public:
+ cDVDImage(const char *Name, const char *Logical, const char *Path);
+ virtual ~cDVDImage();
+
+ virtual void Refresh(void);
+
+ virtual const char *FirstFile(void);
+ virtual const char *NextFile(void);
+
+private:
+ int mainMovie;
+ };
+
+#endif /* DVDIMAGE_H */
+
diff --git a/libs/fsScan/include/FilesystemScanner.h b/libs/fsScan/include/FilesystemScanner.h
new file mode 100644
index 0000000..7a188ce
--- /dev/null
+++ b/libs/fsScan/include/FilesystemScanner.h
@@ -0,0 +1,59 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FilesystemScanner.h
+ * Created: 2. Juli 2012, 13:58
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef FILESYSTEMSCANNER_H
+#define FILESYSTEMSCANNER_H
+
+#include <ManagedVector.h>
+#include <MediaFactory.h>
+#include <map>
+
+class cAbstractMedia;
+class cFilesystemScanner {
+public:
+ cFilesystemScanner();
+ virtual ~cFilesystemScanner();
+
+ cManagedVector &MediaPool(void) { return pool; }
+ std::map<int, size_t> &Categories(void) { return categories; }
+ cAbstractMedia *FindMedia(const char *LogicalPath);
+ void Refresh(void);
+
+ void SetBaseDirectory(const char *dir);
+ void SetMediaFactory(cMediaFactory *factory);
+
+protected:
+ void parseDir(const char *dir, cManagedVector &result);
+
+private:
+ char *baseDirectory;
+ size_t fileBufSize;
+ struct dirent *dirEntryBuf;
+ cManagedVector pool;
+ std::map<int, size_t> categories;
+ cMediaFactory *mediaFactory;
+ };
+
+#endif /* FILESYSTEMSCANNER_H */
+
diff --git a/libs/fsScan/include/LegacyVdrRecording.h b/libs/fsScan/include/LegacyVdrRecording.h
new file mode 100644
index 0000000..147e6fc
--- /dev/null
+++ b/libs/fsScan/include/LegacyVdrRecording.h
@@ -0,0 +1,42 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: LegacyVdrRecording.h
+ * Created: 3. Juli 2012, 08:16
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef LEGACYVDRRECORDING_H
+#define LEGACYVDRRECORDING_H
+
+#include <AbstractMultiFileMovie.h>
+
+class cLegacyVdrRecording : public cAbstractMultiFileMovie {
+public:
+ cLegacyVdrRecording(const char *Name, const char *Logical, const char *Path);
+ virtual ~cLegacyVdrRecording();
+
+ virtual void Refresh(void);
+
+ virtual const char *FirstFile(void);
+ virtual const char *NextFile(void);
+ };
+
+#endif /* LEGACYVDRRECORDING_H */
+
diff --git a/libs/fsScan/include/MediaFactory.h b/libs/fsScan/include/MediaFactory.h
new file mode 100644
index 0000000..b9b5391
--- /dev/null
+++ b/libs/fsScan/include/MediaFactory.h
@@ -0,0 +1,49 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: MediaFactory.h
+ * Created: 2. Juli 2012, 15:43
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef MEDIAFACTORY_H
+#define MEDIAFACTORY_H
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+class cAbstractMedia;
+class cMediaFactory {
+public:
+ cMediaFactory(const char *BaseDirectory);
+ virtual ~cMediaFactory();
+
+ cAbstractMedia *CreateMedia(const char *FileOrDirname, struct stat *st);
+
+ const char *BaseDirectory(void) const { return baseDirectory; }
+ void SetBaseDirectory(const char *dir);
+
+private:
+ char *baseDirectory;
+ char *scratch;
+ size_t scratchSize;
+ };
+
+#endif /* MEDIAFACTORY_H */
+
diff --git a/libs/fsScan/include/Movie.h b/libs/fsScan/include/Movie.h
new file mode 100644
index 0000000..af8b437
--- /dev/null
+++ b/libs/fsScan/include/Movie.h
@@ -0,0 +1,43 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Movie.h
+ * Created: 2. Juli 2012, 15:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef MOVIE_H
+#define MOVIE_H
+
+#include <AbstractMedia.h>
+
+class cMovie : public cAbstractMedia {
+public:
+ cMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type = cAbstractMedia::Movie);
+ virtual ~cMovie();
+
+private:
+ static const char *ContentType(const char *Extension);
+ static SupportedExtension knownExtensions[];
+ friend class cMediaFactory;
+ friend class FScanTest;
+ };
+
+#endif /* MOVIE_H */
+
diff --git a/libs/fsScan/include/Picture.h b/libs/fsScan/include/Picture.h
new file mode 100644
index 0000000..a911a71
--- /dev/null
+++ b/libs/fsScan/include/Picture.h
@@ -0,0 +1,43 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Picture.h
+ * Created: 2. Juli 2012, 15:18
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef PICTURE_H
+#define PICTURE_H
+
+#include <AbstractMedia.h>
+
+class cPicture : public cAbstractMedia {
+public:
+ cPicture(const char *Name, const char *Logical, const char *Path, const char *Mime);
+ virtual ~cPicture();
+
+private:
+ static const char *ContentType(const char *Extension);
+ static SupportedExtension knownExtensions[];
+ friend class cMediaFactory;
+ friend class FScanTest;
+ };
+
+#endif /* PICTURE_H */
+
diff --git a/libs/fsScan/include/VdrRecording.h b/libs/fsScan/include/VdrRecording.h
new file mode 100644
index 0000000..2e3904b
--- /dev/null
+++ b/libs/fsScan/include/VdrRecording.h
@@ -0,0 +1,42 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: VdrRecording.h
+ * Created: 3. Juli 2012, 08:30
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef VDRRECORDING_H
+#define VDRRECORDING_H
+
+#include <AbstractMultiFileMovie.h>
+
+class cVdrRecording : public cAbstractMultiFileMovie {
+public:
+ cVdrRecording(const char *Name, const char *Logical, const char *Path);
+ virtual ~cVdrRecording();
+
+ virtual void Refresh(void);
+
+ virtual const char *FirstFile(void);
+ virtual const char *NextFile(void);
+ };
+
+#endif /* VDRRECORDING_H */
+
diff --git a/libs/fsScan/nbproject/Makefile-Debug.mk b/libs/fsScan/nbproject/Makefile-Debug.mk
new file mode 100644
index 0000000..f2cf866
--- /dev/null
+++ b/libs/fsScan/nbproject/Makefile-Debug.mk
@@ -0,0 +1,139 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/Picture.o \
+ ${OBJECTDIR}/src/Audio.o \
+ ${OBJECTDIR}/src/DVDImage.o \
+ ${OBJECTDIR}/src/VdrRecording.o \
+ ${OBJECTDIR}/src/LegacyVdrRecording.o \
+ ${OBJECTDIR}/src/MediaFactory.o \
+ ${OBJECTDIR}/src/FilesystemScanner.o \
+ ${OBJECTDIR}/src/AbstractMultiFileMovie.o \
+ ${OBJECTDIR}/src/AbstractMedia.o \
+ ${OBJECTDIR}/src/Movie.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+CXXFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+${OBJECTDIR}/src/Picture.o: nbproject/Makefile-${CND_CONF}.mk src/Picture.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Picture.o src/Picture.cc
+
+${OBJECTDIR}/src/Audio.o: nbproject/Makefile-${CND_CONF}.mk src/Audio.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Audio.o src/Audio.cc
+
+${OBJECTDIR}/src/DVDImage.o: nbproject/Makefile-${CND_CONF}.mk src/DVDImage.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/DVDImage.o src/DVDImage.cc
+
+${OBJECTDIR}/src/VdrRecording.o: nbproject/Makefile-${CND_CONF}.mk src/VdrRecording.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/VdrRecording.o src/VdrRecording.cc
+
+${OBJECTDIR}/src/LegacyVdrRecording.o: nbproject/Makefile-${CND_CONF}.mk src/LegacyVdrRecording.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/LegacyVdrRecording.o src/LegacyVdrRecording.cc
+
+${OBJECTDIR}/src/MediaFactory.o: nbproject/Makefile-${CND_CONF}.mk src/MediaFactory.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/MediaFactory.o src/MediaFactory.cc
+
+${OBJECTDIR}/src/FilesystemScanner.o: nbproject/Makefile-${CND_CONF}.mk src/FilesystemScanner.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/FilesystemScanner.o src/FilesystemScanner.cc
+
+${OBJECTDIR}/src/AbstractMultiFileMovie.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractMultiFileMovie.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractMultiFileMovie.o src/AbstractMultiFileMovie.cc
+
+${OBJECTDIR}/src/AbstractMedia.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractMedia.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractMedia.o src/AbstractMedia.cc
+
+${OBJECTDIR}/src/Movie.o: nbproject/Makefile-${CND_CONF}.mk src/Movie.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../networking/include -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Movie.o src/Movie.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/fsScan/nbproject/Makefile-Release.mk b/libs/fsScan/nbproject/Makefile-Release.mk
new file mode 100644
index 0000000..17f8aff
--- /dev/null
+++ b/libs/fsScan/nbproject/Makefile-Release.mk
@@ -0,0 +1,139 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/Picture.o \
+ ${OBJECTDIR}/src/Audio.o \
+ ${OBJECTDIR}/src/DVDImage.o \
+ ${OBJECTDIR}/src/VdrRecording.o \
+ ${OBJECTDIR}/src/LegacyVdrRecording.o \
+ ${OBJECTDIR}/src/MediaFactory.o \
+ ${OBJECTDIR}/src/FilesystemScanner.o \
+ ${OBJECTDIR}/src/AbstractMultiFileMovie.o \
+ ${OBJECTDIR}/src/AbstractMedia.o \
+ ${OBJECTDIR}/src/Movie.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+${OBJECTDIR}/src/Picture.o: nbproject/Makefile-${CND_CONF}.mk src/Picture.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Picture.o src/Picture.cc
+
+${OBJECTDIR}/src/Audio.o: nbproject/Makefile-${CND_CONF}.mk src/Audio.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Audio.o src/Audio.cc
+
+${OBJECTDIR}/src/DVDImage.o: nbproject/Makefile-${CND_CONF}.mk src/DVDImage.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/DVDImage.o src/DVDImage.cc
+
+${OBJECTDIR}/src/VdrRecording.o: nbproject/Makefile-${CND_CONF}.mk src/VdrRecording.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/VdrRecording.o src/VdrRecording.cc
+
+${OBJECTDIR}/src/LegacyVdrRecording.o: nbproject/Makefile-${CND_CONF}.mk src/LegacyVdrRecording.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/LegacyVdrRecording.o src/LegacyVdrRecording.cc
+
+${OBJECTDIR}/src/MediaFactory.o: nbproject/Makefile-${CND_CONF}.mk src/MediaFactory.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/MediaFactory.o src/MediaFactory.cc
+
+${OBJECTDIR}/src/FilesystemScanner.o: nbproject/Makefile-${CND_CONF}.mk src/FilesystemScanner.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/FilesystemScanner.o src/FilesystemScanner.cc
+
+${OBJECTDIR}/src/AbstractMultiFileMovie.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractMultiFileMovie.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractMultiFileMovie.o src/AbstractMultiFileMovie.cc
+
+${OBJECTDIR}/src/AbstractMedia.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractMedia.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractMedia.o src/AbstractMedia.cc
+
+${OBJECTDIR}/src/Movie.o: nbproject/Makefile-${CND_CONF}.mk src/Movie.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Movie.o src/Movie.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/fsScan/nbproject/Makefile-impl.mk b/libs/fsScan/nbproject/Makefile-impl.mk
new file mode 100644
index 0000000..1d398f7
--- /dev/null
+++ b/libs/fsScan/nbproject/Makefile-impl.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=fsScan
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber
+.clobber-impl: .clobber-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+ done
+
+# all
+.all-impl: .all-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+ done
+
+# build tests
+.build-tests-impl: .build-impl .build-tests-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
+
+# run tests
+.test-impl: .build-tests-impl .test-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
+
+# dependency checking support
+.depcheck-impl:
+ @echo "# This code depends on make tool being used" >.dep.inc
+ @if [ -n "${MAKE_VERSION}" ]; then \
+ echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+ echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+ echo "include \$${DEPFILES}" >>.dep.inc; \
+ echo "endif" >>.dep.inc; \
+ else \
+ echo ".KEEP_STATE:" >>.dep.inc; \
+ echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+ fi
+
+# configuration validation
+.validate-impl:
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ echo ""; \
+ echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+ echo "See 'make help' for details."; \
+ echo "Current directory: " `pwd`; \
+ echo ""; \
+ fi
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ exit 1; \
+ fi
+
+
+# help
+.help-impl: .help-pre
+ @echo "This makefile supports the following configurations:"
+ @echo " ${ALLCONFS}"
+ @echo ""
+ @echo "and the following targets:"
+ @echo " build (default target)"
+ @echo " clean"
+ @echo " clobber"
+ @echo " all"
+ @echo " help"
+ @echo ""
+ @echo "Makefile Usage:"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
+ @echo " make [SUB=no] clobber"
+ @echo " make [SUB=no] all"
+ @echo " make help"
+ @echo ""
+ @echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+ @echo " also clean subprojects."
+ @echo "Target 'clobber' will remove all built files from all configurations and,"
+ @echo " unless 'SUB=no', also from subprojects."
+ @echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'help' prints this message."
+ @echo ""
+
diff --git a/libs/fsScan/nbproject/Makefile-variables.mk b/libs/fsScan/nbproject/Makefile-variables.mk
new file mode 100644
index 0000000..e22487e
--- /dev/null
+++ b/libs/fsScan/nbproject/Makefile-variables.mk
@@ -0,0 +1,35 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# Debug configuration
+CND_PLATFORM_Debug=GNU-Linux-x86
+CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86
+CND_ARTIFACT_NAME_Debug=libfsscan.a
+CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/libfsscan.a
+CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Debug=fsScan.tar
+CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/fsScan.tar
+# Release configuration
+CND_PLATFORM_Release=GNU-Linux-x86
+CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
+CND_ARTIFACT_NAME_Release=libfsscan.a
+CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/libfsscan.a
+CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Release=fsScan.tar
+CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/fsScan.tar
+#
+# include compiler specific variables
+#
+# dmake command
+ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
+ (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
+#
+# gmake command
+.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
+#
+include nbproject/private/Makefile-variables.mk
diff --git a/libs/fsScan/nbproject/Package-Debug.bash b/libs/fsScan/nbproject/Package-Debug.bash
new file mode 100644
index 0000000..2a9c453
--- /dev/null
+++ b/libs/fsScan/nbproject/Package-Debug.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+OUTPUT_BASENAME=libfsscan.a
+PACKAGE_TOP_DIR=fsScan/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/fsScan/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/fsScan.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/fsScan.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/fsScan/nbproject/Package-Release.bash b/libs/fsScan/nbproject/Package-Release.bash
new file mode 100644
index 0000000..d996196
--- /dev/null
+++ b/libs/fsScan/nbproject/Package-Release.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libfsscan.a
+OUTPUT_BASENAME=libfsscan.a
+PACKAGE_TOP_DIR=fsScan/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/fsScan/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/fsScan.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/fsScan.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/fsScan/nbproject/configurations.xml b/libs/fsScan/nbproject/configurations.xml
new file mode 100644
index 0000000..a2338c7
--- /dev/null
+++ b/libs/fsScan/nbproject/configurations.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>include/AbstractMedia.h</itemPath>
+ <itemPath>include/AbstractMultiFileMovie.h</itemPath>
+ <itemPath>include/Audio.h</itemPath>
+ <itemPath>include/DVDImage.h</itemPath>
+ <itemPath>include/FilesystemScanner.h</itemPath>
+ <itemPath>include/LegacyVdrRecording.h</itemPath>
+ <itemPath>include/MediaFactory.h</itemPath>
+ <itemPath>include/Movie.h</itemPath>
+ <itemPath>include/Picture.h</itemPath>
+ <itemPath>include/VdrRecording.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/AbstractMedia.cc</itemPath>
+ <itemPath>src/AbstractMultiFileMovie.cc</itemPath>
+ <itemPath>src/Audio.cc</itemPath>
+ <itemPath>src/DVDImage.cc</itemPath>
+ <itemPath>src/FilesystemScanner.cc</itemPath>
+ <itemPath>src/LegacyVdrRecording.cc</itemPath>
+ <itemPath>src/MediaFactory.cc</itemPath>
+ <itemPath>src/Movie.cc</itemPath>
+ <itemPath>src/Picture.cc</itemPath>
+ <itemPath>src/VdrRecording.cc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="TestFiles"
+ displayName="Test Files"
+ projectFiles="false"
+ kind="TEST_LOGICAL_FOLDER">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false"
+ kind="IMPORTANT_FILES_FOLDER">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <ccTool>
+ <incDir>
+ <pElem>include</pElem>
+ <pElem>../networking/include</pElem>
+ <pElem>../util/include</pElem>
+ <pElem>../vdr/include</pElem>
+ </incDir>
+ <commandLine>-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi</commandLine>
+ <preprocessorList>
+ <Elem>_GNU_SOURCE=1</Elem>
+ <Elem>_REENTRANT</Elem>
+ </preprocessorList>
+ <warningLevel>2</warningLevel>
+ </ccTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ </ccTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <asmTool>
+ <developmentMode>5</developmentMode>
+ </asmTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/fsScan/nbproject/private/Makefile-variables.mk b/libs/fsScan/nbproject/private/Makefile-variables.mk
new file mode 100644
index 0000000..a64183e
--- /dev/null
+++ b/libs/fsScan/nbproject/private/Makefile-variables.mk
@@ -0,0 +1,7 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+# Debug configuration
+# Release configuration
diff --git a/libs/fsScan/nbproject/private/configurations.xml b/libs/fsScan/nbproject/private/configurations.xml
new file mode 100644
index 0000000..fa15dc7
--- /dev/null
+++ b/libs/fsScan/nbproject/private/configurations.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/fsScan/nbproject/private/private.xml b/libs/fsScan/nbproject/private/private.xml
new file mode 100644
index 0000000..5ee2703
--- /dev/null
+++ b/libs/fsScan/nbproject/private/private.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+ <data xmlns="http://www.netbeans.org/ns/make-project-private/1">
+ <activeConfTypeElem>3</activeConfTypeElem>
+ <activeConfIndexElem>0</activeConfIndexElem>
+ </data>
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>
diff --git a/libs/fsScan/nbproject/project.xml b/libs/fsScan/nbproject/project.xml
new file mode 100644
index 0000000..a104f65
--- /dev/null
+++ b/libs/fsScan/nbproject/project.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>fsScan</name>
+ <c-extensions/>
+ <cpp-extensions>cc</cpp-extensions>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>Debug</name>
+ <type>3</type>
+ </confElem>
+ <confElem>
+ <name>Release</name>
+ <type>3</type>
+ </confElem>
+ </confList>
+ </data>
+ </configuration>
+</project>
diff --git a/libs/fsScan/src/AbstractMedia.cc b/libs/fsScan/src/AbstractMedia.cc
new file mode 100644
index 0000000..3a3556b
--- /dev/null
+++ b/libs/fsScan/src/AbstractMedia.cc
@@ -0,0 +1,92 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMedia.cc
+ * Created: 2. Juli 2012, 14:33
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <AbstractMedia.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <util.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+cAbstractMedia::cAbstractMedia(cAbstractMedia::SupportedMediaType Type, const char *Name, const char *Logical, const char *Path, const char *Mime)
+ : fd(-1)
+ , mediaType(Type)
+ , logicalPath(Logical ? strdup(Logical) : NULL)
+ , realPath(Path ? strdup(Path) : NULL)
+ , name(Name ? strdup(Name) : NULL)
+ , mimeType(Mime ? strdup(Mime) : NULL)
+ , lastModified(0)
+ , size(0)
+{
+}
+
+cAbstractMedia::~cAbstractMedia()
+{
+ free(logicalPath);
+ free(realPath);
+ free(name);
+ free(mimeType);
+}
+
+void cAbstractMedia::Refresh(void)
+{
+}
+
+size_t cAbstractMedia::ReadChunk(char* Buf, size_t bufSize)
+{
+ long rv = 0;
+
+ if (fd < 1) { // fp stays open between various calls
+ fd = open(RealPath(), O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", RealPath(), errno);
+ return 0;
+ }
+ }
+ isyslog("have filehandle #%d (%s)", fd, RealPath());
+ if ((rv = read(fd, Buf, bufSize)) < 0)
+ esyslog("ERROR: failed to read from file %s #%d", RealPath(), errno);
+ else
+ isyslog("read %u bytes from file", rv);
+ if (rv < (long) bufSize) { // most probabely end of file
+ close(fd);
+ }
+ return rv;
+}
+
+const char *cAbstractMedia::MediaType2Text(int Type)
+{
+ switch(Type) {
+ case Audio: return TO_STRING(Audio);
+ case Movie: return TO_STRING(Movie);
+ case DVDImage: return TO_STRING(DVDImage);
+ case LegacyVdrRecording: return TO_STRING(LegacyVdrRecording);
+ case VdrRecording: return TO_STRING(VdrRecording);
+ case Picture: return TO_STRING(Picture);
+ default: return TO_STRING(Invalid);
+ }
+} \ No newline at end of file
diff --git a/libs/fsScan/src/AbstractMultiFileMovie.cc b/libs/fsScan/src/AbstractMultiFileMovie.cc
new file mode 100644
index 0000000..bcbd115
--- /dev/null
+++ b/libs/fsScan/src/AbstractMultiFileMovie.cc
@@ -0,0 +1,111 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractMultiFileMovie.cc
+ * Created: 3. Juli 2012, 07:39
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <AbstractMultiFileMovie.h>
+#include <Logging.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+cAbstractMultiFileMovie::cAbstractMultiFileMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type)
+ : cMovie(Name, Logical, Path, Mime, Type)
+ , movieFiles(0)
+ , curFileNo(0)
+ , fileNameBuf(NULL)
+ , bufSize(0)
+{
+}
+
+cAbstractMultiFileMovie::~cAbstractMultiFileMovie()
+{
+ free(fileNameBuf);
+}
+
+size_t cAbstractMultiFileMovie::ReadChunk(char* Buf, size_t bufSize)
+{
+ long rv = 0;
+
+ if (fd < 1) {
+ fd = open(FirstFile(), O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", FirstFile(), errno);
+ return 0;
+ }
+ }
+ isyslog("have filehandle #%d (%s)", fd, FirstFile());
+ rv = read(fd, Buf, bufSize);
+
+ if (rv < (long) bufSize) {
+ const char *nextFilename = NextFile();
+
+ if (nextFilename) {
+ close(fd);
+ fd = open(nextFilename, O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", nextFilename, errno);
+ return 0;
+ }
+ isyslog("have filehandle #%d (%s)", fd, nextFilename);
+ rv = read(fd, Buf, bufSize);
+ }
+ if (rv < (long) bufSize) {
+ close(fd);
+ fd = -1;
+ }
+ }
+ return rv;
+}
+
+//int cAbstractMultiFileMovie::ReadBlah(char* buf, size_t bufSize)
+//{
+// size_t bytesRead = 0;
+//
+// if (!fp) {
+// if (!(fp = f open(FirstFile(), "r"))) {
+// //TODO: add some verbose error message?
+// return 0;
+// }
+// }
+//
+// bytesRead = f read(buf, sizeof(char), bufSize, fp);
+//
+// if (bytesRead < bufSize) {
+// const char *nextFilename = NextFile();
+//
+// if (nextFilename) {
+// f close(fp);
+// if (!(fp = f open(nextFilename, "r"))) {
+// //TODO: be verbose
+// return 0;
+// }
+// bytesRead += f read(buf + bytesRead, sizeof(char), bufSize - bytesRead, fp);
+// }
+// if (bytesRead < bufSize) {
+// f close(fp);
+// fp = NULL;
+// }
+// }
+// return bytesRead;
+//}
diff --git a/libs/fsScan/src/Audio.cc b/libs/fsScan/src/Audio.cc
new file mode 100644
index 0000000..25521dc
--- /dev/null
+++ b/libs/fsScan/src/Audio.cc
@@ -0,0 +1,65 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Audio.cc
+ * Created: 2. Juli 2012, 15:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Audio.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cAudio::knownExtensions[] = {
+ { "aac", "audio/aac" },
+ { "aif", "audio/x-aiff" },
+ { "aiff", "audio/x-aiff" },
+ { "aifc", "audio/x-aiff" },
+ { "au", "audio/x-au" },
+ { "fla", "audio/flac" },
+ { "flac", "audio/flac" },
+ { "oga", "audio/ogg" },
+ { "ogg", "audio/ogg" },
+ { "mka", "audio/x-matroska" },
+ { "mp3", "audio/mpeg" },
+ { "mp4", "audio/x-mpeg4" },
+ { "m4a", "audio/x-m4" },
+ { "mpg", "audio/mpeg" },
+ { "mpp", "audio/x-musepack" },
+ { "ram", "audio/x-realaudio" },
+ { NULL, NULL }
+};
+
+cAudio::cAudio(const char *Name, const char *Logical, const char *Path, const char *Mime)
+ : cAbstractMedia(Audio, Name, Logical, Path, Mime)
+{
+}
+
+cAudio::~cAudio()
+{
+}
+
+const char *cAudio::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/DVDImage.cc b/libs/fsScan/src/DVDImage.cc
new file mode 100644
index 0000000..5ffb170
--- /dev/null
+++ b/libs/fsScan/src/DVDImage.cc
@@ -0,0 +1,100 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: DVDImage.cc
+ * Created: 3. Juli 2012, 08:34
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <DVDImage.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "VIDEO_TS/VTS_%02d_%d.VOB"
+
+cDVDImage::cDVDImage(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", DVDImage)
+{
+}
+
+cDVDImage::~cDVDImage()
+{
+}
+
+void cDVDImage::Refresh(void)
+{
+ struct stat stBuf;
+ size_t maxSize = 0;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+ mainMovie = 0;
+
+ for (int movie = 1; movie < 100; ++movie) {
+ total = 0;
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, movie, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ if (total > maxSize) {
+ maxSize = total;
+ mainMovie = movie;
+ }
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cDVDImage::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cDVDImage::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}
diff --git a/libs/fsScan/src/FilesystemScanner.cc b/libs/fsScan/src/FilesystemScanner.cc
new file mode 100644
index 0000000..8377691
--- /dev/null
+++ b/libs/fsScan/src/FilesystemScanner.cc
@@ -0,0 +1,166 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FilesystemScanner.cc
+ * Created: 2. Juli 2012, 13:58
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <FilesystemScanner.h>
+#include <AbstractMedia.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/dir.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <util.h>
+
+void freeMediaCallback(void *elem)
+{
+ delete (cAbstractMedia *)elem;
+}
+
+cFilesystemScanner::cFilesystemScanner()
+ : baseDirectory(NULL)
+ , fileBufSize(512)
+ , dirEntryBuf(NULL)
+ , pool(freeMediaCallback)
+ , mediaFactory(NULL)
+{
+}
+
+cFilesystemScanner::~cFilesystemScanner()
+{
+ FREE(dirEntryBuf);
+ FREE(baseDirectory);
+ pool.clear();
+ if (mediaFactory) delete mediaFactory;
+}
+
+void cFilesystemScanner::SetBaseDirectory(const char* dir)
+{
+ FREE(baseDirectory);
+ baseDirectory = strdup(dir);
+ if (mediaFactory) mediaFactory->SetBaseDirectory(dir);
+}
+
+void cFilesystemScanner::SetMediaFactory(cMediaFactory* factory)
+{
+ if ((mediaFactory = factory)) {
+ FREE(baseDirectory);
+ baseDirectory = strdup(mediaFactory->BaseDirectory());
+ }
+}
+
+// return true if a should be ordered before b
+bool defaultMediaSortOrder(void *a, void *b)
+{
+ if (!a && !b) return true;
+ if (!a && b) return false;
+ if (a && !b) return true;
+ cAbstractMedia *m0 = (cAbstractMedia *)a;
+ cAbstractMedia *m1 = (cAbstractMedia *)b;
+ bool rv = (m0->MediaType() - m1->MediaType()) < 0;
+
+ if (!rv) rv = strcmp(m0->Name(), m1->Name());
+
+ return rv;
+}
+
+void cFilesystemScanner::Refresh()
+{
+ if (!mediaFactory) return;
+ pool.clear();
+ categories.clear();
+ dirEntryBuf = (struct dirent *)malloc(sizeof(struct dirent));
+ if (!dirEntryBuf) {
+ esyslog("ERROR: out of memory!");
+ return;
+ }
+ parseDir(baseDirectory, pool);
+ FREE(dirEntryBuf);
+#ifdef REDNOSE
+ pool.sort(defaultMediaSortOrder);
+#else
+ pool.sort(NULL);
+#endif
+ cAbstractMedia::SupportedMediaType ot = cAbstractMedia::Invalid;
+ cAbstractMedia *m;
+
+ for (size_t i=0; i < pool.size(); ++i) {
+ m = (cAbstractMedia *) pool[i];
+ if (m->MediaType() != ot) {
+ ot = m->MediaType();
+ categories[ot] = i;
+ }
+ }
+}
+
+void cFilesystemScanner::parseDir(const char* dirName, cManagedVector &result)
+{
+ if (!mediaFactory) return;
+ DIR *dir = opendir(dirName);
+ cAbstractMedia *media;
+ char *pathBuf = (char *)malloc(fileBufSize);
+ struct dirent *dirEntry;
+ struct stat statBuf;
+
+ if (!dir) return;
+ if (!pathBuf) {
+ closedir(dir);
+ return;
+ }
+ if (fileBufSize < strlen(dirName) + 128) {
+ fileBufSize += 256;
+ pathBuf = (char *)realloc(pathBuf, fileBufSize);
+ }
+ while (!readdir_r(dir, dirEntryBuf, &dirEntry) && dirEntry) {
+ if (*dirEntry->d_name == '.') continue; // don't bother with hidden stuff
+ strcpy(pathBuf, dirName);
+ strcat(pathBuf, "/");
+ strcat(pathBuf, dirEntry->d_name);
+ if (stat(pathBuf, &statBuf) < 0) return;
+ if ((media = mediaFactory->CreateMedia(pathBuf, &statBuf))) {
+ result.push_back(media);
+ isyslog("found media %s - %s", media->MimeType(), media->LogicalPath());
+ continue;
+ }
+ if ((statBuf.st_mode & S_IFMT) == S_IFDIR) parseDir(pathBuf, result);
+ }
+ closedir(dir);
+ FREE(pathBuf);
+}
+
+cAbstractMedia *cFilesystemScanner::FindMedia(const char* LogicalPath)
+{
+ cAbstractMedia *rv = NULL, *tmp;
+
+ for (size_t i=0; i < pool.size(); ++i) {
+ tmp = (cAbstractMedia *) pool[i];
+ if (!strcmp(tmp->LogicalPath(), LogicalPath)) {
+ rv = tmp;
+ break;
+ }
+ }
+ return rv;
+} \ No newline at end of file
diff --git a/libs/fsScan/src/LegacyVdrRecording.cc b/libs/fsScan/src/LegacyVdrRecording.cc
new file mode 100644
index 0000000..ea2ed35
--- /dev/null
+++ b/libs/fsScan/src/LegacyVdrRecording.cc
@@ -0,0 +1,91 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: LegacyVdrRecording.cc
+ * Created: 3. Juli 2012, 08:16
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <LegacyVdrRecording.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "/%03d.vdr"
+
+cLegacyVdrRecording::cLegacyVdrRecording(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", LegacyVdrRecording)
+{
+}
+
+cLegacyVdrRecording::~cLegacyVdrRecording()
+{
+}
+
+void cLegacyVdrRecording::Refresh(void)
+{
+ struct stat stBuf;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cLegacyVdrRecording::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cLegacyVdrRecording::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}
diff --git a/libs/fsScan/src/MediaFactory.cc b/libs/fsScan/src/MediaFactory.cc
new file mode 100644
index 0000000..a94fbb1
--- /dev/null
+++ b/libs/fsScan/src/MediaFactory.cc
@@ -0,0 +1,137 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: MediaFactory.cc
+ * Created: 2. Juli 2012, 15:43
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <MediaFactory.h>
+#include <Audio.h>
+#include <Movie.h>
+#include <Picture.h>
+#include <LegacyVdrRecording.h>
+#include <VdrRecording.h>
+#include <DVDImage.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+cMediaFactory::cMediaFactory(const char *BaseDirectory)
+ : baseDirectory(BaseDirectory ? strdup(BaseDirectory) : NULL)
+ , scratch(NULL)
+ , scratchSize(1024)
+{
+ if (baseDirectory && *(baseDirectory + strlen(baseDirectory) - 1) == '/')
+ *(baseDirectory + strlen(baseDirectory) - 1) = 0;
+ scratch = (char *)malloc(scratchSize);
+}
+
+cMediaFactory::~cMediaFactory()
+{
+ free(scratch);
+ free(baseDirectory);
+}
+
+void cMediaFactory::SetBaseDirectory(const char* dir)
+{
+ if (baseDirectory == dir) return;
+ char *tmp = baseDirectory;
+ baseDirectory = NULL;
+ free(tmp);
+ if (dir) {
+ baseDirectory = strdup(dir);
+ if (*(baseDirectory + strlen(baseDirectory) - 1) == '/')
+ *(baseDirectory + strlen(baseDirectory) - 1) = 0;
+ }
+}
+
+cAbstractMedia *cMediaFactory::CreateMedia(const char* FileOrDirname, struct stat *st)
+{
+ const char *name = rindex(FileOrDirname, '/') + 1;
+ const char *logical = FileOrDirname + strlen(baseDirectory);
+ const char *mimeType = NULL;
+ cAbstractMedia *rv = NULL;
+
+// printf("CreateMedia(%s) ... name=[%s], logical=[%s]\n", FileOrDirname, name, logical);
+ if ((st->st_mode & S_IFMT) == S_IFDIR) {
+ static const char *addons[] = { "/001.vdr", "/00001.ts", "/VIDEO_TS/VIDEO_TS.IFO", "/video_ts/VIDEO_TS.IFO", "/video_ts/video_ts.ifo", NULL };
+ struct stat stBuf;
+ int n=0;
+
+ if (scratchSize < (strlen(FileOrDirname) + 32)) {
+ scratchSize += 128;
+ scratch = (char *)realloc(scratch, scratchSize);
+ }
+ if (!scratch) return NULL;
+
+ for (const char **pa = addons; pa && *pa; ++pa, ++n) {
+ strcpy(scratch, FileOrDirname);
+ strcat(scratch, *pa);
+
+ if (stat(scratch, &stBuf) < 0) continue;
+
+ if ((stBuf.st_mode & S_IFMT) == S_IFREG) {
+ if (n < 2) {
+ char *tmp = rindex(scratch, '/'); // filename
+ char *p = tmp;
+
+ *p = ')';
+ *(p + 2) = 0;
+ tmp = rindex(scratch, '/'); // ts-directory
+
+ for (; p > tmp; --p) *(p + 1) = *p; // shift it up one position
+ *(p + 1) = '('; // start of ts-directory
+ *tmp = ' '; // add separator
+ tmp = rindex(scratch, '/'); // name of vdr recording
+ if (tmp) name = tmp + 1;
+ }
+ switch (n) {
+ case 0: rv = new cLegacyVdrRecording(name, logical, FileOrDirname); break;
+ case 1: rv = new cVdrRecording(name, logical, FileOrDirname); break;
+ default: rv = new cDVDImage(name, logical, FileOrDirname); break;
+ }
+ rv->SetLastModified(st->st_mtime);
+ }
+ }
+ }
+ else if ((st->st_mode & S_IFMT) == S_IFREG) {
+ const char *extension = rindex(FileOrDirname, '.');
+
+ if (!extension) return NULL;
+ ++extension;
+
+ mimeType = cMovie::ContentType(extension);
+ if (mimeType) rv = new cMovie(name, logical, FileOrDirname, mimeType);
+ else {
+ mimeType = cAudio::ContentType(extension);
+ if (mimeType) rv = new cAudio(name, logical, FileOrDirname, mimeType);
+ else {
+ mimeType = cPicture::ContentType(extension);
+ if (mimeType) rv = new cPicture(name, logical, FileOrDirname, mimeType);
+ }
+ }
+ if (rv) {
+ rv->SetLastModified(st->st_mtime);
+ rv->SetSize(st->st_size);
+ }
+ }
+ return rv;
+} \ No newline at end of file
diff --git a/libs/fsScan/src/Movie.cc b/libs/fsScan/src/Movie.cc
new file mode 100644
index 0000000..a558f81
--- /dev/null
+++ b/libs/fsScan/src/Movie.cc
@@ -0,0 +1,61 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Movie.cc
+ * Created: 2. Juli 2012, 15:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Movie.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cMovie::knownExtensions[] = {
+ { "asd", "video/x-ms-asf" },
+ { "asf", "video/x-ms-asf" },
+ { "avi", "video/x-msvideo" },
+ { "dv", "video/x-dv" },
+ { "flv", "video/x-flv" },
+ { "gl", "video/x-gl" },
+ { "iso", "application/x-iso9660-image" },
+ { "ogv", "video/ogg" },
+ { "mkv", "video/x-matroska" },
+ { "mov", "video/quicktime" },
+ { "mpeg", "video/mpeg" },
+ { "swf", "application/x-shockwave-flash" },
+ { NULL, NULL }
+};
+
+cMovie::cMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type)
+ : cAbstractMedia(Type, Name, Logical, Path, Mime)
+{
+}
+
+cMovie::~cMovie()
+{
+}
+
+const char *cMovie::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/Picture.cc b/libs/fsScan/src/Picture.cc
new file mode 100644
index 0000000..3c44ce6
--- /dev/null
+++ b/libs/fsScan/src/Picture.cc
@@ -0,0 +1,69 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Picture.cc
+ * Created: 2. Juli 2012, 15:18
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Picture.h>
+#include <stddef.h>
+#include <string.h>
+
+SupportedExtension cPicture::knownExtensions[] = {
+ { "bmp", "image/x-windows-bmp" },
+ { "gif", "image/gif" },
+ { "jff", "image/jpeg" },
+ { "jfif", "image/jpeg" },
+ { "jif", "image/jpeg" },
+ { "jp2", "image/jp2" },
+ { "jpe", "image/jpeg" },
+ { "jpeg", "image/jpeg" },
+ { "jpg", "image/jpeg" },
+ { "jpm", "image/jpm" },
+ { "jpx", "image/jpx" },
+ { "pbm", "image/x-portable-bitmap" },
+ { "pct", "image/x-pict" },
+ { "pcx", "image/x-pcx" },
+ { "png", "image/png" },
+ { "pnm", "image/x-portable-anymap" },
+ { "ppm", "image/x-portable-pixmap" },
+ { "qti", "image/quicktime" },
+ { "ras", "image/x-cmu-raster" },
+ { "rgb", "image/x-rgb" },
+ { NULL, NULL }
+};
+
+cPicture::cPicture(const char *Name, const char *Logical, const char *Path, const char *Mime)
+: cAbstractMedia(Picture, Name, Logical, Path, Mime)
+{
+}
+
+cPicture::~cPicture()
+{
+}
+
+const char *cPicture::ContentType(const char* Extension)
+{
+ for (SupportedExtension *p = knownExtensions; p && p->extension; ++p) {
+ if (!strcasecmp(p->extension, Extension)) return p->mimeType;
+ }
+ return NULL;
+}
+
diff --git a/libs/fsScan/src/VdrRecording.cc b/libs/fsScan/src/VdrRecording.cc
new file mode 100644
index 0000000..f706477
--- /dev/null
+++ b/libs/fsScan/src/VdrRecording.cc
@@ -0,0 +1,91 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: VdrRecording.cc
+ * Created: 3. Juli 2012, 08:30
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libfsScan: mediatypes and filesystem scanning
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <VdrRecording.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define FILE_MASK "/%05d.ts"
+
+cVdrRecording::cVdrRecording(const char *Name, const char *Logical, const char *Path)
+ : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", VdrRecording)
+{
+}
+
+cVdrRecording::~cVdrRecording()
+{
+}
+
+void cVdrRecording::Refresh(void)
+{
+ struct stat stBuf;
+ size_t total = 0;
+ time_t lastMod = 0;
+
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) {
+ //TODO: some error message?
+ return;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ movieFiles = 0;
+
+ for (int fileNo = 1;; ++fileNo) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo);
+ if (stat(fileNameBuf, &stBuf) < 0) {
+ movieFiles = fileNo - 1;
+ break;
+ }
+ total += stBuf.st_size;
+ if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime;
+ }
+ SetSize(total);
+ SetLastModified(lastMod);
+}
+
+const char *cVdrRecording::FirstFile(void)
+{
+ if (!fileNameBuf) {
+ if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 16))) {
+ //TODO: some error message?
+ return NULL;
+ }
+ strcpy(fileNameBuf, RealPath());
+ }
+ curFileNo = 1;
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+}
+
+const char *cVdrRecording::NextFile(void)
+{
+ if (++curFileNo < movieFiles) {
+ sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo);
+
+ return fileNameBuf;
+ }
+ return NULL;
+}
diff --git a/libs/fsScan/summary.txt b/libs/fsScan/summary.txt
new file mode 100644
index 0000000..0247690
--- /dev/null
+++ b/libs/fsScan/summary.txt
@@ -0,0 +1 @@
+libfsScan: mediatypes and filesystem scanning
diff --git a/libs/networking/.dep.inc b/libs/networking/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/libs/networking/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/libs/networking/Makefile b/libs/networking/Makefile
new file mode 100644
index 0000000..ec9de69
--- /dev/null
+++ b/libs/networking/Makefile
@@ -0,0 +1,128 @@
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# Available make variables:
+#
+# CND_BASEDIR base directory for relative paths
+# CND_DISTDIR default top distribution directory (build artifacts)
+# CND_BUILDDIR default top build directory (object files, ...)
+# CONF name of current configuration
+# CND_PLATFORM_${CONF} platform name (current configuration)
+# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
+# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
+# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
+# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
+# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
+# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
+#
+# NOCDDL
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+
+
+# build
+build: .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post: .build-impl
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post: .clean-impl
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+# build tests
+build-tests: .build-tests-post
+
+.build-tests-pre:
+# Add your pre 'build-tests' code here...
+
+.build-tests-post: .build-tests-impl
+# Add your post 'build-tests' code here...
+
+
+# run tests
+test: .test-post
+
+.test-pre:
+# Add your pre 'test' code here...
+
+.test-post: .test-impl
+# Add your post 'test' code here...
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
+
+# include project make variables
+include nbproject/Makefile-variables.mk
diff --git a/libs/networking/include/AbstractSocket.h b/libs/networking/include/AbstractSocket.h
new file mode 100644
index 0000000..ff76f52
--- /dev/null
+++ b/libs/networking/include/AbstractSocket.h
@@ -0,0 +1,63 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractSocket.h
+ * Created: 4. Juli 2012, 07:13
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef ABSTRACTSOCKET_H
+#define ABSTRACTSOCKET_H
+
+#include <ConnectionPoint.h>
+#include <sys/socket.h>
+
+class cAbstractSocket {
+public:
+ virtual ~cAbstractSocket();
+ const cConnectionPoint *ThisSide(void) const { return thisSide; }
+ const cConnectionPoint *OtherSide(void) const { return others[0]; }
+ cConnectionPoint *ThisSide(void) { return thisSide; }
+ cConnectionPoint *OtherSide(void) { return others[0]; }
+ virtual void ConfigureSocket(int Socket) {}
+
+protected:
+ cAbstractSocket(int Port, int Queue = 1);
+ cAbstractSocket(const char *ServerName, int Port);
+ bool Connect();
+ bool Open(int Port);
+ cConnectionPoint *Accept(int Port, int TimeoutMs = -1);
+ bool ForceBlockingIO(void) const { return blocking; }
+ void SetBlockingIO(bool ForceBlockingIO = true);
+ cConnectionPoint *GetNameAndAddress(int Socket, struct sockaddr *sa, socklen_t sa_size);
+ void Close(void);
+
+private:
+ int sock;
+ int queue;
+ bool blocking;
+ cConnectionPoint *thisSide;
+ ConnectionPointList others; ///< client sockets have only one other side,
+ ///< but server sockets can have multiple connections open at the same time,
+ ///< so we probabely need a container here.
+ // cConnectionPointInfo *FetchLocalInfo(int Socket, struct addrinfo *AI);
+ };
+
+#endif /* ABSTRACTSOCKET_H */
+
diff --git a/libs/networking/include/Authorization.h b/libs/networking/include/Authorization.h
new file mode 100644
index 0000000..fa04bd4
--- /dev/null
+++ b/libs/networking/include/Authorization.h
@@ -0,0 +1,115 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Authorization.h
+ * Created: 3. Juli 2012, 17:27
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef AUTHORIZATION_H
+#define AUTHORIZATION_H
+
+#include <HTTPRequest.h>
+#include <Principal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <time.h>
+#include <ManagedVector.h>
+
+class cAuthorization {
+public:
+ cAuthorization(const cHTTPRequest &OriginalRequest, char *NOnceFromHeap);
+ cAuthorization(cHTTPRequest::HTTPRequestMethod Method, const char *Raw);
+ cAuthorization(const cAuthorization &other);
+ cAuthorization(const cPrincipal *Principal, cHTTPRequest::HTTPRequestMethod Method, const cAuthorization &other);
+ virtual ~cAuthorization();
+ cAuthorization &operator =(const cAuthorization &other);
+ size_t Write(char *Buffer, size_t BufSize);
+ const char *CalculateResponse(const char *Uri = NULL, const char *Username = NULL, const char *Password = NULL);
+ void Dump(void) const;
+ const char *Uri(void) const { return uri; }
+ const char *Response(void) const { return response; }
+ const char *CNOnce(void) const { return cnonce; }
+ const char *NOnce(void) const { return nonce; }
+ const char *Opaque(void) const { return opaque; }
+ const char *UserID(void) const {
+ if (principal) return principal->Name();
+ else if (tmp) return tmp->Name();
+ return NULL;
+ }
+ const char *UserCredential(void) const {
+ if (principal) return principal->Hash();
+ else if (tmp) return tmp->Hash();
+ return NULL;
+ }
+ const char *Realm(void) const {
+ if (principal) return principal->Realm();
+ else if (tmp) return tmp->Realm();
+ return NULL;
+ }
+ void SetUser(const char *UserID, const char *Password);
+ char *CalculateA1(const char *Username = NULL, const char *Password = NULL);
+ char *CalculateA2(const char *Uri);
+
+protected:
+ virtual void ParseRawBuffer(const char *Raw);
+ virtual void CreateClientHash();
+ const cPrincipal *Principal(void) const { return principal; }
+ void SetAttribute(char *Name, const char *Value);
+ void SetOpaque(char *Value);
+ void SetPrincipal(const cPrincipal *Principal) { principal = Principal; }
+
+private:
+ void SetServerID(const char *ServerID) { free(serverID); serverID = ServerID ? strdup(ServerID) : NULL; }
+ void SetUri(const char *Uri) { free(uri); uri = Uri ? strdup(Uri) : NULL; }
+ cPrincipal *tmp;
+ const cPrincipal *principal;
+ cHTTPRequest::HTTPRequestMethod method;
+ char *serverID;
+ bool sessAlgo;
+ char *nonce;
+ char *uri;
+ char *response;
+ char *opaque;
+ char *cnonce;
+ char *qop;
+ int counter;
+ time_t authTime;
+ friend class cHTTPResponse;
+ friend class cHTTPRequest;
+ friend class cAuthorizations;
+ friend class cConnectionHandler;
+ };
+
+class cConnectionPoint;
+class cAuthorizations : public cManagedVector {
+public:
+ cAuthorizations();
+ virtual ~cAuthorizations();
+
+ cAuthorization *FindAuthorization(const char *SessionID);
+ void Del(cAuthorization *Auth2Invalidate);
+ const cAuthorization &CreateAuthorization(const cHTTPRequest &OriginalRequest, const cConnectionPoint &client, unsigned long connectionNumber);
+ static char *CreateNOnce(const cConnectionPoint &client, unsigned long connectionNumber);
+ static char *CreateSessionID(const cHTTPRequest &OriginalRequest, time_t AuthTime);
+ };
+
+#endif /* AUTHORIZATION_H */
+
diff --git a/libs/networking/include/ClientSocket.h b/libs/networking/include/ClientSocket.h
new file mode 100644
index 0000000..0dc899e
--- /dev/null
+++ b/libs/networking/include/ClientSocket.h
@@ -0,0 +1,39 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ClientSocket.h
+ * Created: 4. Juli 2012, 07:25
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef CLIENTSOCKET_H
+#define CLIENTSOCKET_H
+
+#include <AbstractSocket.h>
+
+class cClientSocket : public cAbstractSocket {
+public:
+ cClientSocket(const char *serverName, int Port);
+ virtual ~cClientSocket();
+ bool Connect(void);
+ void Close(void);
+ };
+
+#endif /* CLIENTSOCKET_H */
+
diff --git a/libs/networking/include/ConnectionHandler.h b/libs/networking/include/ConnectionHandler.h
new file mode 100644
index 0000000..c4232be
--- /dev/null
+++ b/libs/networking/include/ConnectionHandler.h
@@ -0,0 +1,77 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ConnectionHandler.h
+ * Created: 4. Juli 2012, 07:32
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef CONNECTIONHANDLER_H
+#define CONNECTIONHANDLER_H
+
+#include <Thread.h>
+#include <ServerConfig.h>
+#include <sys/types.h>
+
+class cConnectionPoint;
+class cAuthorization;
+class cHTTPResponse;
+class cHTTPRequest;
+class cFileHandler;
+class cHTTPRequestHandler;
+class cStringBuilder;
+class cConnectionHandler : public cThread {
+public:
+ cConnectionHandler(cConnectionPoint &Client, cServerConfig &Config, bool StayConnected = false);
+ virtual ~cConnectionHandler();
+
+ void Action(void);
+
+ bool AuthorizationRequired(void) { return config.AuthorizationRequired(); }
+ const char *NOnce(void) const { return nonce; }
+ bool StayConnected(void) const { return stayConnected; }
+ virtual void Cancel(int WaitSeconds = 0);
+
+ static void RegisterRequestHandler(const char *UrlPrefix, cHTTPRequestHandler *CommandHandler);
+ static void RegisterDefaultHandler(cHTTPRequestHandler *DefaultHandler);
+ static void Cleanup(void);
+
+protected:
+ cAuthorizations &Authorizations(void) { return config.authorizations; }
+ cServerSocket &ServerSocket(void) { return config.server; }
+ cHTTPResponse *ProcessRequest(cHTTPRequest &Request);
+ void TransferResponse(cHTTPResponse *Response);
+ void SetNonce(char *NOnce) { nonce = NOnce; }
+ bool IsAuthorizationValid(cAuthorization *ServerAuth, const cHTTPRequest &request);
+ void Usage(cStringBuilder &sb);
+
+private:
+ void Init(void);
+ cServerConfig &config;
+ cConnectionPoint &client;
+ unsigned long connectionNumber;
+ size_t bufSize;
+ char *scratch;
+ char *nonce;
+ bool stayConnected;
+ friend class cTestUnit;
+ };
+
+#endif /* CONNECTIONHANDLER_H */
+
diff --git a/libs/networking/include/ConnectionPoint.h b/libs/networking/include/ConnectionPoint.h
new file mode 100644
index 0000000..8980adb
--- /dev/null
+++ b/libs/networking/include/ConnectionPoint.h
@@ -0,0 +1,60 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ConnectionPoint.h
+ * Created: 4. Juli 2012, 06:29
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef CONNECTIONPOINT_H
+#define CONNECTIONPOINT_H
+
+#include <stddef.h>
+#include <vector>
+
+class cConnectionPoint {
+public:
+ cConnectionPoint(const char *NameOrIP, int Port, const char *RealName = NULL);
+ virtual ~cConnectionPoint();
+
+ int IOWait(long MilliSeconds = 300);
+ const char *HostName(void) const { return nameOrIP; }
+ const char *RealName(void) const { return realName ? realName : "unknown"; }
+ const char *ToString() const { return combined ? combined : AssembleCombined(); }
+ int Port(void) const { return port; }
+ int Socket(void) const { return sock; }
+
+private:
+ char *nameOrIP;
+ char *realName;
+ mutable char *combined;
+ int port;
+ int sock;
+ const char *AssembleCombined(void) const;
+ void Close(void);
+ void SetSocket(int Socket) { sock = Socket; }
+ void SetRealName(const char *Name);
+ friend class cAbstractSocket;
+ friend class cConnectionHandler;
+ };
+
+typedef std::vector<cConnectionPoint *> ConnectionPointList;
+
+#endif /* CONNECTIONPOINT_H */
+
diff --git a/libs/networking/include/Credentials.h b/libs/networking/include/Credentials.h
new file mode 100644
index 0000000..c27532d
--- /dev/null
+++ b/libs/networking/include/Credentials.h
@@ -0,0 +1,61 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Credentials.h
+ * Created: 3. Juli 2012, 14:37
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef CREDENTIALS_H
+#define CREDENTIALS_H
+
+#include <Principal.h>
+#include <string>
+#include <tr1/unordered_map>
+
+class cCredentials {
+public:
+ typedef std::tr1::unordered_map<std::string, cPrincipal *>::const_iterator const_iterator;
+ cCredentials();
+ virtual ~cCredentials();
+
+ const cPrincipal *FindPrincipal(const char *Name, const char *Realm);
+ const char *ApplicationRealm(void) const;
+ void SetApplicationRealm(const char *ApplicationRealm = "knownUser@myApp");
+
+ int Load(const char *FileName);
+ int Store(const char *FileName);
+
+ void Put(const char *Key, cPrincipal *p);
+ cPrincipal *Get(const char *Key);
+ void Clear(void);
+
+ const_iterator begin() { return internalMap.begin(); }
+ const_iterator end() { return internalMap.end(); }
+
+private:
+ cPrincipal *parsePrincipal(char *buf, size_t bufSize);
+ std::tr1::unordered_map<std::string, cPrincipal *> internalMap;
+ typedef std::tr1::unordered_map<std::string, cPrincipal *>::iterator iterator;
+ };
+
+extern cCredentials Credentials;
+
+#endif /* CREDENTIALS_H */
+
diff --git a/libs/networking/include/HTTPAuthorizationRequest.h b/libs/networking/include/HTTPAuthorizationRequest.h
new file mode 100644
index 0000000..d3d566d
--- /dev/null
+++ b/libs/networking/include/HTTPAuthorizationRequest.h
@@ -0,0 +1,41 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPAuthorizationRequest.h
+ * Created: 4. Juli 2012, 07:41
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPAUTHORIZATIONREQUEST_H
+#define HTTPAUTHORIZATIONREQUEST_H
+
+#include <HTTPResponse.h>
+
+class cHTTPRequest;
+class cHTTPAuthorizationRequest : public cHTTPResponse {
+///< the server requires authorization, so the message is a response
+///< The clients response is another (repeated) request with authentication headers
+public:
+ cHTTPAuthorizationRequest(const cHTTPRequest &OriginalRequest, char *NOnceFromHeap);
+ cHTTPAuthorizationRequest(const cAuthorization &Authorization);
+ virtual ~cHTTPAuthorizationRequest();
+ };
+
+#endif /* HTTPAUTHORIZATIONREQUEST_H */
+
diff --git a/libs/networking/include/HTTPFileResponse.h b/libs/networking/include/HTTPFileResponse.h
new file mode 100644
index 0000000..0457850
--- /dev/null
+++ b/libs/networking/include/HTTPFileResponse.h
@@ -0,0 +1,48 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPFileResponse.h
+ * Created: 4. Juli 2012, 07:50
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPFILERESPONSE_H
+#define HTTPFILERESPONSE_H
+
+#include <HTTPResponse.h>
+
+class cHTTPFileResponse : public cHTTPResponse {
+public:
+ cHTTPFileResponse(const char *RealPath);
+ virtual ~cHTTPFileResponse();
+ const char *RealPath(void) const { return realPath; }
+
+ virtual size_t ReadContentChunk(char *Buf, size_t bufSize);
+
+protected:
+ cHTTPFileResponse();
+
+private:
+ void DetermineTypeAndSize(const char *Path);
+ const char *realPath;
+ int fd;
+ };
+
+#endif /* HTTPFILERESPONSE_H */
+
diff --git a/libs/networking/include/HTTPMessage.h b/libs/networking/include/HTTPMessage.h
new file mode 100644
index 0000000..cb88c69
--- /dev/null
+++ b/libs/networking/include/HTTPMessage.h
@@ -0,0 +1,92 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPMessage.h
+ * Created: 3. Juli 2012, 17:40
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPMESSAGE_H
+#define HTTPMESSAGE_H
+
+#define MT_Html "text/html"
+
+#include <ManagedMap.h>
+
+class cAuthorization;
+class cHTTPMessage {
+public:
+ typedef enum { Unknown, HTTP_1_0, HTTP_1_1 } HTTPProtocol;
+
+ cHTTPMessage(HTTPProtocol Proto=HTTP_1_1);
+ virtual ~cHTTPMessage();
+
+ HTTPProtocol Protocol(void) { return protocol; }
+ const char *ProtocolString(void);
+ const char *ContentType(void) const { return contentType; }
+ virtual size_t ContentSize(void) const;
+ const char *GetHeader(const char *Name) const;
+ const cAuthorization *Authorization(void) const { return auth; }
+ void SetAuthorization(cAuthorization *Authorization);
+ size_t WritePrefix(char *Buffer, size_t BufSize); ///< writes message header, so content will follow
+ virtual void Dump(void);
+
+protected:
+ enum ParseState {
+ ExpectFormat
+ , ExpectURL
+ , ExpectProtocol
+ , ExpectStatus
+ , ExpectHeader
+ , ExpectContent
+ };
+ enum ParseResult {
+ UnknownError
+ , UnsupportedFormat
+ , InvalidURL
+ , InvalidName
+ , UnsupportedProtocol
+ , Continue
+ , Done
+ };
+ virtual size_t WriteFirstLine(char *Buffer, size_t BufSize) = 0;
+ virtual void SetContentType(const char *ContentType);
+ virtual void SetContentSize(size_t ContentSize) { contentSize = ContentSize; }
+ void SetHeader(const char *Name, const char *Value);
+ void SetProtocol(HTTPProtocol Protocol) { protocol = Protocol; }
+ cAuthorization *Authorization(void) { return auth; }
+ char *FormatTime(time_t time);
+ const cManagedMap &Headers() const { return header; }
+ int WriteTime(char *Buffer, size_t BufSize);
+ void Reset(void);
+
+private:
+ HTTPProtocol protocol;
+ time_t timeStamp;
+ cManagedMap header;
+ cAuthorization *auth;
+ size_t contentSize;
+ char *contentType;
+ friend class cMediaListHandler;
+ friend class cConnectionHandler;
+ friend class cTestUnit;
+ };
+
+#endif /* HTTPMESSAGE_H */
+
diff --git a/libs/networking/include/HTTPParser.h b/libs/networking/include/HTTPParser.h
new file mode 100644
index 0000000..9ed8169
--- /dev/null
+++ b/libs/networking/include/HTTPParser.h
@@ -0,0 +1,47 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPParser.h
+ * Created: 10. Juli 2012, 08:37
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPPARSER_H
+#define HTTPPARSER_H
+
+class cHTTPMessage;
+class cHTTPRequest;
+class cHTTPResponse;
+class cHTTPParser
+{
+public:
+ cHTTPParser();
+ virtual ~cHTTPParser();
+
+ cHTTPMessage *ParseMessage(const char *MessageBuf);
+
+protected:
+ cHTTPRequest *parseRequest(const char *MessageBuf);
+ cHTTPResponse *parseResponse(const char *MessageBuf);
+
+private:
+};
+
+#endif /* HTTPPARSER_H */
+
diff --git a/libs/networking/include/HTTPRequest.h b/libs/networking/include/HTTPRequest.h
new file mode 100644
index 0000000..87c78d7
--- /dev/null
+++ b/libs/networking/include/HTTPRequest.h
@@ -0,0 +1,62 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPRequest.h
+ * Created: 3. Juli 2012, 17:54
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPREQUEST_H
+#define HTTPREQUEST_H
+
+#include <HTTPMessage.h>
+#include <Url.h>
+
+class cHTTPResponse;
+class cHTTPRequest : public cHTTPMessage {
+///< a message sent from client to server to access a certain resource
+public:
+ typedef enum { INVALID, GET, POST } HTTPRequestMethod;
+ cHTTPRequest(const char *MessageBuf);
+ cHTTPRequest(HTTPRequestMethod Format, const char *Url);
+ cHTTPRequest(const cHTTPResponse &res, const char *Url);
+ virtual ~cHTTPRequest();
+ HTTPRequestMethod Method(void) const { return method; }
+ const cUrl &Url() const { return url; }
+ cUrl &Url() { return url; }
+ const char *UserAgent() const;
+ const char *ClientHost(void) const;
+ void SetUser(const char *UserID, const char *Password);
+
+protected:
+ void SetMethod(HTTPRequestMethod Method) { method = Method; }
+ void SetURL(const char *Url);
+ virtual size_t WriteFirstLine(char *Buffer, size_t BufSize);
+ void ParseMessage(const char *MessageBuf);
+
+private:
+ HTTPRequestMethod method;
+ cUrl url;
+ friend class HTTPParser;
+ };
+
+extern const char *requestMethod2String(cHTTPRequest::HTTPRequestMethod Method);
+
+#endif /* HTTPREQUEST_H */
+
diff --git a/libs/networking/include/HTTPRequestHandler.h b/libs/networking/include/HTTPRequestHandler.h
new file mode 100644
index 0000000..99c31d2
--- /dev/null
+++ b/libs/networking/include/HTTPRequestHandler.h
@@ -0,0 +1,48 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPRequestHandler.h
+ * Created: 4. Juli 2012, 15:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPREQUESTHANDLER_H
+#define HTTPREQUESTHANDLER_H
+
+class cHTTPRequest;
+class cHTTPResponse;
+class cStringBuilder;
+class cHTTPRequestHandler {
+public:
+ cHTTPRequestHandler();
+ virtual ~cHTTPRequestHandler();
+
+ virtual cHTTPResponse *ProcessRequest(cHTTPRequest &Request) = 0;
+ virtual void Usage(cStringBuilder &sb) = 0;
+
+ const char *ID() const { return prefix; }
+
+private:
+ void SetID(const char *UrlPrefix);
+ char *prefix;
+ friend class cHTTPRequestHandlers;
+ };
+
+#endif /* HTTPREQUESTHANDLER_H */
+
diff --git a/libs/networking/include/HTTPResponse.h b/libs/networking/include/HTTPResponse.h
new file mode 100644
index 0000000..afa4ae5
--- /dev/null
+++ b/libs/networking/include/HTTPResponse.h
@@ -0,0 +1,73 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPResponse.h
+ * Created: 4. Juli 2012, 06:03
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPRESPONSE_H
+#define HTTPRESPONSE_H
+
+#define MT_Unknown "unsupported/unknown"
+#define MT_CSS "text/css"
+#define MT_JavaScript "application/javascript"
+#define MT_Gif "image/gif"
+#define MT_Png "image/png"
+#define MT_Ico "image/x-icon"
+#define MT_Jpg "image/jpeg"
+#define MT_Xml "application/xml"
+#define MT_XmlDtd "application/xml-dtd"
+
+#include <HTTPStatus.h>
+#include <HTTPMessage.h>
+#include <StringBuilder.h>
+
+class cHTTPResponse : public cHTTPMessage {
+public:
+ cHTTPResponse(HTTPStatusCode Status = HTTP_OK);
+ ///< server side creates a response by status code
+ cHTTPResponse(const char *Buffer);
+ ///< client side creates a response from receiving buffer
+ virtual ~cHTTPResponse();
+
+ HTTPStatusCode Status(void) const { return status; }
+ virtual size_t ContentSize(void) const;
+ virtual void SetContentType(const char *ContentType) { cHTTPMessage::SetContentType(ContentType); }
+ virtual void SetContentSize(size_t ContentSize) { cHTTPMessage::SetContentSize(ContentSize); }
+ cStringBuilder &StringBuilder(void) { return content; }
+
+ static const char *ServerID(void);
+ static void SetServerID(const char *ServerID);
+
+protected:
+ virtual size_t WriteFirstLine(char *Buffer, size_t BufSize);
+ void ParseMessage(const char *MessageBuf);
+
+private:
+ virtual size_t ReadContentChunk(char *Buf, size_t bufSize);
+ void SetDefaultStatusBody(HTTPStatusCode Status);
+ HTTPStatusCode status;
+ cStringBuilder content;
+ friend class cConnectionHandler;
+ friend class HTTPParser;
+ };
+
+#endif /* HTTPRESPONSE_H */
+
diff --git a/libs/networking/include/HTTPServer.h b/libs/networking/include/HTTPServer.h
new file mode 100644
index 0000000..4dbe5a8
--- /dev/null
+++ b/libs/networking/include/HTTPServer.h
@@ -0,0 +1,61 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPServer.h
+ * Created: 4. Juli 2012, 12:16
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPSERVER_H
+#define HTTPSERVER_H
+
+#include <ServerConfig.h>
+#include <Mutex.h>
+#include <vector>
+
+class cThread;
+class cHTTPServer /* : public cThread */ {
+public:
+ cHTTPServer(cServerConfig &Config);
+ ~cHTTPServer();
+
+ bool Start(void);
+ void Stop(void);
+
+protected:
+ void Action(void);
+ bool AuthorizationRequired(void) const { return config.AuthorizationRequired(); }
+ bool Running(void);
+ cServerSocket &ServerSocket() { return config.server; }
+
+private:
+#ifdef LIVE_CLEANUP
+ void Cleanup(cThread *ThreadContext);
+ static int cleanerThread(void *opaque, cThread *ThreadContext);
+ cThread *cleaner;
+ cMutex poolMutex;
+#else
+ void Cleanup();
+#endif
+ cServerConfig &config;
+ std::vector<cThread *> *threads;
+ };
+
+#endif /* HTTPSERVER_H */
+
diff --git a/libs/networking/include/HTTPStatus.h b/libs/networking/include/HTTPStatus.h
new file mode 100644
index 0000000..10ff080
--- /dev/null
+++ b/libs/networking/include/HTTPStatus.h
@@ -0,0 +1,74 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPStatus.h
+ * Created: 3. Juli 2012, 17:34
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef HTTPSTATUS_H
+#define HTTPSTATUS_H
+
+typedef enum {
+ HTTP_Continue = 100
+, HTTP_SwitchProtocol = 101
+, HTTP_OK = 200
+, HTTP_Created = 201
+, HTTP_Accepted = 202
+, HTTP_NoContent = 204
+, HTTP_ResetContent = 205
+, HTTP_PartialContent = 206
+, HTTP_MultipleChoices = 300
+, HTTP_MovedPermanently = 301
+, HTTP_Found = 302
+, HTTP_SeeOther = 303
+, HTTP_NotModified = 304
+, HTTP_UseProxy = 305
+, HTTP_MovedTemporarily = 307
+, HTTP_BadRequest = 400
+, HTTP_UnAuthorized = 401
+, HTTP_PaymentRequired = 402
+, HTTP_Forbidden = 403
+, HTTP_NotFound = 404
+, HTTP_MethodNotAllowed = 405
+, HTTP_NotAcceptable = 406
+, HTTP_ProxyAuthenticationRequired = 407
+, HTTP_RequestTimeout = 408
+, HTTP_Conflict = 409
+, HTTP_Gone = 410
+, HTTP_LengthRequired = 411
+, HTTP_PreconditionFailed = 412
+, HTTP_RequestTooLarge = 413
+, HTTP_RequestURIToLong = 414
+, HTTP_UnsupportedMediaType = 415
+, HTTP_RequestRangeNotSatisfiable = 416
+, HTTP_ExpectationFailed = 417
+, HTTP_InternalServerError = 500
+, HTTP_NotImplemented = 501
+, HTTP_BadGateway = 502
+, HTTP_ServiceUnavailable = 503
+, HTTP_GatewayTimeout = 504
+, HTTP_VersionNotSupported = 505
+ } HTTPStatusCode;
+
+extern const char *httpStatus2Text(int Status);
+extern HTTPStatusCode strtoHTTPStatus(const char *p);
+
+#endif /* HTTPSTATUS_H */
+
diff --git a/libs/networking/include/Principal.h b/libs/networking/include/Principal.h
new file mode 100644
index 0000000..49afbde
--- /dev/null
+++ b/libs/networking/include/Principal.h
@@ -0,0 +1,64 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Principal.h
+ * Created: 3. Juli 2012, 12:50
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef PRINCIPAL_H
+#define PRINCIPAL_H
+
+class cPrincipal {
+public:
+ cPrincipal(const char *Name, const char *Realm);
+ cPrincipal(const cPrincipal &other);
+ virtual ~cPrincipal();
+ cPrincipal &operator =(const cPrincipal &other);
+ const char *operator *(void) { return name; }
+
+ void CreateHash(const char *Password);
+
+ const char *Name(void) const { return name; }
+ const char *Realm(void) const { return realm; }
+ const char *ExtendedInfo(void) const { return xinfo; }
+ int Age(void) const { return age; }
+ void SetAge(int Age) { age = Age; }
+ const char *Hash(void) const { return hash; }
+
+ void Dump(void) const;
+
+protected:
+ void SetName(const char *Name);
+ void SetRealm(const char *Realm);
+ void SetExtendedInfo(const char *Info);
+ void SetHash(const char *Hash);
+
+private:
+ char *name;
+ char *realm;
+ char *hash;
+ char *xinfo;
+ int age;
+ friend class cAuthorization;
+ friend class cCredentials;
+ };
+
+#endif /* PRINCIPAL_H */
+
diff --git a/libs/networking/include/ServerConfig.h b/libs/networking/include/ServerConfig.h
new file mode 100644
index 0000000..f64b5f5
--- /dev/null
+++ b/libs/networking/include/ServerConfig.h
@@ -0,0 +1,56 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ServerConfig.h
+ * Created: 8. Juli 2012, 06:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef SERVERCONFIG_H
+#define SERVERCONFIG_H
+
+#include <ServerSocket.h>
+#include <Authorization.h>
+
+class cServerConfig
+{
+public:
+ cServerConfig(int Port);
+ virtual ~cServerConfig();
+
+ bool AuthorizationRequired(void) { return authorizationRequired; }
+ const char *AppIconPath(void) const { return appIconPath; }
+ const char *DocumentRoot(void) const { return documentRoot; }
+
+ void SetAppIcon(const char *AppIcon);
+ void SetAuthorizationRequired(bool Authorize) { authorizationRequired = Authorize; }
+ void SetDocumentRoot(const char *DocumentRoot);
+
+private:
+ cServerSocket server;
+ cAuthorizations authorizations;
+ bool authorizationRequired;
+ char *documentRoot;
+ char *appIconPath;
+ friend class cHTTPServer;
+ friend class cConnectionHandler;
+};
+
+#endif /* SERVERCONFIG_H */
+
diff --git a/libs/networking/include/ServerSocket.h b/libs/networking/include/ServerSocket.h
new file mode 100644
index 0000000..2fc17fb
--- /dev/null
+++ b/libs/networking/include/ServerSocket.h
@@ -0,0 +1,52 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ServerSocket.h
+ * Created: 4. Juli 2012, 07:28
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef SERVERSOCKET_H
+#define SERVERSOCKET_H
+
+#include <AbstractSocket.h>
+
+class cServerSocket : public cAbstractSocket {
+public:
+ cServerSocket(int Port, int Queue = 1);
+ virtual ~cServerSocket();
+ bool Open(void);
+ bool Active(void) const { return active; }
+ void SetActive(bool Active = true) { active = Active; }
+ cConnectionPoint *Accept(void);
+ int Port(void) const { return port; }
+ int ReUseAddress(void) const;
+ void SetReUseAddress(int ReUse);
+ void ConfigureSocket(int Socket);
+ bool ForceBlockingIO(void) const;
+ void SetBlockingIO(bool ForceBlockingIO = true);
+
+private:
+ int port; ///< in case we plenty open and close server sockets
+ ///< we need a place to remember the server port
+ bool active;
+ };
+
+#endif /* SERVERSOCKET_H */
+
diff --git a/libs/networking/include/Url.h b/libs/networking/include/Url.h
new file mode 100644
index 0000000..c88a00a
--- /dev/null
+++ b/libs/networking/include/Url.h
@@ -0,0 +1,67 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Url.h
+ * Created: 4. Juli 2012, 05:42
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef URL_H
+#define URL_H
+
+#include <stddef.h>
+#include <string>
+#include <tr1/unordered_map>
+class cURLEncoder;
+class cURLDecoder;
+
+class cUrl {
+///< splits an url into machine readable parts:
+///< from top-level sight, an url consists of url and querystring. Looking bit closer,
+///< the url consists of toplevel and path, where as the querystring is a list of
+///< name/value tuples with value being an optional part.
+public:
+ cUrl(const char *RawURL);
+ virtual ~cUrl();
+ const char *Parameter(const char *Name);
+ void SetParameter(const char* Name, const char* Value = NULL);
+ size_t EstimatedSize(void) const; ///< is a rough guess about the size of the final encoded url
+ void ParseURL(const char *URL);
+ char *ToString(void) const; ///< writes the url to a newly allocated buffer
+ int WriteBuf(char *buf, size_t bufSize) const; ///< writes the url to preexisting buffer
+ ///< returns the characters written. -1 as return value indicates a buffer overrun.
+ const char * Path() const { return path; }
+#ifdef DEBUG
+ void Dump(void);
+#endif
+ static void Cleanup(void);
+
+protected:
+ void ParseQueryString(const char *QueryString);
+ cURLEncoder *Encoder(void) const;
+ cURLDecoder *Decoder(void) const;
+
+private:
+ typedef std::tr1::unordered_map<std::string, std::string> ParameterMap;
+ char *path;
+ ParameterMap parameters;
+ };
+
+#endif /* URL_H */
+
diff --git a/libs/networking/nbproject/Makefile-Debug.mk b/libs/networking/nbproject/Makefile-Debug.mk
new file mode 100644
index 0000000..1187090
--- /dev/null
+++ b/libs/networking/nbproject/Makefile-Debug.mk
@@ -0,0 +1,193 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/HTTPRequest.o \
+ ${OBJECTDIR}/src/ServerSocket.o \
+ ${OBJECTDIR}/src/HTTPAuthorizationRequest.o \
+ ${OBJECTDIR}/src/Url.o \
+ ${OBJECTDIR}/src/Principal.o \
+ ${OBJECTDIR}/src/Authorization.o \
+ ${OBJECTDIR}/src/ServerConfig.o \
+ ${OBJECTDIR}/src/HTTPServer.o \
+ ${OBJECTDIR}/src/ConnectionPoint.o \
+ ${OBJECTDIR}/src/HTTPResponse.o \
+ ${OBJECTDIR}/src/ConnectionHandler.o \
+ ${OBJECTDIR}/src/Credentials.o \
+ ${OBJECTDIR}/src/HTTPRequestHandler.o \
+ ${OBJECTDIR}/src/HTTPMessage.o \
+ ${OBJECTDIR}/src/HTTPFileResponse.o \
+ ${OBJECTDIR}/src/HTTPParser.o \
+ ${OBJECTDIR}/src/ClientSocket.o \
+ ${OBJECTDIR}/src/AbstractSocket.o \
+ ${OBJECTDIR}/src/HTTPStatus.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+CXXFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+${OBJECTDIR}/src/HTTPRequest.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPRequest.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPRequest.o src/HTTPRequest.cc
+
+${OBJECTDIR}/src/ServerSocket.o: nbproject/Makefile-${CND_CONF}.mk src/ServerSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ServerSocket.o src/ServerSocket.cc
+
+${OBJECTDIR}/src/HTTPAuthorizationRequest.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPAuthorizationRequest.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPAuthorizationRequest.o src/HTTPAuthorizationRequest.cc
+
+${OBJECTDIR}/src/Url.o: nbproject/Makefile-${CND_CONF}.mk src/Url.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Url.o src/Url.cc
+
+${OBJECTDIR}/src/Principal.o: nbproject/Makefile-${CND_CONF}.mk src/Principal.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Principal.o src/Principal.cc
+
+${OBJECTDIR}/src/Authorization.o: nbproject/Makefile-${CND_CONF}.mk src/Authorization.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Authorization.o src/Authorization.cc
+
+${OBJECTDIR}/src/ServerConfig.o: nbproject/Makefile-${CND_CONF}.mk src/ServerConfig.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ServerConfig.o src/ServerConfig.cc
+
+${OBJECTDIR}/src/HTTPServer.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPServer.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPServer.o src/HTTPServer.cc
+
+${OBJECTDIR}/src/ConnectionPoint.o: nbproject/Makefile-${CND_CONF}.mk src/ConnectionPoint.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ConnectionPoint.o src/ConnectionPoint.cc
+
+${OBJECTDIR}/src/HTTPResponse.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPResponse.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPResponse.o src/HTTPResponse.cc
+
+${OBJECTDIR}/src/ConnectionHandler.o: nbproject/Makefile-${CND_CONF}.mk src/ConnectionHandler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ConnectionHandler.o src/ConnectionHandler.cc
+
+${OBJECTDIR}/src/Credentials.o: nbproject/Makefile-${CND_CONF}.mk src/Credentials.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Credentials.o src/Credentials.cc
+
+${OBJECTDIR}/src/HTTPRequestHandler.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPRequestHandler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPRequestHandler.o src/HTTPRequestHandler.cc
+
+${OBJECTDIR}/src/HTTPMessage.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPMessage.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPMessage.o src/HTTPMessage.cc
+
+${OBJECTDIR}/src/HTTPFileResponse.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPFileResponse.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPFileResponse.o src/HTTPFileResponse.cc
+
+${OBJECTDIR}/src/HTTPParser.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPParser.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPParser.o src/HTTPParser.cc
+
+${OBJECTDIR}/src/ClientSocket.o: nbproject/Makefile-${CND_CONF}.mk src/ClientSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ClientSocket.o src/ClientSocket.cc
+
+${OBJECTDIR}/src/AbstractSocket.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractSocket.o src/AbstractSocket.cc
+
+${OBJECTDIR}/src/HTTPStatus.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPStatus.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../util/include -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPStatus.o src/HTTPStatus.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/networking/nbproject/Makefile-Release.mk b/libs/networking/nbproject/Makefile-Release.mk
new file mode 100644
index 0000000..39e0873
--- /dev/null
+++ b/libs/networking/nbproject/Makefile-Release.mk
@@ -0,0 +1,193 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/HTTPRequest.o \
+ ${OBJECTDIR}/src/ServerSocket.o \
+ ${OBJECTDIR}/src/HTTPAuthorizationRequest.o \
+ ${OBJECTDIR}/src/Url.o \
+ ${OBJECTDIR}/src/Principal.o \
+ ${OBJECTDIR}/src/Authorization.o \
+ ${OBJECTDIR}/src/ServerConfig.o \
+ ${OBJECTDIR}/src/HTTPServer.o \
+ ${OBJECTDIR}/src/ConnectionPoint.o \
+ ${OBJECTDIR}/src/HTTPResponse.o \
+ ${OBJECTDIR}/src/ConnectionHandler.o \
+ ${OBJECTDIR}/src/Credentials.o \
+ ${OBJECTDIR}/src/HTTPRequestHandler.o \
+ ${OBJECTDIR}/src/HTTPMessage.o \
+ ${OBJECTDIR}/src/HTTPFileResponse.o \
+ ${OBJECTDIR}/src/HTTPParser.o \
+ ${OBJECTDIR}/src/ClientSocket.o \
+ ${OBJECTDIR}/src/AbstractSocket.o \
+ ${OBJECTDIR}/src/HTTPStatus.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+${OBJECTDIR}/src/HTTPRequest.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPRequest.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPRequest.o src/HTTPRequest.cc
+
+${OBJECTDIR}/src/ServerSocket.o: nbproject/Makefile-${CND_CONF}.mk src/ServerSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ServerSocket.o src/ServerSocket.cc
+
+${OBJECTDIR}/src/HTTPAuthorizationRequest.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPAuthorizationRequest.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPAuthorizationRequest.o src/HTTPAuthorizationRequest.cc
+
+${OBJECTDIR}/src/Url.o: nbproject/Makefile-${CND_CONF}.mk src/Url.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Url.o src/Url.cc
+
+${OBJECTDIR}/src/Principal.o: nbproject/Makefile-${CND_CONF}.mk src/Principal.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Principal.o src/Principal.cc
+
+${OBJECTDIR}/src/Authorization.o: nbproject/Makefile-${CND_CONF}.mk src/Authorization.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Authorization.o src/Authorization.cc
+
+${OBJECTDIR}/src/ServerConfig.o: nbproject/Makefile-${CND_CONF}.mk src/ServerConfig.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ServerConfig.o src/ServerConfig.cc
+
+${OBJECTDIR}/src/HTTPServer.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPServer.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPServer.o src/HTTPServer.cc
+
+${OBJECTDIR}/src/ConnectionPoint.o: nbproject/Makefile-${CND_CONF}.mk src/ConnectionPoint.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ConnectionPoint.o src/ConnectionPoint.cc
+
+${OBJECTDIR}/src/HTTPResponse.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPResponse.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPResponse.o src/HTTPResponse.cc
+
+${OBJECTDIR}/src/ConnectionHandler.o: nbproject/Makefile-${CND_CONF}.mk src/ConnectionHandler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ConnectionHandler.o src/ConnectionHandler.cc
+
+${OBJECTDIR}/src/Credentials.o: nbproject/Makefile-${CND_CONF}.mk src/Credentials.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Credentials.o src/Credentials.cc
+
+${OBJECTDIR}/src/HTTPRequestHandler.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPRequestHandler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPRequestHandler.o src/HTTPRequestHandler.cc
+
+${OBJECTDIR}/src/HTTPMessage.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPMessage.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPMessage.o src/HTTPMessage.cc
+
+${OBJECTDIR}/src/HTTPFileResponse.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPFileResponse.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPFileResponse.o src/HTTPFileResponse.cc
+
+${OBJECTDIR}/src/HTTPParser.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPParser.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPParser.o src/HTTPParser.cc
+
+${OBJECTDIR}/src/ClientSocket.o: nbproject/Makefile-${CND_CONF}.mk src/ClientSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ClientSocket.o src/ClientSocket.cc
+
+${OBJECTDIR}/src/AbstractSocket.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractSocket.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractSocket.o src/AbstractSocket.cc
+
+${OBJECTDIR}/src/HTTPStatus.o: nbproject/Makefile-${CND_CONF}.mk src/HTTPStatus.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/HTTPStatus.o src/HTTPStatus.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/networking/nbproject/Makefile-impl.mk b/libs/networking/nbproject/Makefile-impl.mk
new file mode 100644
index 0000000..08c8342
--- /dev/null
+++ b/libs/networking/nbproject/Makefile-impl.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=networking
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber
+.clobber-impl: .clobber-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+ done
+
+# all
+.all-impl: .all-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+ done
+
+# build tests
+.build-tests-impl: .build-impl .build-tests-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
+
+# run tests
+.test-impl: .build-tests-impl .test-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
+
+# dependency checking support
+.depcheck-impl:
+ @echo "# This code depends on make tool being used" >.dep.inc
+ @if [ -n "${MAKE_VERSION}" ]; then \
+ echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+ echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+ echo "include \$${DEPFILES}" >>.dep.inc; \
+ echo "endif" >>.dep.inc; \
+ else \
+ echo ".KEEP_STATE:" >>.dep.inc; \
+ echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+ fi
+
+# configuration validation
+.validate-impl:
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ echo ""; \
+ echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+ echo "See 'make help' for details."; \
+ echo "Current directory: " `pwd`; \
+ echo ""; \
+ fi
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ exit 1; \
+ fi
+
+
+# help
+.help-impl: .help-pre
+ @echo "This makefile supports the following configurations:"
+ @echo " ${ALLCONFS}"
+ @echo ""
+ @echo "and the following targets:"
+ @echo " build (default target)"
+ @echo " clean"
+ @echo " clobber"
+ @echo " all"
+ @echo " help"
+ @echo ""
+ @echo "Makefile Usage:"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
+ @echo " make [SUB=no] clobber"
+ @echo " make [SUB=no] all"
+ @echo " make help"
+ @echo ""
+ @echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+ @echo " also clean subprojects."
+ @echo "Target 'clobber' will remove all built files from all configurations and,"
+ @echo " unless 'SUB=no', also from subprojects."
+ @echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'help' prints this message."
+ @echo ""
+
diff --git a/libs/networking/nbproject/Makefile-variables.mk b/libs/networking/nbproject/Makefile-variables.mk
new file mode 100644
index 0000000..25db304
--- /dev/null
+++ b/libs/networking/nbproject/Makefile-variables.mk
@@ -0,0 +1,35 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# Debug configuration
+CND_PLATFORM_Debug=GNU-Linux-x86
+CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86
+CND_ARTIFACT_NAME_Debug=libnetworking.a
+CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/libnetworking.a
+CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Debug=networking.tar
+CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/networking.tar
+# Release configuration
+CND_PLATFORM_Release=GNU-Linux-x86
+CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
+CND_ARTIFACT_NAME_Release=libnetworking.a
+CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/libnetworking.a
+CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Release=networking.tar
+CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/networking.tar
+#
+# include compiler specific variables
+#
+# dmake command
+ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
+ (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
+#
+# gmake command
+.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
+#
+include nbproject/private/Makefile-variables.mk
diff --git a/libs/networking/nbproject/Package-Debug.bash b/libs/networking/nbproject/Package-Debug.bash
new file mode 100644
index 0000000..4c7fd47
--- /dev/null
+++ b/libs/networking/nbproject/Package-Debug.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+OUTPUT_BASENAME=libnetworking.a
+PACKAGE_TOP_DIR=networking/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/networking/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/networking.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/networking.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/networking/nbproject/Package-Release.bash b/libs/networking/nbproject/Package-Release.bash
new file mode 100644
index 0000000..4525cc6
--- /dev/null
+++ b/libs/networking/nbproject/Package-Release.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libnetworking.a
+OUTPUT_BASENAME=libnetworking.a
+PACKAGE_TOP_DIR=networking/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/networking/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/networking.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/networking.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/networking/nbproject/configurations.xml b/libs/networking/nbproject/configurations.xml
new file mode 100644
index 0000000..fc79ca1
--- /dev/null
+++ b/libs/networking/nbproject/configurations.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>include/AbstractSocket.h</itemPath>
+ <itemPath>include/Authorization.h</itemPath>
+ <itemPath>include/ClientSocket.h</itemPath>
+ <itemPath>include/ConnectionHandler.h</itemPath>
+ <itemPath>include/ConnectionPoint.h</itemPath>
+ <itemPath>include/Credentials.h</itemPath>
+ <itemPath>include/HTTPAuthorizationRequest.h</itemPath>
+ <itemPath>include/HTTPFileResponse.h</itemPath>
+ <itemPath>include/HTTPMessage.h</itemPath>
+ <itemPath>include/HTTPParser.h</itemPath>
+ <itemPath>include/HTTPRequest.h</itemPath>
+ <itemPath>include/HTTPRequestHandler.h</itemPath>
+ <itemPath>include/HTTPResponse.h</itemPath>
+ <itemPath>include/HTTPServer.h</itemPath>
+ <itemPath>include/HTTPStatus.h</itemPath>
+ <itemPath>include/Principal.h</itemPath>
+ <itemPath>include/ServerConfig.h</itemPath>
+ <itemPath>include/ServerSocket.h</itemPath>
+ <itemPath>include/Url.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/AbstractSocket.cc</itemPath>
+ <itemPath>src/Authorization.cc</itemPath>
+ <itemPath>src/ClientSocket.cc</itemPath>
+ <itemPath>src/ConnectionHandler.cc</itemPath>
+ <itemPath>src/ConnectionPoint.cc</itemPath>
+ <itemPath>src/Credentials.cc</itemPath>
+ <itemPath>src/HTTPAuthorizationRequest.cc</itemPath>
+ <itemPath>src/HTTPFileResponse.cc</itemPath>
+ <itemPath>src/HTTPMessage.cc</itemPath>
+ <itemPath>src/HTTPParser.cc</itemPath>
+ <itemPath>src/HTTPRequest.cc</itemPath>
+ <itemPath>src/HTTPRequestHandler.cc</itemPath>
+ <itemPath>src/HTTPResponse.cc</itemPath>
+ <itemPath>src/HTTPServer.cc</itemPath>
+ <itemPath>src/HTTPStatus.cc</itemPath>
+ <itemPath>src/Principal.cc</itemPath>
+ <itemPath>src/ServerConfig.cc</itemPath>
+ <itemPath>src/ServerSocket.cc</itemPath>
+ <itemPath>src/Url.cc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="TestFiles"
+ displayName="Test Files"
+ projectFiles="false"
+ kind="TEST_LOGICAL_FOLDER">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false"
+ kind="IMPORTANT_FILES_FOLDER">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <ccTool>
+ <incDir>
+ <pElem>include</pElem>
+ <pElem>../util/include</pElem>
+ <pElem>../vdr/include</pElem>
+ </incDir>
+ <commandLine>-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi</commandLine>
+ <preprocessorList>
+ <Elem>_GNU_SOURCE=1</Elem>
+ <Elem>_REENTRANT</Elem>
+ </preprocessorList>
+ <warningLevel>2</warningLevel>
+ </ccTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ </ccTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <asmTool>
+ <developmentMode>5</developmentMode>
+ </asmTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/networking/nbproject/private/Makefile-variables.mk b/libs/networking/nbproject/private/Makefile-variables.mk
new file mode 100644
index 0000000..a64183e
--- /dev/null
+++ b/libs/networking/nbproject/private/Makefile-variables.mk
@@ -0,0 +1,7 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+# Debug configuration
+# Release configuration
diff --git a/libs/networking/nbproject/private/configurations.xml b/libs/networking/nbproject/private/configurations.xml
new file mode 100644
index 0000000..fa15dc7
--- /dev/null
+++ b/libs/networking/nbproject/private/configurations.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/networking/nbproject/private/private.xml b/libs/networking/nbproject/private/private.xml
new file mode 100644
index 0000000..5ee2703
--- /dev/null
+++ b/libs/networking/nbproject/private/private.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+ <data xmlns="http://www.netbeans.org/ns/make-project-private/1">
+ <activeConfTypeElem>3</activeConfTypeElem>
+ <activeConfIndexElem>0</activeConfIndexElem>
+ </data>
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>
diff --git a/libs/networking/nbproject/project.xml b/libs/networking/nbproject/project.xml
new file mode 100644
index 0000000..45ed83d
--- /dev/null
+++ b/libs/networking/nbproject/project.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>networking</name>
+ <c-extensions/>
+ <cpp-extensions>cc</cpp-extensions>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>Debug</name>
+ <type>3</type>
+ </confElem>
+ <confElem>
+ <name>Release</name>
+ <type>3</type>
+ </confElem>
+ </confList>
+ </data>
+ </configuration>
+</project>
diff --git a/libs/networking/networking.cbp b/libs/networking/networking.cbp
new file mode 100644
index 0000000..fc36817
--- /dev/null
+++ b/libs/networking/networking.cbp
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="CMP.libs.networking" />
+ <Option pch_mode="2" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Debug">
+ <Option output="libnetworking" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Debug/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-g" />
+ </Compiler>
+ </Target>
+ <Target title="Release">
+ <Option output="libnetworking" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Release/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-O2" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ </Linker>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi" />
+ <Add option="-D_REENTRANT" />
+ <Add option="-D_GNU_SOURCE=1" />
+ <Add directory="../vdr/include" />
+ <Add directory="../util/include" />
+ <Add directory="include" />
+ </Compiler>
+ <Unit filename="include/AbstractSocket.h" />
+ <Unit filename="include/Authorization.h" />
+ <Unit filename="include/ClientSocket.h" />
+ <Unit filename="include/ConnectionHandler.h" />
+ <Unit filename="include/ConnectionPoint.h" />
+ <Unit filename="include/Credentials.h" />
+ <Unit filename="include/HTTPAuthorizationRequest.h" />
+ <Unit filename="include/HTTPFileResponse.h" />
+ <Unit filename="include/HTTPMessage.h" />
+ <Unit filename="include/HTTPRequest.h" />
+ <Unit filename="include/HTTPRequestHandler.h" />
+ <Unit filename="include/HTTPResponse.h" />
+ <Unit filename="include/HTTPServer.h" />
+ <Unit filename="include/HTTPStatus.h" />
+ <Unit filename="include/Principal.h" />
+ <Unit filename="include/ServerConfig.h" />
+ <Unit filename="include/ServerSocket.h" />
+ <Unit filename="include/Url.h" />
+ <Unit filename="src/AbstractSocket.cc" />
+ <Unit filename="src/Authorization.cc" />
+ <Unit filename="src/ClientSocket.cc" />
+ <Unit filename="src/ConnectionHandler.cc" />
+ <Unit filename="src/ConnectionPoint.cc" />
+ <Unit filename="src/Credentials.cc" />
+ <Unit filename="src/HTTPAuthorizationRequest.cc" />
+ <Unit filename="src/HTTPFileResponse.cc" />
+ <Unit filename="src/HTTPMessage.cc" />
+ <Unit filename="src/HTTPRequest.cc" />
+ <Unit filename="src/HTTPRequestHandler.cc" />
+ <Unit filename="src/HTTPResponse.cc" />
+ <Unit filename="src/HTTPServer.cc" />
+ <Unit filename="src/HTTPStatus.cc" />
+ <Unit filename="src/Principal.cc" />
+ <Unit filename="src/ServerConfig.cc" />
+ <Unit filename="src/ServerSocket.cc" />
+ <Unit filename="src/Url.cc" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <lib_finder disable_auto="1" />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/libs/networking/networking.depend b/libs/networking/networking.depend
new file mode 100644
index 0000000..c4ac310
--- /dev/null
+++ b/libs/networking/networking.depend
@@ -0,0 +1 @@
+# depslib dependency file v1.0
diff --git a/libs/networking/networking.layout b/libs/networking/networking.layout
new file mode 100644
index 0000000..a008101
--- /dev/null
+++ b/libs/networking/networking.layout
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/HTTPFileResponse.cc" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/ConnectionHandler.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="1551" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/ConnectionPoint.cc" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/HTTPMessage.h" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ConnectionHandler.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ConnectionPoint.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/HTTPMessage.cc" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/HTTPResponse.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/networking/networking.layout.save b/libs/networking/networking.layout.save
new file mode 100644
index 0000000..e313395
--- /dev/null
+++ b/libs/networking/networking.layout.save
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/ConnectionPoint.cc" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/HTTPMessage.h" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/HTTPMessage.cc" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/HTTPFileResponse.cc" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/HTTPResponse.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ConnectionPoint.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ConnectionHandler.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/ConnectionHandler.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="1551" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/networking/poll.sample b/libs/networking/poll.sample
new file mode 100644
index 0000000..a252b7d
--- /dev/null
+++ b/libs/networking/poll.sample
@@ -0,0 +1,53 @@
+EXAMPLES
+
+ Checking for Events on a Stream
+
+ The following example opens a pair of STREAMS devices and then waits for either one to become writable. This example proceeds as follows:
+
+ 1. Sets the timeout parameter to 500 milliseconds.
+ 2. Opens the STREAMS devices /dev/dev0 and /dev/dev1, and then polls them, specifying POLLOUT and POLLWRBAND as the events of interest.
+ The STREAMS device names /dev/dev0 and /dev/dev1 are only examples of how STREAMS devices can be named; STREAMS naming conventions may vary among systems conforming to the IEEE Std 1003.1-2001.
+ 3. Uses the ret variable to determine whether an event has occurred on either of the two STREAMS. The poll() function is given 500 milliseconds to wait for an event to occur (if it has not occurred prior to the poll() call).
+ 4. Checks the returned value of ret. If a positive value is returned, one of the following can be done:
+ 1. Priority data can be written to the open STREAM on priority bands greater than 0, because the POLLWRBAND event occurred on the open STREAM ( fds[0] or fds[1]).
+ 2. Data can be written to the open STREAM on priority-band 0, because the POLLOUT event occurred on the open STREAM ( fds[0] or fds[1]).
+ 5. If the returned value is not a positive value, permission to write data to the open STREAM (on any priority band) is denied.
+ 6. If the POLLHUP event occurs on the open STREAM ( fds[0] or fds[1]), the device on the open STREAM has disconnected.
+
+ #include <stropts.h>
+ #include <poll.h>
+ ...
+ struct pollfd fds[2];
+ int timeout_msecs = 500;
+ int ret;
+ int i;
+
+
+ /* Open STREAMS device. */
+ fds[0].fd = open("/dev/dev0", ...);
+ fds[1].fd = open("/dev/dev1", ...);
+ fds[0].events = POLLOUT | POLLWRBAND;
+ fds[1].events = POLLOUT | POLLWRBAND;
+
+
+ ret = poll(fds, 2, timeout_msecs);
+
+
+ if (ret > 0) {
+ /* An event on one of the fds has occurred. */
+ for (i=0; i<2; i++) {
+ if (fds[i].revents & POLLWRBAND) {
+ /* Priority data may be written on device number i. */
+ ...
+ }
+ if (fds[i].revents & POLLOUT) {
+ /* Data may be written on device number i. */
+ ...
+ }
+ if (fds[i].revents & POLLHUP) {
+ /* A hangup has occurred on device number i. */
+ ...
+ }
+ }
+ }
+
diff --git a/libs/networking/src/AbstractSocket.cc b/libs/networking/src/AbstractSocket.cc
new file mode 100644
index 0000000..827d466
--- /dev/null
+++ b/libs/networking/src/AbstractSocket.cc
@@ -0,0 +1,290 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractSocket.cc
+ * Created: 4. Juli 2012, 07:13
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <AbstractSocket.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <poll.h>
+
+cAbstractSocket::cAbstractSocket(int Port, int Queue)
+ : sock(-1)
+ , queue(Queue)
+ , blocking(true)
+ , thisSide(NULL)
+{
+}
+
+cAbstractSocket::cAbstractSocket(const char *ServerName, int Port)
+ : sock(-1)
+ , queue(0)
+ , blocking(true)
+ , thisSide(NULL)
+{
+ others.push_back(new cConnectionPoint(ServerName, Port));
+}
+
+cAbstractSocket::~cAbstractSocket()
+{
+ Close();
+ if (thisSide) delete thisSide;
+ cConnectionPoint *p;
+
+ for (size_t i=0; i < others.size(); ++i) {
+ p = others[i];
+ delete p;
+ }
+}
+
+void cAbstractSocket::Close(void)
+{
+ if (sock >= 0) {
+ close(sock);
+ sock = -1;
+ }
+}
+
+// the client side
+bool cAbstractSocket::Connect(void)
+{
+ if (sock < 0) {
+ struct addrinfo hints, *result, *rp;
+ char buf[20];
+ int s;
+
+ /* Obtain address(es) matching host/port */
+ memset(buf, 0, sizeof(buf));
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6
+ hints.ai_socktype = SOCK_STREAM;
+ snprintf(buf, sizeof(buf), "%d", OtherSide()->Port());
+
+ if ((s = getaddrinfo(OtherSide()->HostName(), buf, &hints, &result))) {
+ esyslog("getaddrinfo: %s", gai_strerror(s));
+
+ return -1;
+ }
+
+ // getaddrinfo potentially returns a list of addresses, that may fit,
+ // so try each address until we successfully connect
+ for (rp = result; rp; rp = rp->ai_next) {
+ sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sock == -1) continue;
+
+ if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
+ break; // we got a connection
+ close(sock);
+ }
+ if (rp == NULL) { // no address could be connected to
+ esyslog("Could not connect!");
+ Close();
+
+ return false;
+ }
+ // here we have a valid connection, so lets gather some information
+ thisSide = GetNameAndAddress(sock, rp->ai_addr, rp->ai_addrlen);
+ OtherSide()->SetSocket(sock);
+ char nameBuf[512];
+
+ memset(nameBuf, 0, sizeof(nameBuf));
+ if ((s = getnameinfo(rp->ai_addr, rp->ai_addrlen, nameBuf, sizeof(nameBuf), NULL, 0, NI_NAMEREQD))) {
+ esyslog("failed to determine servers hostname %s", gai_strerror(s));
+ }
+ else {
+ OtherSide()->SetRealName(nameBuf);
+ }
+ freeaddrinfo(result);
+ }
+ return sock > 0;
+}
+
+// as each address may be IP4 or IP6, cut this off
+static void * getAddr(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET)
+ return &(((struct sockaddr_in*)sa)->sin_addr);
+ return &(((struct sockaddr_in6*)sa)->sin6_addr);
+}
+
+// same is true for port access
+static int getPort(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET)
+ return ((struct sockaddr_in*)sa)->sin_port;
+ return ((struct sockaddr_in6*)sa)->sin6_port;
+}
+
+cConnectionPoint *cAbstractSocket::GetNameAndAddress(int Socket, struct sockaddr *sa, socklen_t sa_size)
+{
+ cConnectionPoint *rv = NULL;
+ char nameBuf[512], addrBuf[INET6_ADDRSTRLEN];
+
+ if (getnameinfo(sa, sa_size, nameBuf, sizeof(nameBuf), NULL, 0, NI_NAMEREQD)) {
+ // ok, just ip address has to suffice to start work
+ rv = new cConnectionPoint(inet_ntop(sa->sa_family, getAddr(sa), addrBuf, sizeof(addrBuf))
+ , ntohs(getPort(sa))
+ , inet_ntop(sa->sa_family, getAddr(sa), addrBuf, sizeof(addrBuf)));
+ }
+ else {
+ rv = new cConnectionPoint(inet_ntop(sa->sa_family, getAddr(sa), addrBuf, sizeof(addrBuf))
+ , ntohs(getPort(sa))
+ , nameBuf);
+ }
+ if (rv) rv->SetSocket(Socket);
+
+ return rv;
+}
+
+void cAbstractSocket::SetBlockingIO(bool ForceBlockingIO)
+{
+ blocking = ForceBlockingIO;
+}
+
+// server side first part
+bool cAbstractSocket::Open(int Port)
+{
+ if (sock < 0) {
+ isyslog("socket is < 0 - so start a new connection ...");
+ struct addrinfo hints, *result, *rp;
+ char buf[20];
+ int s;
+
+ memset(&hints, 0, sizeof(hints));
+ memset(buf, 0, sizeof(buf));
+ hints.ai_family = AF_UNSPEC; // allow IPv4 or IPv6
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ snprintf(buf, sizeof(buf), "%d", Port);
+
+ if ((s = getaddrinfo(NULL, buf, &hints, &result))) {
+ esyslog("getaddrinfo: %s\n", gai_strerror(s));
+
+ return false;
+ }
+ int yes=1;
+
+ // getaddrinfo potentially returns a list of addresses, that may fit,
+ // so try each address until we successfully bound
+ for (rp = result; rp; rp = rp->ai_next) {
+ sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sock == -1) continue;
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
+
+ if (bind(sock, rp->ai_addr, rp->ai_addrlen) != -1)
+ break; // ok, we succeeded to bind
+ close(sock);
+ }
+ if (!rp) {
+ esyslog("could not bind");
+ Close();
+
+ return false;
+ }
+ ConfigureSocket(sock);
+ freeaddrinfo(result);
+
+ // listen to the socket:
+ if (listen(sock, queue) < 0) {
+ esyslog("failed to listen to bound socket!");
+ Close();
+ return (false);
+ }
+ }
+ return (true);
+}
+
+// server side second part
+cConnectionPoint *cAbstractSocket::Accept(int Port, int TimeoutMs)
+{
+ cConnectionPoint *client = NULL;
+
+ if (Open(Port)) {
+ struct sockaddr_storage clientname;
+ uint cl_size = sizeof(clientname);
+ struct pollfd pf[1];
+
+ pf[0].fd = sock;
+ pf[0].events = POLLIN;
+
+ if (poll(pf, 1, TimeoutMs) < 1) return NULL;
+ int newsock = accept(sock, (struct sockaddr *) &clientname, &cl_size);
+
+ if (newsock > 0) {
+ isyslog("ok, got client connection request ...");
+
+ // if server address has not been restricted at bind-time, its possible that we don't
+ // have a local address yet. If server is bound to 0 (any address), we can determine
+ // the real server address in use now. But only do it once.
+ if (!thisSide) {
+ struct sockaddr_storage server;
+ uint sa_size = sizeof(server);
+
+ if (getpeername(newsock, (struct sockaddr *) &server, &sa_size)) {
+ esyslog("getpeername failed: #%d", errno);
+ }
+ else thisSide = GetNameAndAddress(newsock, (struct sockaddr *) &server, sa_size);
+ }
+
+ // At server side, multiple clients can have open connections at the same time,
+ // so get rid of that here. We always fetch connections informations
+ // before any access decisions, so those could be extended to use names
+ // some day ...
+ client = GetNameAndAddress(newsock, (struct sockaddr *) &clientname, cl_size);
+ if (client) {
+ bool accepted = true;
+ //FIXME: change determination of accepting client access!
+ // accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
+ // change to:
+ // accepted = SVDRPHosts.Acceptable(cpi);
+ // so in SVDRPHosts you have IP-Address and real name (if accessible)
+
+ if (!accepted) {
+ const char *s = "Access denied!\n";
+
+ if (write(newsock, s, strlen(s)) < 0) {
+ esyslog(s);
+ close(newsock);
+ }
+ newsock = -1;
+ client = NULL;
+ }
+ else {
+ others.push_back(client);
+ }
+ isyslog("connect from %s, port %hu - %s", client->HostName(), client->Port(), accepted ? "accepted" : "DENIED");
+ }
+ }
+ else if (errno != EINTR && errno != EAGAIN) {
+ esyslog("failed to accept client");
+ }
+ }
+ return (client);
+}
diff --git a/libs/networking/src/Authorization.cc b/libs/networking/src/Authorization.cc
new file mode 100644
index 0000000..b22145a
--- /dev/null
+++ b/libs/networking/src/Authorization.cc
@@ -0,0 +1,469 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Authorization.cc
+ * Created: 3. Juli 2012, 17:27
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Authorization.h>
+#include <Credentials.h>
+#include <MD5Calculator.h>
+#include <Principal.h>
+#include <ConnectionPoint.h>
+#include <Logging.h>
+#include <stdio.h>
+#include <util.h>
+
+static bool useSessionHash = true;
+
+cAuthorization::cAuthorization(const cHTTPRequest &OriginalRequest, char *NOnceFromHeap)
+///< use this constructor to create an authorization request for responses to
+///< clients without valid authorization headers.
+ : tmp(NULL)
+ , principal(NULL)
+ , method(OriginalRequest.Method())
+ , serverID(NULL)
+ , sessAlgo(useSessionHash)
+ , nonce(NOnceFromHeap)
+ , uri(OriginalRequest.Url().ToString())
+ , response(NULL)
+ , opaque(NULL)
+ , cnonce(NULL)
+ , qop(NULL)
+ , counter(0)
+ , authTime(time(NULL))
+{
+ tmp = new cPrincipal("unset", Credentials.ApplicationRealm());
+ opaque = cAuthorizations::CreateSessionID(OriginalRequest, authTime);
+}
+
+cAuthorization::cAuthorization(cHTTPRequest::HTTPRequestMethod Method, const char *Raw)
+///< use this constructor to create an authorization from clients request message
+ : tmp(NULL)
+ , principal(NULL)
+ , method(Method)
+ , serverID(NULL)
+ , sessAlgo(false)
+ , nonce(NULL)
+ , uri(NULL)
+ , response(NULL)
+ , opaque(NULL)
+ , cnonce(NULL)
+ , qop(NULL)
+ , counter(0)
+{
+ ParseRawBuffer(Raw);
+}
+
+cAuthorization::cAuthorization(const cPrincipal *Principal, cHTTPRequest::HTTPRequestMethod Method, const cAuthorization &other)
+ : tmp(other.tmp ? new cPrincipal(*other.tmp) : NULL)
+ , principal(Principal)
+ , method(Method)
+ , serverID(other.serverID ? strdup(other.serverID) : NULL)
+ , sessAlgo(other.sessAlgo)
+ , nonce(other.nonce ? strdup(other.nonce) : NULL)
+ , uri(other.uri ? strdup(other.uri) : NULL)
+ , response(other.response ? strdup(other.response) : NULL)
+ , opaque(other.opaque ? strdup(other.opaque) : NULL)
+ , cnonce(other.cnonce ? strdup(other.cnonce) : NULL)
+ , qop(other.qop ? strdup(other.qop) : NULL)
+ , counter(other.counter)
+{
+}
+
+cAuthorization::cAuthorization(const cAuthorization& other)
+ : tmp(other.tmp ? new cPrincipal(*other.tmp) : NULL)
+ , principal(other.principal)
+ , method(other.method)
+ , serverID(other.serverID ? strdup(other.serverID) : NULL)
+ , sessAlgo(other.sessAlgo)
+ , nonce(other.nonce ? strdup(other.nonce) : NULL)
+ , uri(other.uri ? strdup(other.uri) : NULL)
+ , response(other.response ? strdup(other.response) : NULL)
+ , opaque(other.opaque ? strdup(other.opaque) : NULL)
+ , cnonce(other.cnonce ? strdup(other.cnonce) : NULL)
+ , qop(other.qop ? strdup(other.qop) : NULL)
+ , counter(other.counter + 1)
+{
+}
+
+cAuthorization::~cAuthorization()
+{
+ if (tmp) delete tmp;
+ FREE(nonce);
+ FREE(uri);
+ FREE(serverID);
+ FREE(response);
+ FREE(opaque);
+ FREE(cnonce);
+ FREE(qop);
+}
+
+cAuthorization& cAuthorization::operator=(const cAuthorization& other)
+{
+ if (&other == this) return *this;
+ if (tmp) delete tmp;
+ FREE(nonce);
+ FREE(uri);
+ FREE(serverID);
+ FREE(response);
+ FREE(opaque);
+ FREE(cnonce);
+
+ principal = other.principal;
+ sessAlgo = other.sessAlgo;
+ method = other.method;
+ serverID = other.serverID ? strdup(other.serverID) : NULL;
+ nonce = other.nonce ? strdup(other.nonce) : NULL;
+ uri = other.uri ? strdup(other.uri) : NULL;
+ response = other.response ? strdup(other.response) : NULL;
+ opaque = other.opaque ? strdup(other.opaque) : NULL;
+ cnonce = other.cnonce ? strdup(other.cnonce) : NULL;
+ counter = other.counter;
+ qop = other.qop ? strdup(other.qop) : NULL;
+ tmp = other.tmp ? new cPrincipal(*other.tmp) : NULL;
+
+ return *this;
+}
+
+void cAuthorization::CreateClientHash()
+{
+ cMD5Calculator hc;
+ char buf[40];
+
+ snprintf(buf, sizeof(buf), "%lu", random());
+
+ hc.AddContent(serverID);
+ hc.AddContent(":");
+ hc.AddContent(buf);
+
+ cnonce = hc.Hash();
+}
+
+static const char *getAttrName(char *buf, int bufSize, const char *src)
+{
+ const char *s = src;
+ char *d = buf;
+
+ while (*s && isspace(*s)) ++s;
+ while (*s && ((d - buf) < bufSize) && *s != '=' && !isspace(*s)) *d++ = *s++;
+ *d = 0;
+
+ return *s ? s : NULL;
+}
+
+static const char *getValue(char *buf, int bufSize, const char *src)
+{
+ const char *s = src;
+ char *d = buf;
+
+ if (*s == '"') {
+ ++s;
+ while (*s && ((d - buf) < bufSize) && *s != '"') *d++ = *s++;
+ if (*s != '"') return NULL;
+ ++s;
+ }
+ else {
+ while (*s && ((d - buf) < bufSize) && *s != ',') *d++ = *s++;
+ }
+ *d = 0;
+
+ return *s ? s : NULL;
+}
+
+size_t cAuthorization::Write(char* Buffer, size_t BufSize)
+{
+ static const char *UnAuthorizedMask = "WWW-Authenticate: Digest realm=\"%s\", "
+ "nonce=\"%s\", opaque=\"%s\", algorithm=\"MD5%s\", qop=\"auth\"\n";
+ static const char *AuthorizedMask = "Authorization: Digest username=\"%s\", "
+ "realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\", opaque=\"%s\", qop=\"auth\", nc=%08X, algorithm=\"MD5%s\", cnonce=\"%s\"";
+ static const char *AuthenticationMaskDef = "Authentication-Info: qop=auth, nc=%08X, rspauth=\"%s\", cnonce=\"%s\"";
+ static const char *AuthenticationMaskNew = "Authentication-Info: nextnounce=\"%s\", qop=auth, nc=%08X, rspauth=\"%s\", cnonce=\"%s\"";
+ size_t n=0;
+
+ if (principal && strcmp(principal->Name(), "unset")) {
+ static bool timeout = 0;
+ //TODO: authorization info, should be sent after certain timeout
+ if (timeout) n = snprintf(Buffer, BufSize, AuthenticationMaskNew, nonce, counter, response, cnonce);
+ else n = snprintf(Buffer, BufSize, AuthenticationMaskDef, counter, response, cnonce);
+ }
+ else if (!principal && tmp && tmp->Name() && tmp->Hash()) {
+ n = snprintf(Buffer, BufSize, AuthorizedMask, tmp->Name(), tmp->Realm(), nonce, uri, response, opaque,
+ counter, sessAlgo ? "-sess" : "", cnonce);
+ }
+ else {
+ n = snprintf(Buffer, BufSize, UnAuthorizedMask, Credentials.ApplicationRealm(), nonce, opaque, sessAlgo ? "-sess" : "");
+ }
+ return n;
+}
+
+
+// authorization is one line, so conforms to header value. Digest has been broken for readability
+// Digest username="ich oder",
+// realm="Schnarcher@my.box",
+// nonce="59F980BB771C1CC31EE7360C7B06F15D",
+// uri="/favicon.ico",
+// response="7d060b3de37d132e2f4e4b014b127818",
+// opaque="33B9703065AD7E1A1DED1DFE07AA357C",
+// qop=auth,
+// nc=00000001,
+// cnonce="4dd872a6c6debac8"
+void cAuthorization::ParseRawBuffer(const char* Raw)
+{
+ static const char *eyecatch = "Digest";
+
+ if (strncmp(Raw, eyecatch, strlen(eyecatch))) {
+// esyslog("Authentication is not of type Digest! - not supported!");
+
+ return;
+ }
+ char nameBuf[30];
+ char scratch[128];
+ const char *p = Raw + strlen(eyecatch);
+ bool done=false;
+
+ if (tmp) {
+ delete tmp;
+ tmp = NULL;
+ }
+ while (!done) {
+ p = getAttrName(nameBuf, sizeof(nameBuf), p);
+ if (*p != '=') {
+ esyslog("invalid digest format! Expected '=' and found %C (%02X)", *p, *p);
+ return;
+ }
+ p = getValue(scratch, sizeof(scratch), ++p);
+ SetAttribute(nameBuf, scratch);
+
+ if (!p) break;
+ if (*p != ',') break;
+ else ++p;
+ }
+}
+
+void cAuthorization::SetUser(const char *UserID, const char *Password)
+{
+ if (principal) {
+ //TODO: do we really want to support change of user/password on existing principal?
+ }
+ else if (tmp) {
+ tmp->SetName(UserID);
+ tmp->CreateHash(Password);
+ CreateClientHash();
+ }
+}
+
+void cAuthorization::SetAttribute(char* Name, const char* Value)
+{
+ char **p = NULL;
+
+// isyslog("cAuthorization::SetAttribute(\"%s\") => [%s]", Name, Value);
+ if (!strcasecmp(Name, "username")) {
+ if (!tmp) tmp = new cPrincipal(Value, "unset");
+ else tmp->SetName(Value);
+ }
+ else if (!strcasecmp(Name, "realm")) {
+ if (!tmp) tmp = new cPrincipal("unset", Value);
+ else tmp->SetRealm(Value);
+ }
+ else if (!strcasecmp(Name, "algorithm")) {
+ if (!strcmp("MD5-sess", Value)) sessAlgo = true;
+ }
+ else if (!strcasecmp(Name, "nonce")) p = &nonce;
+ else if (!strcasecmp(Name, "uri")) p = &uri;
+ else if (!strcasecmp(Name, "response")) p = &response;
+ else if (!strcasecmp(Name, "opaque")) p = &opaque;
+ else if (!strcasecmp(Name, "cnonce")) p = &cnonce;
+ else if (!strcasecmp(Name, "qop")) {
+ if (!strncmp(Value, "auth", 4)) p = &qop;
+ else esyslog("invalid/unsupported auth method! - only \"auth\" supported!");
+ }
+ else if (!strcasecmp(Name, "nc")) {
+ counter = strtol(Value, NULL, 16);
+ }
+ if (p) {
+ free(*p);
+ *p = strdup(Value);
+ }
+ if (tmp) {
+ principal = Credentials.FindPrincipal(tmp->Name(), tmp->Realm());
+ if (principal) {
+ delete tmp;
+ tmp = NULL;
+ }
+ }
+}
+
+char * cAuthorization::CalculateA1(const char *Username, const char *Password)
+{
+ if (Username && Password) SetUser(Username, Password);
+ char *principalHash = (char *) (principal ? principal->Hash() : tmp->Hash());
+
+ if (sessAlgo) {
+ cMD5Calculator hc;
+
+ hc.AddContent(principalHash);
+ hc.AddContent(":");
+ hc.AddContent(nonce);
+ hc.AddContent(":");
+ hc.AddContent(cnonce);
+
+ return hc.Hash();
+ }
+ return strdup(principalHash);
+}
+
+char * cAuthorization::CalculateA2(const char *Uri)
+{
+ cMD5Calculator hc;
+
+ // don't send method on authorized response
+ if (!principal || strcmp(principal->Name(), "unset")) hc.AddContent(requestMethod2String(method));
+ hc.AddContent(":");
+ hc.AddContent(Uri);
+
+ return hc.Hash();
+}
+
+const char * cAuthorization::CalculateResponse(const char *Uri, const char *Username, const char *Password)
+{
+ free(response);
+ char *a1 = CalculateA1(Username, Password);
+ char *a2 = CalculateA2(Uri ? Uri : uri);
+ cMD5Calculator hc;
+ char buf[12];
+
+ snprintf(buf, sizeof(buf), "%08x", counter);
+ hc.AddContent(a1);
+ hc.AddContent(":");
+ hc.AddContent(nonce);
+ if (qop) {
+ hc.AddContent(":");
+ hc.AddContent(buf);
+ hc.AddContent(":");
+ hc.AddContent(cnonce);
+ hc.AddContent(":");
+ hc.AddContent(qop);
+ }
+ hc.AddContent(":");
+ hc.AddContent(a2);
+
+ response = hc.Hash();
+
+// printf("CalculateResponse: Realm-Digest (A1) =>%s<\n", a1);
+// printf("CalculateResponse: URL-Digest (A2) =>%s<\n", a2);
+// printf("CalculateResponse: Request-Digest =>%s<\n", response);
+
+ free(a1);
+ free(a2);
+
+ return response;
+}
+
+void cAuthorization::Dump(void) const
+{
+ printf(">>>---------- Authorization ------------------\n");
+ if (principal) principal->Dump();
+ else if (tmp) tmp->Dump();
+ else printf("principal is NULL\n");
+ printf("nonce ...: >%s<\n", nonce);
+ printf("method ..: >%s<\n", requestMethod2String(method));
+ printf("uri .....: >%s<\n", uri);
+ printf("response : >%s<\n", response);
+ printf("opaque ..: >%s<\n", opaque);
+ printf("cnonce ..: >%s<\n", cnonce);
+ printf("counter .: >%d<\n", counter);
+ printf("============= Authorization ===============<<<\n");
+}
+
+// --- Authorizations ---------------------------------------------------------
+
+static void freeAuthorizationCallback(void *elem)
+{
+ delete (cAuthorization *)elem;
+}
+
+cAuthorizations::cAuthorizations()
+ : cManagedVector(freeAuthorizationCallback)
+{
+}
+
+cAuthorizations::~cAuthorizations()
+{
+}
+
+cAuthorization *cAuthorizations::FindAuthorization(const char *SessionID)
+{
+ cAuthorization *a;
+
+ for (size_t i=0; i < size(); ++i) {
+ a = (cAuthorization *) (*this)[i];
+ if (!strcmp(a->Opaque(), SessionID)) return a;
+ }
+ return NULL;
+}
+
+const cAuthorization &cAuthorizations::CreateAuthorization(const cHTTPRequest &originalRequest, const cConnectionPoint &client, unsigned long connectionNumber)
+{
+ cAuthorization *rv = new cAuthorization(originalRequest, CreateNOnce(client, connectionNumber));
+
+ push_back(rv);
+
+ return *rv;
+}
+
+char *cAuthorizations::CreateNOnce(const cConnectionPoint &client, unsigned long connectionNumber)
+{
+ char buf[40];
+ cMD5Calculator hc;
+
+ snprintf(buf, sizeof(buf), "%lu:%lu", connectionNumber, random());
+
+ hc.AddContent(buf);
+ hc.AddContent(":");
+ hc.AddContent(client.HostName());
+
+ return hc.Hash();
+}
+
+char *cAuthorizations::CreateSessionID(const cHTTPRequest &OriginalRequest, time_t AuthTime)
+{
+ char buf[40];
+ cMD5Calculator hc;
+ const char *p0, *p1;
+
+ snprintf(buf, sizeof(buf), "%lu", AuthTime);
+
+ p0 = OriginalRequest.ClientHost();
+ p1 = OriginalRequest.UserAgent();
+
+ hc.AddContent(p0 ? p0 : "localhost");
+ hc.AddContent(":");
+ hc.AddContent(buf);
+ hc.AddContent(":");
+ hc.AddContent(p1 ? p1 : "unknown");
+
+ return hc.Hash();
+}
+
+void cAuthorizations::Del(cAuthorization *Auth2Invalidate)
+{
+//TODO:
+} \ No newline at end of file
diff --git a/libs/networking/src/ClientSocket.cc b/libs/networking/src/ClientSocket.cc
new file mode 100644
index 0000000..db42cf9
--- /dev/null
+++ b/libs/networking/src/ClientSocket.cc
@@ -0,0 +1,45 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ClientSocket.cc
+ * Created: 4. Juli 2012, 07:25
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ClientSocket.h>
+
+cClientSocket::cClientSocket(const char *ServerName, int Port)
+ : cAbstractSocket(ServerName, Port)
+{
+}
+
+cClientSocket::~cClientSocket()
+{
+}
+
+bool cClientSocket::Connect(void)
+{
+ return cAbstractSocket::Connect();
+}
+
+void cClientSocket::Close(void)
+{
+ cAbstractSocket::Close();
+}
+
diff --git a/libs/networking/src/ConnectionHandler.cc b/libs/networking/src/ConnectionHandler.cc
new file mode 100644
index 0000000..c5d5ebf
--- /dev/null
+++ b/libs/networking/src/ConnectionHandler.cc
@@ -0,0 +1,393 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ConnectionHandler.cc
+ * Created: 4. Juli 2012, 07:32
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ConnectionHandler.h>
+#include <ServerSocket.h>
+#include <HTTPRequest.h>
+#include <HTTPFileResponse.h>
+#include <HTTPAuthorizationRequest.h>
+#include <HTTPRequestHandler.h>
+#include <Authorization.h>
+#include <Credentials.h>
+#include <MD5Calculator.h>
+#include <StringBuilder.h>
+#include <TimeMs.h>
+#include <Logging.h>
+#include <util.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <iostream>
+#include <tr1/unordered_map>
+
+static unsigned long connectionCounter = 0;
+class cHTTPRequestHandlers {
+public:
+ typedef std::tr1::unordered_map<std::string, cHTTPRequestHandler *>::iterator iterator;
+ cHTTPRequestHandlers();
+ ~cHTTPRequestHandlers();
+
+ cHTTPRequestHandler *Handler(const char *UrlPrefix);
+ void SetHandler(const char *UrlPrefix, cHTTPRequestHandler *Handler);
+ cHTTPRequestHandler *DefaultHandler(void) { return defaultHandler; }
+ void SetDefaultHandler(cHTTPRequestHandler *Handler) { defaultHandler = Handler; }
+
+ cHTTPRequestHandlers::iterator begin() { return internalMap.begin(); }
+ cHTTPRequestHandlers::iterator end() { return internalMap.end(); }
+
+private:
+ cHTTPRequestHandler *defaultHandler;
+ std::tr1::unordered_map<std::string, cHTTPRequestHandler *> internalMap;
+ };
+
+cHTTPRequestHandlers::cHTTPRequestHandlers()
+ : defaultHandler(NULL)
+{
+}
+
+cHTTPRequestHandlers::~cHTTPRequestHandlers()
+{
+ cHTTPRequestHandlers::iterator it = internalMap.begin();
+
+ while (it != internalMap.end()) {
+ delete it->second;
+ ++it;
+ }
+ if (defaultHandler) delete defaultHandler;
+}
+
+cHTTPRequestHandler *cHTTPRequestHandlers::Handler(const char* UrlPrefix)
+{
+ cHTTPRequestHandlers::iterator it = internalMap.find(UrlPrefix);
+
+ if (it == internalMap.end()) return NULL;
+ return it->second;
+}
+
+void cHTTPRequestHandlers::SetHandler(const char* UrlPrefix, cHTTPRequestHandler* Handler)
+{
+ Handler->SetID(UrlPrefix);
+ internalMap[UrlPrefix] = Handler;
+}
+static cHTTPRequestHandlers registeredHandlers;
+
+cConnectionHandler::cConnectionHandler(cConnectionPoint &Client, cServerConfig &Config, bool StayConnected)
+ : config(Config)
+ , client(Client)
+ , connectionNumber(++connectionCounter)
+ , bufSize(2048)
+ , scratch(NULL)
+ , nonce(NULL)
+ , stayConnected(StayConnected)
+{
+}
+
+cConnectionHandler::~cConnectionHandler()
+{
+ Cancel();
+}
+
+void cConnectionHandler::Action()
+{
+ if (!scratch) scratch = (char *)malloc(bufSize);
+ if (!scratch) {
+ esyslog("failed to allocate scratch buffer of size %ld", bufSize);
+ return;
+ }
+ cHTTPRequest *request;
+ cHTTPResponse *response = NULL;
+ uint64_t start, end;
+ size_t nTrans;
+
+ isyslog("ConnectionHandler::Action() - start the loop");
+ while (Running()) {
+ memset(scratch, 0, bufSize);
+
+ // process at least one request
+ isyslog("read next request from Client");
+ nTrans = read(client.Socket(), scratch, bufSize);
+ if (nTrans < 1) {
+ esyslog("failed to read client-Request! End of this connection handler ... #%d", errno);
+ return;
+ }
+ start = cTimeMs::Now();
+ if (nTrans == bufSize) {
+ char *p = scratch + nTrans;
+
+ bufSize += 2048;
+ scratch = (char *) realloc(scratch, bufSize);
+ nTrans += read(client.Socket(), p, 2048);
+
+ //TODO: should we support multiple buffer resize?
+ if (nTrans == bufSize) {
+ esyslog("OUPS - buffer overflow? - Lets stop this connection handler ...");
+ return;
+ }
+ }
+ isyslog("#%lu - got client request |>%s<|", connectionNumber, scratch);
+
+ request = new cHTTPRequest(scratch);
+ if (!request) {
+ esyslog("ERROR: failed to parse request from client!");
+ response = new cHTTPResponse(HTTP_NotAcceptable);
+ }
+ else {
+ isyslog("got request from client (%ld bytes) %s", nTrans, request->Url().Path());
+
+ if (AuthorizationRequired()) {
+ if (request->Authorization()) {
+ char *url = request->Url().ToString();
+
+ for (EVER) {
+ //TODO: 1, check uri from request against uri from auth
+ if (strcmp(request->Authorization()->Uri(), url)) {
+ esyslog("ATTENTION - security attack! URI mismatch between request and authorization header!");
+ response = new cHTTPResponse(HTTP_BadRequest);
+ break;
+ }
+
+ //TODO: 2. search user/principal
+ cAuthorization *auth = Authorizations().FindAuthorization(request->Authorization()->Opaque());
+
+ if (!auth) {
+ response = new cHTTPAuthorizationRequest(Authorizations().CreateAuthorization(*request, client, connectionNumber));
+ esyslog("Huh? - didn't find a matching authorization, but client sent authorization header. Something went wrong!");
+ break;
+ }
+
+ //TODO: 3. check auth->principal->hash against hash from found principal
+ if (IsAuthorizationValid(auth, *request))
+ response = ProcessRequest(*request);
+ if (!response) {
+ //TODO: 406 or should we create a new authorization request?
+ response = new cHTTPResponse(HTTP_NotAcceptable);
+ }
+ break;
+ }
+ free(url);
+ }
+ else {
+ //TODO: create authorization request
+ response = new cHTTPAuthorizationRequest(Authorizations().CreateAuthorization(*request, client, connectionNumber));
+ }
+ }
+ else response = ProcessRequest(*request);
+ }
+ TransferResponse(response);
+ delete response;
+ delete request;
+ response = NULL;
+ request = NULL;
+ end = cTimeMs::Now();
+ isyslog("processing of request took %ld ms.", (end - start));
+
+ isyslog("check IO status ...");
+ if (!client.IOWait(500)) {
+ if (!StayConnected()) {
+ isyslog(" >>> connection timed out without any data <<<");
+ break; // leave temporary connections after timeout
+ }
+ }
+ }
+ Cancel();
+}
+
+void cConnectionHandler::Cancel(int WaitSeconds)
+{
+ dsyslog("Ok, lets close the client socket ...");
+ client.Close();
+ FREE(scratch);
+ FREE(nonce);
+}
+
+bool cConnectionHandler::IsAuthorizationValid(cAuthorization *ServerAuth, const cHTTPRequest &request)
+{
+ // Auth is the authorization based on opaque value from request->auth (session-ID)
+ // check other values from auth/request too
+ const cAuthorization *ClientAuth = request.Authorization();
+ const cPrincipal *principal = ServerAuth->Principal();
+
+ if (!principal || !strcmp(ServerAuth->UserID(), "unset"))
+ principal = Credentials.FindPrincipal(ClientAuth->UserID(), ClientAuth->Realm());
+
+ for (EVER) {
+ if (!principal) {
+ esyslog("username or realm is unknown");
+ break;
+ }
+ if (strcmp(ClientAuth->UserID(), principal->Name()) || strcmp(ClientAuth->Realm(), principal->Realm())) {
+ esyslog("username or realm did not match authenticated session");
+ break;
+ }
+ if (strcmp(principal->Hash(), ClientAuth->UserCredential())) {
+ esyslog("password given was invalid");
+ break;
+ }
+ cAuthorization *authCheck = new cAuthorization(principal, request.Method(), *ClientAuth);
+ const char *authHash = authCheck->CalculateResponse();
+
+ if (strcmp(authHash, ClientAuth->Response())) {
+ delete authCheck;
+ break;
+ }
+
+ if (strcmp(ServerAuth->UserID(), principal->Name())) {
+ // validation passed, so remember authorized user
+ ServerAuth->SetPrincipal(principal);
+ }
+ delete authCheck;
+
+ return true;
+ }
+ // validation of authorization failed, so remove any existing authorization from this session
+ Authorizations().Del(ServerAuth);
+
+ return false;
+}
+
+cHTTPResponse *cConnectionHandler::ProcessRequest(cHTTPRequest &Request)
+{
+ cHTTPResponse *res = NULL;
+
+ isyslog("ConnectionHandler::ProcessRequest: %s", Request.Url().Path());
+ if (!strcmp(Request.Url().Path(), "/stop")) {
+ ServerSocket().SetActive(false);
+ res = new cHTTPResponse(HTTP_Gone);
+ }
+ else if (!strcmp(Request.Url().Path(), "/favicon.ico")) {
+ res = new cHTTPFileResponse(config.AppIconPath());
+ }
+ else if (!strcmp(Request.Url().Path(), "/help")) {
+ cHTTPResponse *ir = new cHTTPResponse();
+
+ isyslog("start assembling usage message ...");
+ Usage(ir->StringBuilder());
+
+ ir->StringBuilder().Append("<hr>").Append(ir->ServerID()).Append(" ").Append(config.DocumentRoot());
+ isyslog("assembling of usage message done - let's send it to client ...");
+ ir->SetContentType("text/html");
+ ir->SetContentSize(ir->StringBuilder().Size());
+ res = ir;
+ }
+ else {
+ cHTTPRequestHandler *rh = registeredHandlers.Handler(Request.Url().Path());
+
+ if (rh) res = rh->ProcessRequest(Request);
+ if (!rh || !res) {
+ rh = registeredHandlers.DefaultHandler();
+
+ if (rh) res = rh->ProcessRequest(Request);
+ }
+ }
+ if (!res) res = new cHTTPResponse(HTTP_NotFound);
+
+ return res;
+}
+
+void cConnectionHandler::Usage(cStringBuilder& sb)
+{
+ cHTTPRequestHandlers::iterator it = registeredHandlers.begin();
+
+ isyslog("start of cConnectionHandler::Usage() ...");
+ sb.Append("<h2>Media server</h2><p>serves media files to remote/client media-players. Those ");
+ sb.Append("media-player should support the http-protocol. Opposed to well known http-servers, this ");
+ sb.Append("server handles multifile media transparently for the client.</p>");
+ sb.Append("<h3>supported requests:</h3>");
+ sb.Append("<dl>");
+
+ while (it != registeredHandlers.end()) {
+ sb.Append("<dt><br/><em>");
+ sb.Append(it->first.c_str());
+ sb.Append("</em></dt><dd>");
+ it->second->Usage(sb);
+ sb.Append("</dd>");
+ ++it;
+ }
+ if (registeredHandlers.DefaultHandler()) {
+ sb.Append("<dt><br/><em>");
+ sb.Append("default");
+ sb.Append("</em></dt><dd>");
+ registeredHandlers.DefaultHandler()->Usage(sb);
+ sb.Append("</dd>");
+ sb.Append("</dl>");
+ }
+ isyslog("end of cConnectionHandler::Usage() ...");
+}
+
+void cConnectionHandler::TransferResponse(cHTTPResponse *Response)
+{
+ if (!Response) {
+ esyslog("OUPS - should not happen!!! - Response was empty!");
+ close(client.Socket());
+
+ return;
+ }
+//#ifdef DEBUG
+// static int responseCounter = 0;
+// char filename[64] = {0};
+// sprintf(filename, "/tmp/rednose%03d", ++responseCounter);
+//#endif
+
+ memset(scratch, 0, bufSize);
+
+//#ifdef DEBUG
+// int fdClient = open(filename, O_WRONLY | O_CREAT);
+//#else
+ int fdClient = client.Socket();
+//#endif
+ isyslog("gonna sent message to client (Socket #%d)", fdClient);
+
+ int nRaw = Response->WritePrefix(scratch, bufSize);
+ int nTrans = send(fdClient, scratch, nRaw, MSG_NOSIGNAL);
+ size_t total = 0;
+
+ if (nTrans != nRaw) esyslog("ERROR: failed to transmit response header! (%d <> %d)", nRaw, nTrans);
+ while ((nRaw = Response->ReadContentChunk(scratch, bufSize)) > 0) {
+ int nTrans = send(fdClient, scratch, nRaw, MSG_NOSIGNAL);
+
+ if (nTrans < 1) {
+ esyslog("failed to transmit chunk. Error #%d", errno);
+ break;
+ }
+ total += nTrans;
+ if (nTrans == nRaw) isyslog("successfully written message chunk of %d bytes", nTrans);
+ else esyslog("failed to transmit response chunk (%d <> %d)", nRaw, nTrans);
+ }
+ if (total != Response->ContentSize())
+ esyslog("failed to transfer response - should be %ld, was %ld", Response->ContentSize(), total);
+//#ifdef DEBUG
+// close(fdClient);
+//#endif
+}
+
+void cConnectionHandler::RegisterDefaultHandler(cHTTPRequestHandler *DefaultHandler)
+{
+ registeredHandlers.SetDefaultHandler(DefaultHandler);
+}
+
+void cConnectionHandler::RegisterRequestHandler(const char *UrlPrefix, cHTTPRequestHandler *RequestHandler)
+{
+ registeredHandlers.SetHandler(UrlPrefix, RequestHandler);
+}
diff --git a/libs/networking/src/ConnectionPoint.cc b/libs/networking/src/ConnectionPoint.cc
new file mode 100644
index 0000000..4700652
--- /dev/null
+++ b/libs/networking/src/ConnectionPoint.cc
@@ -0,0 +1,89 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ConnectionPoint.cc
+ * Created: 4. Juli 2012, 06:29
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ConnectionPoint.h>
+#include <util.h>
+#include <poll.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+cConnectionPoint::cConnectionPoint(const char *NameOrIP, int Port, const char *RealName)
+ : nameOrIP(strdup(NameOrIP))
+ , realName(RealName ? strdup(RealName): NULL)
+ , combined(NULL)
+ , port(Port)
+ , sock(-1)
+{
+}
+
+cConnectionPoint::~cConnectionPoint()
+{
+ Close();
+}
+
+void cConnectionPoint::Close()
+{
+ if (sock > 0) {
+ close(sock);
+ sock = -1;
+ }
+ FREE(nameOrIP);
+ FREE(realName);
+ FREE(combined);
+}
+
+void cConnectionPoint::SetRealName(const char *Name)
+{
+ FREE(realName);
+ realName = Name ? strdup(Name) : NULL;
+}
+
+int cConnectionPoint::IOWait(long MilliSeconds)
+{
+ struct pollfd fds;
+
+ fds.fd = sock;
+ fds.events = POLLIN | POLLPRI;
+
+ int rv = poll(&fds, 1, MilliSeconds);
+
+ if (rv > 0) return fds.revents; // so app can ask for priority events
+ return rv;
+}
+
+const char *cConnectionPoint::AssembleCombined() const
+{
+ FREE(combined);
+ size_t len = strlen(nameOrIP) + 16;
+
+ if (realName) len += strlen(realName);
+ char *p = (char *)malloc(len);
+
+ if (realName) snprintf(p, len, "%s:%d (%s)", nameOrIP, port, realName);
+ else snprintf(p, len, "%s:%d", nameOrIP, port);
+ if (p) ((cConnectionPoint *)this)->combined = p;
+
+ return combined;
+}
diff --git a/libs/networking/src/Credentials.cc b/libs/networking/src/Credentials.cc
new file mode 100644
index 0000000..db1e219
--- /dev/null
+++ b/libs/networking/src/Credentials.cc
@@ -0,0 +1,171 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Credentials.cc
+ * Created: 3. Juli 2012, 14:37
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Credentials.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+cCredentials Credentials;
+static const char *appRealm = NULL;
+
+cCredentials::cCredentials()
+{
+}
+
+cCredentials::~cCredentials()
+{
+ Clear();
+}
+
+void cCredentials::Clear()
+{
+ iterator it = internalMap.begin();
+
+ while (it != internalMap.end()) {
+ delete it->second;
+ ++it;
+ }
+}
+
+const char *cCredentials::ApplicationRealm() const
+{
+ return appRealm;
+}
+
+const cPrincipal *cCredentials::FindPrincipal(const char* Name, const char* Realm)
+{
+ std::string tmp = Name;
+ cPrincipal *rv = internalMap[tmp];
+
+ if (!strcmp(rv->Name(), Name) && !strcmp(rv->Realm(), Realm)) return rv;
+ return NULL;
+}
+
+void cCredentials::SetApplicationRealm(const char* ApplicationRealm)
+{
+ appRealm = ApplicationRealm;
+}
+
+void cCredentials::Put(const char* Key, cPrincipal* p)
+{
+ internalMap[Key] = p;
+}
+
+cPrincipal *cCredentials::Get(const char* Key)
+{
+ iterator it = internalMap.find(Key);
+
+ if (it != internalMap.end()) return it->second;
+ return NULL;
+}
+
+int cCredentials::Load(const char *FileName)
+{
+ char buf[256];
+ FILE *fp = fopen(FileName, "r");
+ cPrincipal *principal = NULL;
+ char *chunk = buf;
+ int principalsProcessed = 0;
+ int bytesRead = 0;
+
+ if (!fp) {
+ //TODO: verbose message?
+ return 0;
+ }
+ while ((bytesRead = fread(chunk, sizeof(char), sizeof(buf) - (chunk - buf), fp)) > 0) {
+ char *endOfLine = index(buf, '\n');
+
+ while (chunk && endOfLine) {
+ principal = parsePrincipal(chunk, endOfLine - chunk);
+ if (!principal) break;
+ std::string userid = principal->Name();
+
+ internalMap[userid] = principal;
+ ++principalsProcessed;
+ chunk = endOfLine < (buf + sizeof(buf)) ? endOfLine + 1 : NULL;
+ endOfLine = index(chunk, '\n');
+ }
+ // shift rest of buffer down and read a smaller chunk
+ if (chunk && !endOfLine) {
+ int rest = sizeof(buf) - (chunk - buf);
+
+ memmove(buf, chunk, rest);
+ chunk = buf + rest;
+ }
+ }
+ fclose(fp);
+
+ return principalsProcessed;
+}
+
+cPrincipal *cCredentials::parsePrincipal(char* buf, size_t bufSize)
+///< format is: name:hash:age:extendedInfo
+{
+ if (!buf || !*buf || bufSize < 30) return NULL;
+ cPrincipal *rv = NULL;
+ char *hash = index(buf, ':') + 1;
+ char *age = index(hash, ':') + 1;
+ char *xi = index(age, ':') + 1;
+
+ if (hash == (char *)1 || !*hash) return NULL;
+ if (age == (char *)1 || !*age) return NULL;
+ if (xi == (char *)1 || !*xi) return NULL;
+
+ *(hash - 1) = 0;
+ *(age - 1) = 0;
+ *(xi - 1) = 0;
+ *(buf + bufSize - 1) = 0;
+
+ rv = new cPrincipal(buf, ApplicationRealm());
+ if (rv) {
+ rv->SetHash(hash);
+ rv->SetAge(atoi(age));
+ rv->SetExtendedInfo(xi);
+ }
+ return rv;
+}
+
+int cCredentials::Store(const char* FileName)
+{
+ FILE *fp = fopen(FileName, "w");
+ cPrincipal *p;
+ int principalsProcessed = 0;
+
+ if (!fp) {
+ //TODO: verbose message?
+ return 0;
+ }
+ cCredentials::const_iterator principals = begin();
+
+ while (principals != end()) {
+ p = principals->second;
+ fprintf(fp, "%s:%s:%d:%s\n", p->Name(), p->Hash(), p->Age(), p->ExtendedInfo() ? p->ExtendedInfo() : " ");
+ ++principalsProcessed;
+ ++principals;
+ }
+ fclose(fp);
+
+ return principalsProcessed;
+} \ No newline at end of file
diff --git a/libs/networking/src/HTTPAuthorizationRequest.cc b/libs/networking/src/HTTPAuthorizationRequest.cc
new file mode 100644
index 0000000..5c558f8
--- /dev/null
+++ b/libs/networking/src/HTTPAuthorizationRequest.cc
@@ -0,0 +1,47 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPAuthorizationRequest.cc
+ * Created: 4. Juli 2012, 07:41
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPAuthorizationRequest.h>
+#include <Authorization.h>
+#include <HTTPRequest.h>
+#include <stddef.h>
+
+cHTTPAuthorizationRequest::cHTTPAuthorizationRequest(const cHTTPRequest &OriginalRequest, char *NOnceFromHeap)
+ : cHTTPResponse(HTTP_UnAuthorized)
+{
+ SetHeader("Connection", "Close");
+ SetAuthorization(new cAuthorization(OriginalRequest, NOnceFromHeap ? strdup(NOnceFromHeap) : NULL));
+}
+
+cHTTPAuthorizationRequest::cHTTPAuthorizationRequest(const cAuthorization &Authorization)
+ : cHTTPResponse(HTTP_UnAuthorized)
+{
+ SetHeader("Connection", "Close");
+ SetAuthorization(new cAuthorization(Authorization));
+}
+
+cHTTPAuthorizationRequest::~cHTTPAuthorizationRequest()
+{
+}
+
diff --git a/libs/networking/src/HTTPFileResponse.cc b/libs/networking/src/HTTPFileResponse.cc
new file mode 100644
index 0000000..d79b085
--- /dev/null
+++ b/libs/networking/src/HTTPFileResponse.cc
@@ -0,0 +1,102 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPFileResponse.cc
+ * Created: 4. Juli 2012, 07:50
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPFileResponse.h>
+#include <Logging.h>
+#include <util.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+cHTTPFileResponse::cHTTPFileResponse(const char *RealPath)
+ : cHTTPResponse(HTTP_OK)
+ , realPath(RealPath)
+ , fd(0)
+{
+ DetermineTypeAndSize(realPath);
+}
+
+cHTTPFileResponse::cHTTPFileResponse()
+ : cHTTPResponse(HTTP_OK)
+ , realPath(NULL)
+ , fd(0)
+{
+}
+
+cHTTPFileResponse::~cHTTPFileResponse()
+{
+}
+
+void cHTTPFileResponse::DetermineTypeAndSize(const char* Path)
+{
+ struct stat st;
+ const char *xt;
+
+ if (!Path) return;
+ if (stat(Path, &st) < 0) {
+ esyslog("invalid path given - %d", errno);
+ return;
+ }
+ SetContentSize(st.st_size);
+ xt = strrchr(Path, '.');
+ if (!xt) SetContentType(MT_Unknown);
+ ++xt;
+
+ // File response serves only simple files, like tiny webservers
+ if (!strcasecmp("html", xt)) SetContentType(MT_Html);
+ else if (!strcasecmp("css", xt)) SetContentType(MT_CSS);
+ else if (!strcasecmp("js", xt)) SetContentType(MT_JavaScript);
+ else if (!strcasecmp("ico", xt)) SetContentType(MT_Ico);
+ else if (!strcasecmp("gif", xt)) SetContentType(MT_Gif);
+ else if (!strcasecmp("png", xt)) SetContentType(MT_Png);
+ else if (!strcasecmp("jpg", xt)) SetContentType(MT_Jpg);
+ else if (!strcasecmp("jpeg", xt)) SetContentType(MT_Jpg);
+ else if (!strcasecmp("dtd", xt)) SetContentType(MT_XmlDtd);
+ else if (!strcasecmp("xml", xt)) SetContentType(MT_Xml);
+}
+
+size_t cHTTPFileResponse::ReadContentChunk(char* Buf, size_t bufSize)
+{
+ long rv = 0;
+
+ if (fd < 1) {
+ fd = open(RealPath(), O_RDONLY | O_LARGEFILE);
+ if (fd < 1) {
+ esyslog("could not open requested path %s - Error #%d", RealPath(), errno);
+ return 0;
+ }
+ }
+ isyslog("have filehandle #%d (%s)", fd, RealPath());
+ if ((rv = read(fd, Buf, bufSize)) < 0)
+ esyslog("ERROR: failed to read from file %s #%d", RealPath(), errno);
+ else
+ isyslog("read %u bytes from file", rv);
+ if (rv < (long) bufSize) { // most probabely end of file
+ close(fd);
+ }
+ return rv;
+}
diff --git a/libs/networking/src/HTTPMessage.cc b/libs/networking/src/HTTPMessage.cc
new file mode 100644
index 0000000..9e1b5ba
--- /dev/null
+++ b/libs/networking/src/HTTPMessage.cc
@@ -0,0 +1,165 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPMessage.cc
+ * Created: 3. Juli 2012, 17:40
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPMessage.h>
+#include <Authorization.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <util.h>
+
+static void freeHeaderCallback(void *elem)
+{
+ free(elem);
+}
+
+cHTTPMessage::cHTTPMessage(HTTPProtocol Proto)
+ : protocol(Proto)
+ , timeStamp(0)
+ , header(freeHeaderCallback)
+ , auth(NULL)
+ , contentSize(0)
+ , contentType(NULL)
+{
+}
+
+cHTTPMessage::~cHTTPMessage()
+{
+ if (auth) delete auth;
+ FREE(contentType);
+}
+
+char *cHTTPMessage::FormatTime(time_t timeStamp)
+{
+ struct tm *t = gmtime(&timeStamp);
+ char buf[128];
+
+ strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", t);
+
+ return strdup(buf);
+}
+
+void cHTTPMessage::SetHeader(const char *Name, const char *Value)
+{
+ header.put(Name, Value ? strdup(Value) : NULL);
+}
+
+const char *cHTTPMessage::GetHeader(const char* Name) const
+{
+ return (const char *) header.get(Name);
+}
+
+size_t cHTTPMessage::WritePrefix(char *Buffer, size_t BufSize)
+///< writes message prefix to existing buffer. Prefix is the message without
+///< the content body, so internal and external content will be processed
+///< separately.
+///< IMPORTANT: content size and content type has to be set before this call!
+///< or this information needs to be added by custom call.
+{
+ cManagedMap::const_iterator it = Headers().begin();
+ size_t n = WriteFirstLine(Buffer, BufSize);
+
+ strcpy(Buffer + n, "Date: ");
+ n += 6;
+ n += WriteTime(Buffer + n, BufSize - n);
+ while (it != Headers().end()) {
+ n += snprintf(Buffer + n, BufSize - n, "%s: %s\r\n", it->first.c_str(), (const char *) it->second);
+ ++it;
+ }
+ if (auth) n += auth->Write(Buffer + n, BufSize - n);
+ if (ContentSize() > 0) {
+ n += snprintf(Buffer + n, BufSize - n, "Content-Type: %s\r\n", ContentType());
+ n += snprintf(Buffer + n, BufSize - n, "Content-Length: %ld\r\n", ContentSize());
+ if (n < BufSize - 3) {
+ Buffer[n++] = '\n'; // this is the separator between header and content!
+ Buffer[n] = 0;
+ }
+ }
+ return n;
+}
+
+int cHTTPMessage::WriteTime(char *Buffer, size_t BufSize)
+{
+ if (!timeStamp) timeStamp = time(NULL);
+ struct tm *t = gmtime(&timeStamp);
+
+ return strftime(Buffer, BufSize, "%a, %d %b %Y %H:%M:%S GMT\r\n", t);
+}
+
+void cHTTPMessage::Reset()
+{
+ header.clear();
+ contentSize = 0;
+}
+
+size_t cHTTPMessage::ContentSize() const
+{
+ return contentSize;
+}
+
+void cHTTPMessage::SetContentType(const char* ContentType)
+{
+ FREE(contentType);
+ contentType = ContentType ? strdup(ContentType) : NULL;
+}
+
+void cHTTPMessage::SetAuthorization(cAuthorization* Authorization)
+{
+ if (auth) {
+ delete auth;
+ auth = NULL;
+ }
+ auth = Authorization;
+}
+
+const char *cHTTPMessage::ProtocolString(void) {
+ switch (protocol) {
+ case HTTP_1_0: return "HTTP/1.0";
+ case HTTP_1_1: return "HTTP/1.1";
+ default: return "Unknown/Unsupported";
+ }
+}
+
+void cHTTPMessage::Dump(void )
+{
+ cManagedMap::const_iterator it = Headers().begin();
+ char buf[1024];
+
+ WriteFirstLine(buf, sizeof(buf));
+ printf("=========== Dump HTTP message ==============\n");
+ printf("Protocol: %s\n", ProtocolString());
+ printf("first line: %s\n", buf);
+ printf("header entries:\n");
+ while (it != Headers().end()) {
+ printf("\t[%s] ==> >|%s|<\n", it->first.c_str(), (const char *) it->second);
+ ++it;
+ }
+ if (auth) auth->Dump();
+ if (ContentSize()) {
+ printf("---------- content (%ld Bytes of type %s) -------------\n"
+ , ContentSize(), ContentType());
+ }
+ else printf(">>> NO Content!\n");
+ printf("========== End Dump HTTP message ===========\n");
+}
+
diff --git a/libs/networking/src/HTTPParser.cc b/libs/networking/src/HTTPParser.cc
new file mode 100644
index 0000000..2fc1dad
--- /dev/null
+++ b/libs/networking/src/HTTPParser.cc
@@ -0,0 +1,42 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPParser.cc
+ * Created: 10. Juli 2012, 08:37
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPParser.h>
+#include <HTTPRequest.h>
+#include <HTTPResponse.h>
+#include <string.h>
+
+cHTTPParser::cHTTPParser()
+{
+}
+
+cHTTPParser::~cHTTPParser()
+{
+}
+
+cHTTPMessage *cHTTPParser::ParseMessage(const char* MessageBuf)
+{
+ if (!strncmp("HTTP", MessageBuf, 4)) return new cHTTPResponse(MessageBuf);
+ return new cHTTPRequest(MessageBuf);
+}
diff --git a/libs/networking/src/HTTPRequest.cc b/libs/networking/src/HTTPRequest.cc
new file mode 100644
index 0000000..c17b29c
--- /dev/null
+++ b/libs/networking/src/HTTPRequest.cc
@@ -0,0 +1,171 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPRequest.cc
+ * Created: 3. Juli 2012, 17:54
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPRequest.h>
+#include <HTTPResponse.h>
+#include <Authorization.h>
+#include <Principal.h>
+#include <Logging.h>
+#include <util.h>
+#include <stdio.h>
+
+
+cHTTPRequest::cHTTPRequest(const char *MessageBuf)
+ : method(INVALID)
+ , url(NULL)
+{
+ ParseMessage(MessageBuf);
+}
+
+cHTTPRequest::cHTTPRequest(cHTTPRequest::HTTPRequestMethod Method, const char* Url)
+ : method(Method)
+ , url(Url)
+{
+}
+
+cHTTPRequest::cHTTPRequest(const cHTTPResponse &res, const char *Url)
+ : method(cHTTPRequest::GET)
+ , url(Url)
+{
+ SetAuthorization(new cAuthorization(*res.Authorization()));
+ Authorization()->SetUri(Url);
+}
+
+
+cHTTPRequest::~cHTTPRequest()
+{
+}
+
+const char *requestMethod2String(cHTTPRequest::HTTPRequestMethod Method)
+{
+ switch (Method) {
+ case cHTTPRequest::GET: return "GET";
+ case cHTTPRequest::POST: return "POST";
+ default: return "unknown/unsupported";
+ }
+}
+
+void cHTTPRequest::SetURL(const char *Url)
+{
+ url.ParseURL(Url);
+}
+
+const char *cHTTPRequest::ClientHost(void ) const
+{
+ return (const char *) Headers().get("Host");
+}
+
+const char *cHTTPRequest::UserAgent() const
+{
+ return (const char *) Headers().get("User-Agent");
+}
+
+void cHTTPRequest::SetUser(const char *UserID, const char *Password)
+{
+ char *uri = Url().ToString();
+ this->Authorization()->CalculateResponse(uri, UserID, Password);
+ free(uri);
+}
+
+static const char *fetchLine(char *Buf, int BufSize, const char *Source)
+{
+ const char *end = strchr(Source, '\r');
+ int len = 0;
+
+ if (!end) end = strchr(Source, '\n');
+ if (!end) end = Source + strlen(Source);
+ len = end - Source;
+ if (len > BufSize) len = BufSize - 1;
+
+ strncpy(Buf, Source, len);
+ Buf[len] = 0;
+ end = Source + len;
+
+ return end;
+}
+
+void cHTTPRequest::ParseMessage(const char *RequestBuf)
+{
+ char scratch[512];
+ const char *start = RequestBuf, *end = strchr(start, ' ');
+ const char *name;
+ char *value;
+
+ if (strncasecmp("GET", start, end - start)) SetMethod(GET);
+ else if (strncasecmp("POST", start, end - start)) SetMethod(POST);
+ start = end;
+ while (*start == ' ') ++start;
+ end = strchr(start, ' ');
+// printf("request-URI %*.*s\n", (int)(end - start), (int)(end - start), start);
+ if ((end - start) >= (int)sizeof(scratch)) {
+ esyslog("URI exhausted buffer - abort request!");
+ return;
+ }
+ else {
+ strncpy(scratch, start, end - start);
+ scratch[end - start] = 0;
+ SetURL(scratch);
+ }
+ start = end;
+ while (*start == ' ') ++start;
+ end = strchr(start, '\r');
+ if (!end) end = strchr(start, '\n');
+// printf("http-protocol %*.*s\n", (int)(end - start), (int)(end - start), start);
+ if (!strncmp("HTTP/1.1", start, end - start)) SetProtocol(HTTP_1_1);
+ else SetProtocol(HTTP_1_0);
+
+ for (start = end; start && *start; start = end) {
+ if (*start == '\r') ++start;
+ if (*start == '\n') ++start;
+ if (!*start) break;
+ end = fetchLine(scratch, sizeof(scratch), start);
+// printf("a line from request (%03d) [%s]\n", strlen(scratch), scratch);
+
+ name = scratch;
+ value = strchr((char *)name, ':');
+ if (value) {
+ if (value) *value++ = 0;
+ if (*value == ' ') *value++ = 0;
+
+ SetHeader(name, value);
+ }
+ else {
+// printf("possibly end of header ...\n");
+ continue;
+ }
+// printf("\nresult - name [%s] => |>%s<|\n", name, value);
+ }
+}
+
+size_t cHTTPRequest::WriteFirstLine(char* Buffer, size_t BufSize)
+{
+ size_t n = snprintf(Buffer, BufSize, "%s ", requestMethod2String(Method()));
+ int tmp = url.WriteBuf(Buffer + n, BufSize - n);
+
+ if (tmp > 0) n += tmp;
+ n += snprintf(Buffer + n, BufSize - n, " %s\n", ProtocolString());
+
+ return n;
+}
+
diff --git a/libs/networking/src/HTTPRequestHandler.cc b/libs/networking/src/HTTPRequestHandler.cc
new file mode 100644
index 0000000..60ce8d9
--- /dev/null
+++ b/libs/networking/src/HTTPRequestHandler.cc
@@ -0,0 +1,43 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPRequestHandler.cc
+ * Created: 4. Juli 2012, 15:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPRequestHandler.h>
+#include <string.h>
+#include <util.h>
+
+cHTTPRequestHandler::cHTTPRequestHandler()
+ : prefix(NULL)
+{
+}
+
+cHTTPRequestHandler::~cHTTPRequestHandler()
+{
+ FREE(prefix);
+}
+
+void cHTTPRequestHandler::SetID(const char* UrlPrefix)
+{
+ FREE(prefix);
+ prefix = UrlPrefix ? strdup(UrlPrefix) : NULL;
+} \ No newline at end of file
diff --git a/libs/networking/src/HTTPResponse.cc b/libs/networking/src/HTTPResponse.cc
new file mode 100644
index 0000000..2f0eeef
--- /dev/null
+++ b/libs/networking/src/HTTPResponse.cc
@@ -0,0 +1,183 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPResponse.cc
+ * Created: 4. Juli 2012, 06:03
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPResponse.h>
+#include <Authorization.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <util.h>
+
+static const char *serverID = NULL;
+cHTTPResponse::cHTTPResponse(HTTPStatusCode Status)
+ : status(Status)
+ , content(512)
+{
+ SetHeader("Server", serverID);
+ if (!(Status <= HTTP_OK /* || Status == HTTP_NoContent */ || Status == 304))
+ SetDefaultStatusBody(Status);
+}
+
+cHTTPResponse::cHTTPResponse(const char *Buffer)
+{
+ ParseMessage(Buffer);
+ if (Authorization()) Authorization()->SetServerID(ServerID());
+}
+
+cHTTPResponse::~cHTTPResponse()
+{
+}
+
+size_t cHTTPResponse::ContentSize() const
+{
+ if (content.Size()) return content.Size();
+ return cHTTPMessage::ContentSize();
+}
+
+const char * cHTTPResponse::ServerID(void)
+{
+ return serverID;
+}
+
+void cHTTPResponse::SetServerID(const char* ServerID)
+{
+ serverID = ServerID;
+}
+
+void cHTTPResponse::SetDefaultStatusBody(HTTPStatusCode Status)
+{
+ SetContentType(MT_Html);
+ content.Append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
+"\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\n"
+"<HTML>\n"
+" <HEAD>\n"
+" <TITLE>Error ");
+ content.Append(Status).Append("</TITLE>\n"
+" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">\n"
+" </HEAD>\n"
+" <BODY><H1>");
+ content.Append(Status).Append(" ").Append(httpStatus2Text(Status)).Append(".</H1></BODY>\n"
+"</HTML>\n");
+}
+
+size_t cHTTPResponse::ReadContentChunk(char* Buf, size_t bufSize)
+{
+ return content.Copy(Buf, bufSize);
+}
+
+size_t cHTTPResponse::WriteFirstLine(char* Buffer, size_t BufSize)
+{
+ return snprintf(Buffer, BufSize, "%s %d %s\n", ProtocolString(), status, httpStatus2Text(status));
+}
+
+//static const char *SampleRawResponse =
+//HTTP/1.1 401 Unauthorized
+//Date: Tue, 29 May 2012 03:54:02 GMT
+//Server: (null)
+//Connection: Close
+//WWW-Authenticate: Digest realm="validUsers@MyTestApp", nonce="dbe67572c707d25689a394ef7a9a9e8c", opaque="94c70a11bef0589719f190baf192bbcd", qop="auth"
+//Content-Type: text/html
+//Content-Length: 301
+
+//<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+//<HTML>
+// <HEAD>
+// <TITLE>Error</TITLE>
+// <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
+// </HEAD>
+// <BODY><H1>401 Unauthorized.</H1></BODY>
+//</HTML>
+//
+void cHTTPResponse::ParseMessage(const char *RawMessage)
+{
+ char scratch[512];
+ const char *p = RawMessage;
+ char *tmp;
+ ParseState state = ExpectProtocol;
+ ParseResult status = Continue;
+
+ Reset();
+ while (status == Continue) {
+ memset(scratch, 0, sizeof(scratch));
+ switch (state) {
+ case ExpectStatus:
+ p = getWord(scratch, sizeof(scratch), p);
+ this->status = strtoHTTPStatus(scratch);
+ p = restOfLine(scratch, sizeof(scratch), p); // just read the rest of the line
+ state = ExpectHeader;
+ break;
+
+ case ExpectProtocol:
+ p = getWord(scratch, sizeof(scratch), p);
+ if (!strcmp(scratch, "HTTP/1.0")) {
+ SetProtocol(HTTP_1_0);
+ state = ExpectStatus;
+ }
+ else if (!strcmp(scratch, "HTTP/1.1")) {
+ SetProtocol(HTTP_1_1);
+ state = ExpectStatus;
+ }
+ else status = UnsupportedProtocol;
+ break;
+
+ case ExpectContent:
+ printf("should read %ld bytes from %10.10s\n", ContentSize(), p);
+ status = Done;
+ break;
+
+ case ExpectHeader:
+ p = getWord(scratch, sizeof(scratch), p);
+ if (!strncmp(p, "\n\n", 2)) {
+ p += 2;
+ state = ExpectContent;
+ break;
+ }
+ if (!strncmp(p, "\r\n\r\n", 4)) {
+ p += 4;
+ state = ExpectContent;
+ break;
+ }
+ tmp = scratch + strlen(scratch);
+ if (*(tmp -1) == ':') {
+ *(tmp -1) = 0;
+ tmp = strdup(scratch);
+ p = restOfLine(scratch, sizeof(scratch), p);
+ if (!strcasecmp(tmp, "WWW-Authenticate") || !strcasecmp(tmp, "Authorization-Info"))
+ SetAuthorization(new cAuthorization(cHTTPRequest::GET, scratch));
+ else if (!strcasecmp(tmp, "content-type"))
+ SetContentType(scratch);
+ else if (!strcasecmp(tmp, "content-length"))
+ SetContentSize(atol(scratch));
+ else SetHeader(tmp, scratch);
+ FREE(tmp);
+ }
+ else {
+ status = InvalidName;
+ }
+ break;
+
+ default: break;
+ } // end switch
+ } // end while (status == OK)
+}
+
diff --git a/libs/networking/src/HTTPServer.cc b/libs/networking/src/HTTPServer.cc
new file mode 100644
index 0000000..f435e2f
--- /dev/null
+++ b/libs/networking/src/HTTPServer.cc
@@ -0,0 +1,156 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPServer.cc
+ * Created: 4. Juli 2012, 12:16
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPServer.h>
+#include <HTTPResponse.h>
+#include <ConnectionHandler.h>
+#include <CondWait.h>
+#include <Mutex.h>
+#include <Logging.h>
+#include <util.h>
+#include <stdio.h>
+
+static volatile bool running = true;
+cHTTPServer::cHTTPServer(cServerConfig &Config)
+ : config(Config)
+#ifdef LIVE_CLEANUP
+ , cleaner(NULL)
+#endif
+{
+ threads = new std::vector<cThread *>();
+#ifdef LIVE_CLEANUP
+ cleaner = new cThread(cleanerThread, NULL, "cleanup thread stubs");
+#endif
+}
+
+cHTTPServer::~cHTTPServer()
+{
+#ifdef LIVE_CLEANUP
+ cleaner->Cancel(0);
+ delete cleaner;
+#else
+ Cleanup();
+#endif
+ delete threads;
+}
+
+void cHTTPServer::Action()
+{
+#ifdef LIVE_CLEANUP
+ if (cleaner) {
+ fprintf(stderr, "check size of thread pool ...\n");
+ if (!threads->empty()) fprintf(stderr, "thread pool has size of %lu\n", threads->size());
+ fprintf(stderr, "start cleaner thread\n");
+ cleaner->Start();
+ }
+#endif
+ fprintf(stderr, "startup server now\n");
+ while (Running()) {
+ cConnectionPoint *cp = ServerSocket().Accept();
+
+ if (cp) {
+ // this has to come after accept, as the hostnames can not be determined before an established connection.
+ if (!cHTTPResponse::ServerID()) {
+ char *id;
+
+ asprintf(&id, "HTTPServer %s:%d", ServerSocket().ThisSide()->RealName(), ServerSocket().Port());
+ cHTTPResponse::SetServerID(id);
+ }
+ cConnectionHandler *ch = new cConnectionHandler(*cp, config);
+
+ ch->Start();
+
+#ifdef LIVE_CLEANUP
+ cMutexLock poolSync(&poolMutex);
+#endif
+ threads->push_back(ch);
+ }
+ }
+}
+
+bool cHTTPServer::Running()
+{
+ return ServerSocket().Active();
+}
+
+#ifdef LIVE_CLEANUP
+int cHTTPServer::cleanerThread(void *opaque, cThread *ThreadContext)
+{
+ cHTTPServer *server = (cHTTPServer *)opaque;
+
+ server->Cleanup(ThreadContext);
+ return 0;
+}
+
+void cHTTPServer::Cleanup(cThread *ThreadContext)
+{
+ if (!ThreadContext) return;
+ cThread *p;
+
+ fprintf(stderr, "cleanup-Thread - gonna start loop ...\n");
+ while (ThreadContext->Running()) {
+ fprintf(stderr, "check list of possible threads ...\n");
+ if (!threads->empty()) {
+ fprintf(stderr, "thread pool is not empty ...\n");
+ for (size_t i=0; i < threads->size(); ++i) {
+ fprintf(stderr, "ok, got first entry to check ...\n");
+ p = (*threads)[i];
+ if (p->Active()) continue;
+
+ fprintf(stderr, "thread %lu looks dead ...\n", i);
+ isyslog("thread %lu is not active, so just clean it up", i);
+ p->Cancel();
+ delete p;
+ cMutexLock poolSync(&poolMutex);
+ threads->erase(threads->begin() + i);
+ break;
+ }
+ }
+ cCondWait::SleepMs(200);
+ }
+ ThreadContext->Cancel();
+}
+#else
+void cHTTPServer::Cleanup()
+{
+ cThread *t;
+
+ for (size_t i=0; i < threads->size(); ++i) {
+ t = (*threads)[i];
+ t->Cancel();
+ delete t;
+ }
+}
+#endif
+
+bool cHTTPServer::Start()
+{
+ Action();
+ return true;
+}
+
+void cHTTPServer::Stop()
+{
+ ServerSocket().SetActive(false);
+} \ No newline at end of file
diff --git a/libs/networking/src/HTTPStatus.cc b/libs/networking/src/HTTPStatus.cc
new file mode 100644
index 0000000..74623ed
--- /dev/null
+++ b/libs/networking/src/HTTPStatus.cc
@@ -0,0 +1,121 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: HTTPStatus.cc
+ * Created: 3. Juli 2012, 17:34
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <HTTPStatus.h>
+#include <stdlib.h>
+
+const char *httpStatus2Text(int Status)
+{
+ switch (Status) {
+ case HTTP_Continue: return "Continue";
+ case HTTP_SwitchProtocol: return "Gonna switch Protocol";
+ case HTTP_OK: return "Ok";
+ case HTTP_Created: return "Created";
+ case HTTP_Accepted: return "Accepted";
+ case HTTP_NoContent: return "No Content";
+ case HTTP_ResetContent: return "reset Content";
+ case HTTP_PartialContent: return "partial Content";
+ case HTTP_MultipleChoices: return "Multiple Choices";
+ case HTTP_MovedPermanently: return "Permanently moved";
+ case HTTP_Found: return "Found";
+ case HTTP_SeeOther: return "See other";
+ case HTTP_NotModified: return "Not modified";
+ case HTTP_UseProxy: return "Use Proxy";
+ case HTTP_MovedTemporarily: return "Temporarily moved";
+ case HTTP_BadRequest: return "Bad Request";
+ case HTTP_UnAuthorized: return "Unauthorized";
+ case HTTP_PaymentRequired: return "Payment required";
+ case HTTP_Forbidden: return "Forbidden";
+ case HTTP_NotFound: return "Not Found";
+ case HTTP_MethodNotAllowed: return "Not Allowed";
+ case HTTP_NotAcceptable: return "Not acceptable";
+ case HTTP_ProxyAuthenticationRequired: return "Authentication required";
+ case HTTP_RequestTimeout: return "Request timed out";
+ case HTTP_Conflict: return "Conflict";
+ case HTTP_Gone: return "Gone";
+ case HTTP_LengthRequired: return "Length required";
+ case HTTP_PreconditionFailed: return "Precondition failed";
+ case HTTP_RequestTooLarge: return "Request too large";
+ case HTTP_RequestURIToLong: return "Requested URI to long";
+ case HTTP_UnsupportedMediaType: return "Unsupported Media Type";
+ case HTTP_RequestRangeNotSatisfiable: return "Request Range Not satisfiable";
+ case HTTP_ExpectationFailed: return "Expectation failed";
+ case HTTP_InternalServerError: return "Internal Server Error";
+ case HTTP_NotImplemented: return "Not implemented";
+ case HTTP_BadGateway: return "Bad Gateway";
+ case HTTP_ServiceUnavailable: return "Service unavailable";
+ case HTTP_GatewayTimeout: return "Gateway timed out";
+ case HTTP_VersionNotSupported: return "Version not supported";
+ default: return "Unsupported/Unknown status";
+ }
+}
+
+HTTPStatusCode strtoHTTPStatus(const char *p)
+{
+ int tmp = atoi(p);
+
+ switch (tmp) {
+ case HTTP_Continue: return HTTP_Continue;
+ case HTTP_SwitchProtocol: return HTTP_SwitchProtocol;
+ case HTTP_OK: return HTTP_OK;
+ case HTTP_Created: return HTTP_Created;
+ case HTTP_Accepted: return HTTP_Accepted;
+ case HTTP_NoContent: return HTTP_NoContent;
+ case HTTP_ResetContent: return HTTP_ResetContent;
+ case HTTP_PartialContent: return HTTP_PartialContent;
+ case HTTP_MultipleChoices: return HTTP_MultipleChoices;
+ case HTTP_MovedPermanently: return HTTP_MovedPermanently;
+ case HTTP_Found: return HTTP_Found;
+ case HTTP_SeeOther: return HTTP_SeeOther;
+ case HTTP_NotModified: return HTTP_NotModified;
+ case HTTP_UseProxy: return HTTP_UseProxy;
+ case HTTP_MovedTemporarily: return HTTP_MovedTemporarily;
+ case HTTP_BadRequest: return HTTP_BadRequest;
+ case HTTP_UnAuthorized: return HTTP_UnAuthorized;
+ case HTTP_PaymentRequired: return HTTP_PaymentRequired;
+ case HTTP_Forbidden: return HTTP_Forbidden;
+ case HTTP_NotFound: return HTTP_NotFound;
+ case HTTP_MethodNotAllowed: return HTTP_MethodNotAllowed;
+ case HTTP_NotAcceptable: return HTTP_NotAcceptable;
+ case HTTP_ProxyAuthenticationRequired: return HTTP_ProxyAuthenticationRequired;
+ case HTTP_RequestTimeout: return HTTP_RequestTimeout;
+ case HTTP_Conflict: return HTTP_Conflict;
+ case HTTP_Gone: return HTTP_Gone;
+ case HTTP_LengthRequired: return HTTP_LengthRequired;
+ case HTTP_PreconditionFailed: return HTTP_PreconditionFailed;
+ case HTTP_RequestTooLarge: return HTTP_RequestTooLarge;
+ case HTTP_RequestURIToLong: return HTTP_RequestURIToLong;
+ case HTTP_UnsupportedMediaType: return HTTP_UnsupportedMediaType;
+ case HTTP_RequestRangeNotSatisfiable: return HTTP_RequestRangeNotSatisfiable;
+ case HTTP_ExpectationFailed: return HTTP_ExpectationFailed;
+ case HTTP_InternalServerError: return HTTP_InternalServerError;
+ case HTTP_NotImplemented: return HTTP_NotImplemented;
+ case HTTP_BadGateway: return HTTP_BadGateway;
+ case HTTP_ServiceUnavailable: return HTTP_ServiceUnavailable;
+ case HTTP_GatewayTimeout: return HTTP_GatewayTimeout;
+ case HTTP_VersionNotSupported: return HTTP_VersionNotSupported;
+ default: return HTTP_InternalServerError;
+ }
+}
+
diff --git a/libs/networking/src/Principal.cc b/libs/networking/src/Principal.cc
new file mode 100644
index 0000000..65103d9
--- /dev/null
+++ b/libs/networking/src/Principal.cc
@@ -0,0 +1,105 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Principal.cc
+ * Created: 3. Juli 2012, 12:50
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Principal.h>
+#include <MD5Calculator.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <util.h>
+
+cPrincipal::cPrincipal(const char *Name, const char *Realm)
+ : name(strdup(Name))
+ , realm(strdup(Realm))
+ , hash(NULL)
+ , xinfo(NULL)
+ , age(0)
+{
+}
+
+cPrincipal::cPrincipal(const cPrincipal& other)
+ : name(other.name ? strdup(other.name) : NULL)
+ , realm(other.realm ? strdup(other.realm) : NULL)
+ , hash(other.hash ? strdup(other.hash) : NULL)
+ , xinfo(other.xinfo ? strdup(other.xinfo) : NULL)
+ , age(other.age)
+{
+}
+
+cPrincipal::~cPrincipal()
+{
+ FREE(name);
+ FREE(realm);
+ FREE(hash);
+ FREE(xinfo);
+}
+
+void cPrincipal::CreateHash(const char* Password)
+{
+ cMD5Calculator hc;
+
+ FREE(hash);
+ hc.AddContent(name, strlen(name));
+ hc.AddContent(":", 1);
+ hc.AddContent(realm, strlen(realm));
+ hc.AddContent(":", 1);
+ hc.AddContent(Password, strlen(Password));
+
+ hash = hc.Hash();
+}
+
+void cPrincipal::SetName(const char* Name)
+{
+ FREE(name);
+ name = Name ? strdup(Name) : NULL;
+}
+
+void cPrincipal::SetRealm(const char* Realm)
+{
+ FREE(realm);
+ realm = Realm ? strdup(Realm) : NULL;
+}
+
+void cPrincipal::SetHash(const char* Hash)
+{
+ FREE(hash);
+ hash = Hash ? strdup(Hash) : NULL;
+}
+
+void cPrincipal::SetExtendedInfo(const char* Info)
+{
+ FREE(xinfo);
+ xinfo = Info ? strdup(Info) : NULL;
+}
+
+void cPrincipal::Dump(void) const
+{
+ printf(">>> ========= Principal ======================\n");
+ printf("name ....: >%s<\n", name);
+ printf("realm ...: >%s<\n", realm);
+ printf("hash ....: >%s<\n", hash);
+ printf("age .....: >%d<\n", age);
+ printf("ext. info: >%s<\n", xinfo);
+ printf("------------- Principal ------------------ <<<\n");
+}
diff --git a/libs/networking/src/ServerConfig.cc b/libs/networking/src/ServerConfig.cc
new file mode 100644
index 0000000..e6ad4b8
--- /dev/null
+++ b/libs/networking/src/ServerConfig.cc
@@ -0,0 +1,60 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ServerConfig.cc
+ * Created: 8. Juli 2012, 06:12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ServerConfig.h>
+#include <Logging.h>
+#include <util.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+cServerConfig::cServerConfig(int Port)
+ : server(Port, 5)
+ , documentRoot(NULL)
+ , appIconPath(NULL)
+{
+}
+
+cServerConfig::~cServerConfig()
+{
+ FREE(appIconPath);
+ FREE(documentRoot);
+}
+
+void cServerConfig::SetAppIcon(const char* AppIcon)
+{
+ struct stat st;
+
+ if (!AppIcon) return;
+ if (!stat(AppIcon, &st)) {
+ FREE(appIconPath);
+ appIconPath = strdup(AppIcon);
+ }
+ else esyslog("ERROR: failed to stat application icon! %s", AppIcon);
+}
+
+void cServerConfig::SetDocumentRoot(const char* DocumentRoot)
+{
+ free(documentRoot);
+ documentRoot = DocumentRoot ? strdup(DocumentRoot) : NULL;
+} \ No newline at end of file
diff --git a/libs/networking/src/ServerSocket.cc b/libs/networking/src/ServerSocket.cc
new file mode 100644
index 0000000..2ff92fb
--- /dev/null
+++ b/libs/networking/src/ServerSocket.cc
@@ -0,0 +1,84 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ServerSocket.cc
+ * Created: 4. Juli 2012, 07:28
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ServerSocket.h>
+#include <Logging.h>
+#include <fcntl.h>
+
+cServerSocket::cServerSocket(int Port, int Queue)
+ : cAbstractSocket(Port, Queue)
+ , port(Port)
+ , active(true)
+{
+}
+
+cServerSocket::~cServerSocket()
+{
+}
+
+bool cServerSocket::Open(void)
+{
+ return cAbstractSocket::Open(port);
+}
+
+cConnectionPoint *cServerSocket::Accept(void)
+{
+ cConnectionPoint *rv = NULL;
+
+ while (active && !rv) {
+ rv = cAbstractSocket::Accept(port, 500);
+ }
+ return rv;
+}
+
+void cServerSocket::ConfigureSocket(int Socket)
+{
+ if (!ForceBlockingIO()) {
+ // make it non-blocking:
+ int oldflags = fcntl(Socket, F_GETFL, 0);
+
+ if (oldflags < 0) {
+ esyslog("could not retrieve old socket flags");
+
+ return;
+ }
+
+ oldflags |= O_NONBLOCK;
+ if (fcntl(Socket, F_SETFL, oldflags) < 0) {
+ esyslog("failed to set nonblocking state of socket");
+
+ return;
+ }
+ }
+}
+
+void cServerSocket::SetBlockingIO(bool ForceBlockingIO)
+{
+ cAbstractSocket::SetBlockingIO(ForceBlockingIO);
+}
+
+bool cServerSocket::ForceBlockingIO() const
+{
+ return cAbstractSocket::ForceBlockingIO();
+}
diff --git a/libs/networking/src/Url.cc b/libs/networking/src/Url.cc
new file mode 100644
index 0000000..011d493
--- /dev/null
+++ b/libs/networking/src/Url.cc
@@ -0,0 +1,229 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Url.cc
+ * Created: 4. Juli 2012, 05:42
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libnetworking: classes for tcp/ip sockets and http-protocol handling
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <Url.h>
+#include <Codec.h>
+#include <util.h>
+#ifdef DEBUG
+#include <iostream>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+
+static cURLEncoder * encoder = NULL;
+static cURLDecoder * decoder = NULL;
+
+cUrl::cUrl(const char* RawURL)
+ : path(NULL)
+{
+ ParseURL(RawURL);
+}
+
+cUrl::~cUrl()
+{
+ FREE(path);
+}
+
+cURLDecoder* cUrl::Decoder(void) const
+{
+ if (!decoder) decoder = new cURLDecoder();
+ return decoder;
+}
+
+cURLEncoder* cUrl::Encoder(void) const
+{
+ if (!encoder) encoder = new cURLEncoder();
+ return encoder;
+}
+
+const char *cUrl::Parameter(const char* Name)
+{
+ std::tr1::unordered_map<std::string, std::string>::iterator found = parameters.find(Name);
+ if (found != parameters.end()) return found->second.c_str();
+ return NULL;
+}
+
+void cUrl::SetParameter(const char* Name, const char* Value)
+{
+ std::string name = Name;
+ std::string value = Value ? Value : " ";
+ parameters[name] = value;
+}
+
+size_t cUrl::EstimatedSize(void ) const
+{
+ size_t rv = parameters.size() * 3;
+
+ if (path) rv += strlen(path) + 4;
+ ParameterMap::const_iterator pm = parameters.begin();
+
+ while (pm != parameters.end()) {
+ rv += pm->first.length() * 3;
+ rv += pm->second.length() * 3;
+ ++pm;
+ }
+ return rv;
+}
+
+void cUrl::ParseURL(const char *URL)
+{
+ FREE(path);
+ parameters.clear();
+ if (!URL) return;
+ const char *q = strchr(URL, '?'); // divider between url and querystring
+// char *realURL;
+// size_t l;
+
+ if (!q) q = URL + strlen(URL);
+// l = q - URL;
+// realURL = (char *)malloc(l + 2);
+// if (!realURL) return;
+// strncpy(realURL, URL, l);
+// realURL[l] = 0;
+ path = Decoder()->Decode(URL, q - URL);
+ if (*q) ParseQueryString(++q);
+}
+
+void cUrl::ParseQueryString(const char* QueryString)
+{
+ if (!(QueryString && *QueryString)) return;
+ const char *start, *last;
+ char *scratch = strdup(QueryString);
+ char *p, *end;
+ size_t srcLen = strlen(QueryString);
+
+ for (start = (const char *)scratch, end = (char *) start, last = scratch + srcLen; end && start < last; start = (const char *)++end) {
+ end = (char *) strchr(start, '&');
+ if (!end) end = (char *)start + strlen(start);
+ *end = 0;
+ p = (char *) strchr(start, '=');
+ if (p) {
+ *p++ = 0;
+ char *pn = p ? Decoder()->Decode(start) : NULL;
+ char *pv = p ? Decoder()->Decode(p) : NULL;
+
+ std::string name = pn;
+ std::string value = pv ? pv : " ";
+
+ parameters[name] = value;
+
+ free(pn);
+ free(pv);
+ }
+ else {
+ char *pn = Decoder()->Decode(start);
+
+ std::string name = pn;
+ parameters[name] = " ";
+ free(pn);
+ }
+ }
+ free(scratch);
+}
+
+char* cUrl::ToString(void) const
+///< returns the address of the newly allocated buffer
+{
+ size_t bufSize = EstimatedSize();
+ char *rv = (char *)malloc(bufSize);
+
+ if (!rv) return NULL;
+ int n = WriteBuf(rv, bufSize);
+
+ if (n < 0) {
+ bufSize += 128;
+ rv = (char *) realloc(rv, bufSize);
+ WriteBuf(rv, bufSize);
+ }
+ return rv;
+}
+
+int cUrl::WriteBuf(char* buf, size_t bufSize) const
+///< returns the characters written. -1 as return value indicates a buffer overrun.
+{
+ char *p, *tmp;
+ bool first = true;
+ int n = 0;
+
+ if (path) n += snprintf(buf + n, bufSize - n, "%s", path);
+ p = buf + n;
+ ParameterMap::const_iterator pm = parameters.begin();
+
+ while (pm != parameters.end()) {
+ tmp = Encoder()->Encode(pm->first.c_str());
+ if (p - buf + strlen(tmp) + 2 > bufSize)
+ return -1;
+ if (first) {
+ first = false;
+ *p++ = '?';
+ }
+ else *p++ = '&';
+ strcpy(p, tmp);
+ p += strlen(p);
+ FREE(tmp);
+
+ if (strcmp(pm->second.c_str(), " ")) {
+ tmp = Encoder()->Encode(pm->second.c_str());
+ if (p - buf + strlen(tmp) + 2 > bufSize)
+ return -1;
+ *p++ = '=';
+ strcpy(p, tmp);
+ p += strlen(p);
+ FREE(tmp);
+ }
+ ++pm;
+ }
+ p += strlen(p);
+
+ return p - buf;
+}
+
+#ifdef DEBUG
+void cUrl::Dump(void )
+{
+ ParameterMap::const_iterator pm = parameters.begin();
+
+ while (pm != parameters.end()) {
+ std::cout << "parameter [" << pm->first << "]";
+ if (strcmp(pm->second.c_str(), " "))
+ std::cout << " has value <|" << pm->second << "|>" << std::endl;
+ else
+ std::cout << " has NO value!" << std::endl;
+ ++pm;
+ }
+}
+#endif
+
+void cUrl::Cleanup(void )
+{
+ if (encoder) {
+ delete encoder;
+ encoder = NULL;
+ }
+ if (decoder) {
+ delete decoder;
+ decoder = NULL;
+ }
+} \ No newline at end of file
diff --git a/libs/networking/summary.txt b/libs/networking/summary.txt
new file mode 100644
index 0000000..5e47f27
--- /dev/null
+++ b/libs/networking/summary.txt
@@ -0,0 +1 @@
+libnetworking: classes for tcp/ip sockets and http-protocol handling
diff --git a/libs/util/.dep.inc b/libs/util/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/libs/util/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/libs/util/Makefile b/libs/util/Makefile
new file mode 100644
index 0000000..ec9de69
--- /dev/null
+++ b/libs/util/Makefile
@@ -0,0 +1,128 @@
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# Available make variables:
+#
+# CND_BASEDIR base directory for relative paths
+# CND_DISTDIR default top distribution directory (build artifacts)
+# CND_BUILDDIR default top build directory (object files, ...)
+# CONF name of current configuration
+# CND_PLATFORM_${CONF} platform name (current configuration)
+# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
+# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
+# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
+# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
+# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
+# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
+#
+# NOCDDL
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+
+
+# build
+build: .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post: .build-impl
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post: .clean-impl
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+# build tests
+build-tests: .build-tests-post
+
+.build-tests-pre:
+# Add your pre 'build-tests' code here...
+
+.build-tests-post: .build-tests-impl
+# Add your post 'build-tests' code here...
+
+
+# run tests
+test: .test-post
+
+.test-pre:
+# Add your pre 'test' code here...
+
+.test-post: .test-impl
+# Add your post 'test' code here...
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
+
+# include project make variables
+include nbproject/Makefile-variables.mk
diff --git a/libs/util/include/AbstractListAssembler.h b/libs/util/include/AbstractListAssembler.h
new file mode 100644
index 0000000..1e547e4
--- /dev/null
+++ b/libs/util/include/AbstractListAssembler.h
@@ -0,0 +1,49 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractListAssembler.h
+ * Created: 6. Juli 2012, 09:38
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef ABSTRACTLISTASSEMBLER_H
+#define ABSTRACTLISTASSEMBLER_H
+
+#include <sys/types.h>
+#include <map>
+
+class cStringBuilder;
+class cManagedVector;
+class cAbstractListAssembler {
+public:
+ cAbstractListAssembler();
+ virtual ~cAbstractListAssembler();
+
+ bool AssembleList(cStringBuilder &sb, cManagedVector &ElemVector, std::map<int, size_t> &Categories, size_t start = 0, uint delta = 40);
+
+ virtual const char *MediaType(void) const = 0;
+
+protected:
+ virtual bool OpenList(cStringBuilder &sb, std::map<int, size_t> &Categories, size_t total, size_t start = 0, uint delta = 40) = 0;
+ virtual bool AddElement(cStringBuilder &sb, void *, bool odd) = 0;
+ virtual bool CloseList(cStringBuilder &sb, size_t total, size_t start = 0, uint delta = 40) = 0;
+};
+
+#endif /* ABSTRACTLISTASSEMBLER_H */
+
diff --git a/libs/util/include/Codec.h b/libs/util/include/Codec.h
new file mode 100644
index 0000000..80352d7
--- /dev/null
+++ b/libs/util/include/Codec.h
@@ -0,0 +1,92 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Codec.h
+ * Created: 21. Mai 2012, 14:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef CODEC_H
+#define CODEC_H
+
+#include <stddef.h>
+
+class cCodec {
+///< base class for simple (character based) encoding/decoding
+public:
+ cCodec(const char *Table, char KeyChar = '#');
+ virtual ~cCodec();
+ char KeyChar() const { return keyChar; }
+ const char *TranslateTable() const { return translateTable; }
+ virtual size_t DecodeSequence(unsigned char *d, unsigned char *s);
+
+protected:
+ char *translateTable;
+ char keyChar;
+ };
+
+class cEncoder : public cCodec {
+public:
+ cEncoder(char SpecialChar = '#', const char *TrTable = "0123456789ABCDEF");
+ virtual ~cEncoder();
+ char *Encode(const char *Source, size_t SourceLength = 0); ///< encode Source,
+ ///< optionally limited by SourceLength (default is to encode a 0-terminated cstring)
+ };
+
+class cURLEncoder : public cEncoder {
+public:
+ cURLEncoder();
+ virtual ~cURLEncoder();
+ };
+
+class cDecoder : public cCodec {
+public:
+ cDecoder(char KeyChar = '#', const char *TrTable = "0123456789ABCDEF");
+ virtual ~cDecoder();
+ char *Decode(const char *Source, size_t SourceLength = 0); ///< decode Source,
+ ///< optionally limited by SourceLength (default is to decode a 0-terminated cstring)
+ virtual size_t DecodeSequence(unsigned char *d, unsigned char *s);
+ };
+
+class cURLDecoder : public cDecoder {
+public:
+ cURLDecoder();
+ virtual ~cURLDecoder();
+ };
+
+class cHexEncoder : public cEncoder {
+public:
+ cHexEncoder();
+ virtual ~cHexEncoder();
+ char *Encode(const unsigned char* Source, size_t SourceLength = 0);
+ };
+
+class cHexDecoder : public cDecoder {
+public:
+ cHexDecoder();
+ virtual ~cHexDecoder();
+ char *Decode(const char *Source, size_t SourceLength = 0);
+ };
+
+extern cHexEncoder * getHexEncoder(void);
+extern cHexDecoder * getHexDecoder(void);
+extern void codecCleanUp(void);
+
+#endif /* CODEC_H */
+
diff --git a/libs/util/include/JSonWriter.h b/libs/util/include/JSonWriter.h
new file mode 100644
index 0000000..732daec
--- /dev/null
+++ b/libs/util/include/JSonWriter.h
@@ -0,0 +1,64 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: JSonWriter.h
+ * Created: 6. Juli 2012, 12:47
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef JSONWRITER_H
+#define JSONWRITER_H
+
+#include <stack>
+#include <StringBuilder.h>
+
+class cJSonWriter {
+public:
+ cJSonWriter(cStringBuilder &StringBuilder);
+ virtual ~cJSonWriter();
+
+ cJSonWriter &Object(void);
+ cJSonWriter &EndObject(void);
+ cJSonWriter &Array(void);
+ cJSonWriter &EndArray(void);
+ cJSonWriter &Key(const char *Name);
+ cJSonWriter &Value(const char *Text);
+ cJSonWriter &Value(int v);
+ cJSonWriter &Value(long v);
+ cJSonWriter &Value(size_t v);
+ cJSonWriter &Value(bool v);
+ cJSonWriter &Value(double v);
+
+private:
+ typedef enum {
+ JS_Unknown,
+ JS_Object,
+ JS_Array,
+ JS_Key
+ } JSonState;
+ cJSonWriter::JSonState State(void);
+ void PushState(JSonState State);
+ cJSonWriter::JSonState PopState(void);
+ std::stack<JSonState> state;
+ JSonState lastState;
+ cStringBuilder &sb;
+};
+
+#endif /* JSONWRITER_H */
+
diff --git a/libs/util/include/MD5Calculator.h b/libs/util/include/MD5Calculator.h
new file mode 100644
index 0000000..400aba1
--- /dev/null
+++ b/libs/util/include/MD5Calculator.h
@@ -0,0 +1,45 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: MD5Calculator.h
+ * Created: 3. Juli 2012, 13:15
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef MD5CALCULATOR_H
+#define MD5CALCULATOR_H
+
+#include <openssl/md5.h>
+
+class cMD5Calculator {
+public:
+ cMD5Calculator();
+ virtual ~cMD5Calculator();
+
+ void AddContent(const char *Buf, size_t bufSize = 0);
+
+ char *Hash(void);
+ void Reset(void);
+
+private:
+ MD5_CTX context;
+ };
+
+#endif /* MD5CALCULATOR_H */
+
diff --git a/libs/util/include/ManagedMap.h b/libs/util/include/ManagedMap.h
new file mode 100644
index 0000000..c71de85
--- /dev/null
+++ b/libs/util/include/ManagedMap.h
@@ -0,0 +1,55 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ManagedMap.h
+ * Created: 7. Juli 2012, 08:28
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef MANAGEDMAP_H
+#define MANAGEDMAP_H
+
+#include <string>
+#include <tr1/unordered_map>
+
+class cManagedMap {
+public:
+ typedef std::tr1::unordered_map<std::string, void *>::const_iterator const_iterator;
+
+ cManagedMap(void (*cbFreeElem)(void *));
+ virtual ~cManagedMap();
+
+ void clear(void);
+ void put(const char *key, void *value);
+ void *get(const char *key);
+ const void *get(const char *key) const;
+ size_t size(void) { return internalMap.size(); }
+
+ const_iterator begin() const { return internalMap.begin(); }
+ const_iterator end() const { return internalMap.end(); }
+
+private:
+ std::tr1::unordered_map<std::string, void *> internalMap;
+ void (*freeCallback)(void *);
+ typedef std::tr1::unordered_map<std::string, void *>::iterator iterator;
+};
+
+
+#endif /* MANAGEDMAP_H */
+
diff --git a/libs/util/include/ManagedVector.h b/libs/util/include/ManagedVector.h
new file mode 100644
index 0000000..7fa7af2
--- /dev/null
+++ b/libs/util/include/ManagedVector.h
@@ -0,0 +1,49 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ManagedVector.h
+ * Created: 6. Juli 2012, 19:07
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef MANAGEDVECTOR_H
+#define MANAGEDVECTOR_H
+
+#include <vector>
+#include <stdlib.h>
+
+class cManagedVector {
+public:
+ cManagedVector(void (*cbFreeElem)(void *));
+ virtual ~cManagedVector();
+
+ void clear(void);
+ void push_back(void *p) { internalVector.push_back(p); }
+ void *operator[](size_t n) { return internalVector[n]; }
+ const void *operator[](size_t n) const { return internalVector[n]; }
+ size_t size(void) const { return internalVector.size(); }
+ void sort(bool (*fnSort)(void *a, void *b));
+
+private:
+ std::vector<void *> internalVector;
+ void (*freeCallback)(void *);
+ };
+
+#endif /* MANAGEDVECTOR_H */
+
diff --git a/libs/util/include/NamedValue.h b/libs/util/include/NamedValue.h
new file mode 100644
index 0000000..329061d
--- /dev/null
+++ b/libs/util/include/NamedValue.h
@@ -0,0 +1,51 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: NamedValue.h
+ * Created: 3. Juli 2012, 17:43
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef NAMEDVALUE_H
+#define NAMEDVALUE_H
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <vector>
+
+class cNamedValue {
+public:
+ cNamedValue(char *Name, char *Value = NULL, bool takePointers = false);
+ cNamedValue(const char *Name, const char *Value = NULL);
+ cNamedValue(const cNamedValue &other);
+ virtual ~cNamedValue();
+ cNamedValue &operator =(const cNamedValue &other);
+
+ const char *Name() const { return name; }
+ const char *Value() const { return value; }
+ void SetValue(const char *Value) { free(value); value = strdup(Value); }
+
+private:
+ char *name;
+ char *value;
+ };
+
+#endif /* NAMEDVALUE_H */
+
diff --git a/libs/util/include/StringBuilder.h b/libs/util/include/StringBuilder.h
new file mode 100644
index 0000000..aea9975
--- /dev/null
+++ b/libs/util/include/StringBuilder.h
@@ -0,0 +1,60 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: StringBuilder.h
+ * Created: 6. Juli 2012, 10:54
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef STRINGBUILDER_H
+#define STRINGBUILDER_H
+
+#include <ManagedVector.h>
+#include <time.h>
+
+class cStringBuilder {
+public:
+ cStringBuilder(const char *First);
+ cStringBuilder(int chunkSize = 127);
+ virtual ~cStringBuilder();
+
+ cStringBuilder &Append(const char *Text);
+ cStringBuilder &Append(bool v, const char *TrueValue = "X", const char *FalseValue="-");
+ cStringBuilder &Append(double v);
+ cStringBuilder &Append(int v);
+ cStringBuilder &Append(long v);
+ cStringBuilder &Append(size_t s);
+
+ void Clear(void);
+ size_t Size(void);
+ size_t Size(void) const;
+ void Rewind(void) { readOffset = 0; }
+ size_t Copy(char *Buf, size_t BufSize);
+
+private:
+ void init(void);
+ void Write(const char *p);
+ int chunkSize;
+ size_t readOffset; ///< read offest is the offset over all chunks (thus goes from 0 to size)
+ int writeOffset; ///< write offset is the offset inside the last chunk (thus goes from 0 to chunkSize)
+ cManagedVector pool;
+ };
+
+#endif /* STRINGBUILDER_H */
+
diff --git a/libs/util/include/util.h b/libs/util/include/util.h
new file mode 100644
index 0000000..2b355cc
--- /dev/null
+++ b/libs/util/include/util.h
@@ -0,0 +1,38 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: util.h
+ * Created: 3. Juli 2012, 13:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <stdlib.h>
+#define FREE(m) { void *_tmp_ = m; m = NULL; free(_tmp_); }
+#define TO_STRING(s) #s
+#define EVER ;;
+
+extern const char * skipWhitespace(const char *Buffer);
+extern const char *getWord(char *buf, int bufSize, const char *src);
+extern const char *restOfLine(char *buf, int bufSize, const char *src);
+
+#endif /* UTIL_H */
+
diff --git a/libs/util/nbproject/Makefile-Debug.mk b/libs/util/nbproject/Makefile-Debug.mk
new file mode 100644
index 0000000..f9f3a3c
--- /dev/null
+++ b/libs/util/nbproject/Makefile-Debug.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/JSonWriter.o \
+ ${OBJECTDIR}/src/StringBuilder.o \
+ ${OBJECTDIR}/src/MD5Calculator.o \
+ ${OBJECTDIR}/src/AbstractListAssembler.o \
+ ${OBJECTDIR}/src/ManagedMap.o \
+ ${OBJECTDIR}/src/Codec.o \
+ ${OBJECTDIR}/src/ManagedVector.o \
+ ${OBJECTDIR}/src/NamedValue.o \
+ ${OBJECTDIR}/src/util.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+CXXFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+${OBJECTDIR}/src/JSonWriter.o: nbproject/Makefile-${CND_CONF}.mk src/JSonWriter.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/JSonWriter.o src/JSonWriter.cc
+
+${OBJECTDIR}/src/StringBuilder.o: nbproject/Makefile-${CND_CONF}.mk src/StringBuilder.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/StringBuilder.o src/StringBuilder.cc
+
+${OBJECTDIR}/src/MD5Calculator.o: nbproject/Makefile-${CND_CONF}.mk src/MD5Calculator.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/MD5Calculator.o src/MD5Calculator.cc
+
+${OBJECTDIR}/src/AbstractListAssembler.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractListAssembler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractListAssembler.o src/AbstractListAssembler.cc
+
+${OBJECTDIR}/src/ManagedMap.o: nbproject/Makefile-${CND_CONF}.mk src/ManagedMap.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ManagedMap.o src/ManagedMap.cc
+
+${OBJECTDIR}/src/Codec.o: nbproject/Makefile-${CND_CONF}.mk src/Codec.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Codec.o src/Codec.cc
+
+${OBJECTDIR}/src/ManagedVector.o: nbproject/Makefile-${CND_CONF}.mk src/ManagedVector.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ManagedVector.o src/ManagedVector.cc
+
+${OBJECTDIR}/src/NamedValue.o: nbproject/Makefile-${CND_CONF}.mk src/NamedValue.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/NamedValue.o src/NamedValue.cc
+
+${OBJECTDIR}/src/util.o: nbproject/Makefile-${CND_CONF}.mk src/util.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I../vdr/include -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/util.o src/util.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/util/nbproject/Makefile-Release.mk b/libs/util/nbproject/Makefile-Release.mk
new file mode 100644
index 0000000..29f37c3
--- /dev/null
+++ b/libs/util/nbproject/Makefile-Release.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/JSonWriter.o \
+ ${OBJECTDIR}/src/StringBuilder.o \
+ ${OBJECTDIR}/src/MD5Calculator.o \
+ ${OBJECTDIR}/src/AbstractListAssembler.o \
+ ${OBJECTDIR}/src/ManagedMap.o \
+ ${OBJECTDIR}/src/Codec.o \
+ ${OBJECTDIR}/src/ManagedVector.o \
+ ${OBJECTDIR}/src/NamedValue.o \
+ ${OBJECTDIR}/src/util.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+${OBJECTDIR}/src/JSonWriter.o: nbproject/Makefile-${CND_CONF}.mk src/JSonWriter.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/JSonWriter.o src/JSonWriter.cc
+
+${OBJECTDIR}/src/StringBuilder.o: nbproject/Makefile-${CND_CONF}.mk src/StringBuilder.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/StringBuilder.o src/StringBuilder.cc
+
+${OBJECTDIR}/src/MD5Calculator.o: nbproject/Makefile-${CND_CONF}.mk src/MD5Calculator.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/MD5Calculator.o src/MD5Calculator.cc
+
+${OBJECTDIR}/src/AbstractListAssembler.o: nbproject/Makefile-${CND_CONF}.mk src/AbstractListAssembler.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/AbstractListAssembler.o src/AbstractListAssembler.cc
+
+${OBJECTDIR}/src/ManagedMap.o: nbproject/Makefile-${CND_CONF}.mk src/ManagedMap.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ManagedMap.o src/ManagedMap.cc
+
+${OBJECTDIR}/src/Codec.o: nbproject/Makefile-${CND_CONF}.mk src/Codec.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Codec.o src/Codec.cc
+
+${OBJECTDIR}/src/ManagedVector.o: nbproject/Makefile-${CND_CONF}.mk src/ManagedVector.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ManagedVector.o src/ManagedVector.cc
+
+${OBJECTDIR}/src/NamedValue.o: nbproject/Makefile-${CND_CONF}.mk src/NamedValue.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/NamedValue.o src/NamedValue.cc
+
+${OBJECTDIR}/src/util.o: nbproject/Makefile-${CND_CONF}.mk src/util.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/util.o src/util.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/util/nbproject/Makefile-impl.mk b/libs/util/nbproject/Makefile-impl.mk
new file mode 100644
index 0000000..20dba1a
--- /dev/null
+++ b/libs/util/nbproject/Makefile-impl.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=util
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber
+.clobber-impl: .clobber-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+ done
+
+# all
+.all-impl: .all-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+ done
+
+# build tests
+.build-tests-impl: .build-impl .build-tests-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
+
+# run tests
+.test-impl: .build-tests-impl .test-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
+
+# dependency checking support
+.depcheck-impl:
+ @echo "# This code depends on make tool being used" >.dep.inc
+ @if [ -n "${MAKE_VERSION}" ]; then \
+ echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+ echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+ echo "include \$${DEPFILES}" >>.dep.inc; \
+ echo "endif" >>.dep.inc; \
+ else \
+ echo ".KEEP_STATE:" >>.dep.inc; \
+ echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+ fi
+
+# configuration validation
+.validate-impl:
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ echo ""; \
+ echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+ echo "See 'make help' for details."; \
+ echo "Current directory: " `pwd`; \
+ echo ""; \
+ fi
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ exit 1; \
+ fi
+
+
+# help
+.help-impl: .help-pre
+ @echo "This makefile supports the following configurations:"
+ @echo " ${ALLCONFS}"
+ @echo ""
+ @echo "and the following targets:"
+ @echo " build (default target)"
+ @echo " clean"
+ @echo " clobber"
+ @echo " all"
+ @echo " help"
+ @echo ""
+ @echo "Makefile Usage:"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
+ @echo " make [SUB=no] clobber"
+ @echo " make [SUB=no] all"
+ @echo " make help"
+ @echo ""
+ @echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+ @echo " also clean subprojects."
+ @echo "Target 'clobber' will remove all built files from all configurations and,"
+ @echo " unless 'SUB=no', also from subprojects."
+ @echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'help' prints this message."
+ @echo ""
+
diff --git a/libs/util/nbproject/Makefile-variables.mk b/libs/util/nbproject/Makefile-variables.mk
new file mode 100644
index 0000000..97c386e
--- /dev/null
+++ b/libs/util/nbproject/Makefile-variables.mk
@@ -0,0 +1,35 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# Debug configuration
+CND_PLATFORM_Debug=GNU-Linux-x86
+CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86
+CND_ARTIFACT_NAME_Debug=libutil.a
+CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/libutil.a
+CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Debug=util.tar
+CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/util.tar
+# Release configuration
+CND_PLATFORM_Release=GNU-Linux-x86
+CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
+CND_ARTIFACT_NAME_Release=libutil.a
+CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/libutil.a
+CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Release=util.tar
+CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/util.tar
+#
+# include compiler specific variables
+#
+# dmake command
+ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
+ (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
+#
+# gmake command
+.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
+#
+include nbproject/private/Makefile-variables.mk
diff --git a/libs/util/nbproject/Package-Debug.bash b/libs/util/nbproject/Package-Debug.bash
new file mode 100644
index 0000000..a8b449f
--- /dev/null
+++ b/libs/util/nbproject/Package-Debug.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+OUTPUT_BASENAME=libutil.a
+PACKAGE_TOP_DIR=util/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/util/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/util.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/util.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/util/nbproject/Package-Release.bash b/libs/util/nbproject/Package-Release.bash
new file mode 100644
index 0000000..a08bb00
--- /dev/null
+++ b/libs/util/nbproject/Package-Release.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libutil.a
+OUTPUT_BASENAME=libutil.a
+PACKAGE_TOP_DIR=util/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/util/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/util.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/util.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/util/nbproject/configurations.xml b/libs/util/nbproject/configurations.xml
new file mode 100644
index 0000000..3ff7534
--- /dev/null
+++ b/libs/util/nbproject/configurations.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>include/AbstractListAssembler.h</itemPath>
+ <itemPath>include/Codec.h</itemPath>
+ <itemPath>include/JSonWriter.h</itemPath>
+ <itemPath>include/MD5Calculator.h</itemPath>
+ <itemPath>include/ManagedMap.h</itemPath>
+ <itemPath>include/ManagedVector.h</itemPath>
+ <itemPath>include/NamedValue.h</itemPath>
+ <itemPath>include/StringBuilder.h</itemPath>
+ <itemPath>include/util.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/AbstractListAssembler.cc</itemPath>
+ <itemPath>src/Codec.cc</itemPath>
+ <itemPath>src/JSonWriter.cc</itemPath>
+ <itemPath>src/MD5Calculator.cc</itemPath>
+ <itemPath>src/ManagedMap.cc</itemPath>
+ <itemPath>src/ManagedVector.cc</itemPath>
+ <itemPath>src/NamedValue.cc</itemPath>
+ <itemPath>src/StringBuilder.cc</itemPath>
+ <itemPath>src/util.cc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="TestFiles"
+ displayName="Test Files"
+ projectFiles="false"
+ kind="TEST_LOGICAL_FOLDER">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false"
+ kind="IMPORTANT_FILES_FOLDER">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <ccTool>
+ <incDir>
+ <pElem>include</pElem>
+ <pElem>../vdr/include</pElem>
+ </incDir>
+ <commandLine>-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi</commandLine>
+ <preprocessorList>
+ <Elem>_GNU_SOURCE=1</Elem>
+ <Elem>_REENTRANT</Elem>
+ </preprocessorList>
+ <warningLevel>2</warningLevel>
+ </ccTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ </ccTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <asmTool>
+ <developmentMode>5</developmentMode>
+ </asmTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/util/nbproject/private/Makefile-variables.mk b/libs/util/nbproject/private/Makefile-variables.mk
new file mode 100644
index 0000000..a64183e
--- /dev/null
+++ b/libs/util/nbproject/private/Makefile-variables.mk
@@ -0,0 +1,7 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+# Debug configuration
+# Release configuration
diff --git a/libs/util/nbproject/private/configurations.xml b/libs/util/nbproject/private/configurations.xml
new file mode 100644
index 0000000..fa15dc7
--- /dev/null
+++ b/libs/util/nbproject/private/configurations.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/util/nbproject/private/private.xml b/libs/util/nbproject/private/private.xml
new file mode 100644
index 0000000..5ee2703
--- /dev/null
+++ b/libs/util/nbproject/private/private.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+ <data xmlns="http://www.netbeans.org/ns/make-project-private/1">
+ <activeConfTypeElem>3</activeConfTypeElem>
+ <activeConfIndexElem>0</activeConfIndexElem>
+ </data>
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>
diff --git a/libs/util/nbproject/project.xml b/libs/util/nbproject/project.xml
new file mode 100644
index 0000000..a4df583
--- /dev/null
+++ b/libs/util/nbproject/project.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>util</name>
+ <c-extensions/>
+ <cpp-extensions>cc</cpp-extensions>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>Debug</name>
+ <type>3</type>
+ </confElem>
+ <confElem>
+ <name>Release</name>
+ <type>3</type>
+ </confElem>
+ </confList>
+ </data>
+ </configuration>
+</project>
diff --git a/libs/util/src/AbstractListAssembler.cc b/libs/util/src/AbstractListAssembler.cc
new file mode 100644
index 0000000..e83f965
--- /dev/null
+++ b/libs/util/src/AbstractListAssembler.cc
@@ -0,0 +1,57 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: AbstractListAssembler.cc
+ * Created: 6. Juli 2012, 09:38
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <AbstractListAssembler.h>
+#include <ManagedVector.h>
+#include <StringBuilder.h>
+#include <Logging.h>
+
+cAbstractListAssembler::cAbstractListAssembler()
+{
+}
+
+cAbstractListAssembler::~cAbstractListAssembler()
+{
+}
+
+bool cAbstractListAssembler::AssembleList(cStringBuilder& sb, cManagedVector &ElemVector, std::map<int, size_t> &Categories, size_t start, uint delta)
+{
+ isyslog("::AssembleList() with start=%lu, delta=%i", start, delta);
+ int n = 0;
+ size_t end = start + delta;
+
+ if (end >= ElemVector.size()) {
+ end = ElemVector.size();
+ if (delta >= ElemVector.size()) start = 0;
+ else start = ElemVector.size() - delta;
+ }
+ OpenList(sb, Categories, ElemVector.size(), start, delta);
+ isyslog("now really assemble list with start=%lu, delta=%i", start, delta);
+ for (size_t i=start; i < end; ++i) {
+ AddElement(sb, ElemVector[i], ++n % 2);
+ }
+ CloseList(sb, ElemVector.size(), start, delta);
+
+ return true;
+} \ No newline at end of file
diff --git a/libs/util/src/Codec.cc b/libs/util/src/Codec.cc
new file mode 100644
index 0000000..bf6acf3
--- /dev/null
+++ b/libs/util/src/Codec.cc
@@ -0,0 +1,248 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: Codec.cc
+ * Created: 21. Mai 2012, 14:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include "Codec.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <openssl/md5.h>
+
+// --- Codec ------------------------------------------------------------------
+static cHexEncoder * hexEncoder = NULL;
+static cHexDecoder * hexDecoder = NULL;
+
+cCodec::cCodec(const char *Table, char SpecialChar)
+ : translateTable(strdup(Table))
+ , keyChar(SpecialChar)
+{
+}
+
+cCodec::~cCodec()
+{
+ FREE(translateTable);
+}
+
+size_t cCodec::DecodeSequence(unsigned char *d, unsigned char *s)
+{
+ *d = *s;
+
+ return 1;
+}
+
+// --- Encoder ----------------------------------------------------------------
+
+cEncoder::cEncoder(char SpecialChar, const char *TrTable)
+ : cCodec(TrTable, SpecialChar)
+{
+}
+
+cEncoder::~cEncoder()
+{
+}
+
+char *cEncoder::Encode(const char *Source, size_t SourceLength)
+{
+ if (!Source) return NULL;
+ if (!SourceLength) SourceLength = strlen(Source);
+
+ const unsigned char *s = (const unsigned char *)Source;
+ const unsigned char *last = (const unsigned char *)(Source + SourceLength);
+ char *rv = (char *)malloc(SourceLength * 3 + 1);
+ char *d = rv;
+ unsigned char c;
+
+ for (; s < last; ++s) {
+ c = *s;
+ if (c < 0x80 && (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~'))
+ *d++ = c;
+ else if (c == ' ')
+ *d++ = '+';
+ else {
+ *d++ = KeyChar();
+ *d++ = TranslateTable()[c >> 4];
+ *d++ = TranslateTable()[c & 0x0F];
+ }
+ }
+ *d = 0;
+
+ return rv;
+}
+
+// --- URLEncoder -------------------------------------------------------------
+
+cURLEncoder::cURLEncoder()
+ : cEncoder('%')
+{
+}
+
+cURLEncoder::~cURLEncoder()
+{
+}
+
+// --- Decoder ----------------------------------------------------------------
+
+cDecoder::cDecoder(char SpecialChar, const char *TrTable)
+ : cCodec(TrTable, SpecialChar)
+{
+}
+
+cDecoder::~cDecoder()
+{
+}
+
+char *cDecoder::Decode(const char *Source, size_t SourceLength)
+{
+ if (!Source) return NULL;
+ if (!SourceLength) SourceLength = strlen(Source);
+
+ const unsigned char *s = (const unsigned char *)Source;
+ const unsigned char *last = (const unsigned char *)(Source + SourceLength);
+ char *rv = (char *)malloc(SourceLength + 1);
+ unsigned char *d = (unsigned char *) rv;
+ size_t seqLen;
+
+ for (; s < last; ++s) {
+ if (*s == KeyChar()) {
+ seqLen = DecodeSequence(d++, (unsigned char *) ++s);
+ s += seqLen;
+ }
+ else if (*s == '+') {
+ *d++ = ' ';
+ }
+ else {
+ *d++ = *s;
+ }
+ }
+ *d = 0;
+
+ return rv;
+}
+
+size_t cDecoder::DecodeSequence(unsigned char *d, unsigned char *s)
+{
+ // just transform hex sequence back to character
+ unsigned char c = s[0] >= 'A' ? ((s[0] & 0xDF) - 'A') + 10 : (s[0] - '0');
+
+ c *= 16;
+ c += s[1] >= 'A' ? ((s[1] & 0xDF) - 'A') + 10 : (s[1] - '0');
+ *d = c;
+
+ return 1;
+}
+
+// --- URLDecoder -------------------------------------------------------------
+
+cURLDecoder::cURLDecoder()
+ : cDecoder('%')
+{
+}
+
+cURLDecoder::~cURLDecoder()
+{
+}
+
+// --- HexEncoder -------------------------------------------------------------
+
+cHexEncoder::cHexEncoder()
+ : cEncoder('#', "0123456789abcdef")
+{
+}
+
+cHexEncoder::~cHexEncoder()
+{
+}
+
+char* cHexEncoder::Encode(const unsigned char* Source, size_t SourceLength)
+{
+ if (!SourceLength) SourceLength = strlen((const char *)Source);
+ const unsigned char *s = (const unsigned char *)Source;
+ char *rv = (char *)malloc(SourceLength * 3 + 1);
+ char *d = rv;
+ unsigned char c;
+
+ for (int i=0; i < 16; ++i, ++s) {
+ c = *s;
+ *d++ = TranslateTable()[c >> 4];
+ *d++ = TranslateTable()[c & 0x0F];
+ }
+ *d = 0;
+
+ return rv;
+}
+
+cHexEncoder * getHexEncoder(void) {
+ if (!hexEncoder) hexEncoder = new cHexEncoder();
+ return hexEncoder;
+}
+
+// --- HexDecoder -------------------------------------------------------------
+
+cHexDecoder::cHexDecoder()
+{
+}
+
+cHexDecoder::~cHexDecoder()
+{
+}
+
+char* cHexDecoder::Decode(const char* Source, size_t SourceLength)
+{
+ if (!Source) return NULL;
+ if (!SourceLength) SourceLength = strlen(Source);
+
+ const unsigned char *s = (const unsigned char *)Source;
+ const unsigned char *last = (const unsigned char *)(Source + SourceLength);
+ char *rv = (char *)malloc(SourceLength + 1);
+ unsigned char *d = (unsigned char *) rv;
+ unsigned char c0, c1;
+
+ for (; s < last; s += 2) {
+ c0 = toupper(s[0]);
+ c1 = c0 >= 'A' ? ((c0 & 0xDF) - 'A') + 10 : (c0 - '0');
+ c1 *= 16;
+ c0 = toupper(s[1]);
+ c1 = c0 >= 'A' ? ((c0 & 0xDF) - 'A') + 10 : (c0 - '0');
+ *d++ = c1;
+ }
+ *d = 0;
+
+ return rv;
+}
+
+cHexDecoder * getHexDecoder(void) {
+ if (!hexDecoder) hexDecoder = new cHexDecoder();
+ return hexDecoder;
+}
+
+void codecCleanUp(void) {
+ if (hexEncoder) {
+ delete hexEncoder;
+ hexEncoder = NULL;
+ }
+ if (hexDecoder) {
+ delete hexDecoder;
+ hexDecoder = NULL;
+ }
+}
diff --git a/libs/util/src/JSonWriter.cc b/libs/util/src/JSonWriter.cc
new file mode 100644
index 0000000..cde994c
--- /dev/null
+++ b/libs/util/src/JSonWriter.cc
@@ -0,0 +1,178 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: JSonWriter.cc
+ * Created: 6. Juli 2012, 12:47
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <JSonWriter.h>
+#include <StringBuilder.h>
+#include <Logging.h>
+#include <stdio.h>
+
+cJSonWriter::cJSonWriter(cStringBuilder &StringBuilder)
+ : lastState(JS_Unknown)
+ , sb(StringBuilder)
+{
+}
+
+cJSonWriter::~cJSonWriter()
+{
+}
+
+cJSonWriter::JSonState cJSonWriter::State()
+{
+ if (state.empty()) return JS_Unknown;
+ return state.top();
+}
+
+void cJSonWriter::PushState(JSonState State)
+{
+ state.push(State);
+}
+
+cJSonWriter::JSonState cJSonWriter::PopState(void)
+{
+ lastState = State();
+ state.pop();
+
+ return lastState;
+}
+
+cJSonWriter &cJSonWriter::Object(void) {
+ if (lastState == JS_Object) sb.Append(",");
+ sb.Append("{");
+ PushState(JS_Object);
+ lastState = JS_Unknown;
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::EndObject(void) {
+ if (State() != JS_Object) {
+ esyslog("JSonWriter::EndObject(): invalid status %d - should be %d", State(), JS_Object);
+ }
+ else {
+ PopState();
+ sb.Append("}");
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Array(void) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Array(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ sb.Append("[");
+ PushState(JS_Array);
+ lastState = JS_Unknown;
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::EndArray(void) {
+ if (State() != JS_Array) {
+ esyslog("JSonWriter::EndArray(): invalid status %d - should be %d", State(), JS_Array);
+ }
+ else {
+ sb.Append("]");
+ PopState();
+ if (State() == JS_Key) PopState(); // array is a value, so pop the key
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Key(const char *Name) {
+ if (State() != JS_Object) {
+ esyslog("JSonWriter::Key(): invalid status %d - should be %d", State(), JS_Object);
+ }
+ else {
+ if (lastState == JS_Key) sb.Append(", ");
+ sb.Append("\"").Append(Name).Append("\": ");
+ PushState(JS_Key);
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(const char *Text) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append("\"").Append(Text).Append("\"");
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(int v) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append(v);
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(long v) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append(v);
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(size_t v) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append(v);
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(double v) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append(v);
+ }
+ return *this;
+}
+
+cJSonWriter &cJSonWriter::Value(bool v) {
+ if (State() != JS_Key) {
+ esyslog("JSonWriter::Value(): invalid status %d - should be %d", State(), JS_Key);
+ }
+ else {
+ PopState();
+ sb.Append(v, "true", "false");
+ }
+ return *this;
+}
diff --git a/libs/util/src/MD5Calculator.cc b/libs/util/src/MD5Calculator.cc
new file mode 100644
index 0000000..7f2aea4
--- /dev/null
+++ b/libs/util/src/MD5Calculator.cc
@@ -0,0 +1,57 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: MD5Calculator.cc
+ * Created: 3. Juli 2012, 13:15
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <MD5Calculator.h>
+#include <Codec.h>
+#include <string.h>
+
+cMD5Calculator::cMD5Calculator()
+{
+ MD5_Init(&context);
+}
+
+cMD5Calculator::~cMD5Calculator()
+{
+}
+
+void cMD5Calculator::AddContent(const char* Buf, size_t bufSize)
+{
+ if (!bufSize) bufSize = strlen(Buf);
+ MD5_Update(&context, Buf, bufSize);
+}
+
+char * cMD5Calculator::Hash(void)
+{
+ unsigned char md[20];
+
+ MD5_Final(md, &context);
+
+ return getHexEncoder()->Encode(md, 16);
+}
+
+void cMD5Calculator::Reset()
+{
+ memset(&context, 0, sizeof(context));
+ MD5_Init(&context);
+} \ No newline at end of file
diff --git a/libs/util/src/ManagedMap.cc b/libs/util/src/ManagedMap.cc
new file mode 100644
index 0000000..e0dd528
--- /dev/null
+++ b/libs/util/src/ManagedMap.cc
@@ -0,0 +1,73 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ManagedMap.cc
+ * Created: 7. Juli 2012, 08:48
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ManagedMap.h>
+#include <Logging.h>
+#include <stdlib.h>
+
+cManagedMap::cManagedMap(void (*cbFreeElem)(void *))
+ : freeCallback(cbFreeElem)
+{
+}
+
+cManagedMap::~cManagedMap()
+{
+ clear();
+}
+
+void cManagedMap::clear()
+{
+ iterator it = internalMap.begin();
+
+ while (it != internalMap.end()) {
+ if (freeCallback) {
+ isyslog("gonna free %s", it->first.c_str());
+ freeCallback(it->second);
+ }
+ ++it;
+ }
+ internalMap.clear();
+}
+
+void *cManagedMap::get(const char* key)
+{
+ const_iterator it = internalMap.find(key);
+
+ if (it == internalMap.end()) return NULL;
+ return it->second;
+}
+
+const void *cManagedMap::get(const char* key) const
+{
+ const_iterator it = internalMap.find(key);
+
+ if (it == internalMap.end()) return NULL;
+ return it->second;
+}
+
+void cManagedMap::put(const char* key, void* value)
+{
+ isyslog("cManagedMap::put[%s] => 0x%0X", key, value);
+ internalMap[key] = value;
+} \ No newline at end of file
diff --git a/libs/util/src/ManagedVector.cc b/libs/util/src/ManagedVector.cc
new file mode 100644
index 0000000..7a67bfb
--- /dev/null
+++ b/libs/util/src/ManagedVector.cc
@@ -0,0 +1,51 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ManagedVector.cc
+ * Created: 7. Juli 2012, 08:30
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <ManagedVector.h>
+#include <vector>
+#include <algorithm>
+
+cManagedVector::cManagedVector(void (*cbFreeElem)(void *))
+ : freeCallback(cbFreeElem)
+{
+}
+
+cManagedVector::~cManagedVector()
+{
+ clear();
+}
+
+void cManagedVector::clear()
+{
+ for (size_t i=0; i < internalVector.size(); ++i) {
+ freeCallback(internalVector[i]);
+ }
+ internalVector.clear();
+}
+
+void cManagedVector::sort(bool (*fnSort)(void *a, void *b))
+{
+ if (fnSort) std::sort(internalVector.begin(), internalVector.end(), fnSort);
+ else std::sort(internalVector.begin(), internalVector.end());
+} \ No newline at end of file
diff --git a/libs/util/src/NamedValue.cc b/libs/util/src/NamedValue.cc
new file mode 100644
index 0000000..f807cb6
--- /dev/null
+++ b/libs/util/src/NamedValue.cc
@@ -0,0 +1,67 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: NamedValue.cc
+ * Created: 3. Juli 2012, 17:43
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <NamedValue.h>
+#include <util.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+cNamedValue::cNamedValue(char *Name, char *Value, bool takePointers)
+ : name(takePointers ? Name : strdup(Name))
+ , value(takePointers ? Value : Value ? strdup(Value) : NULL)
+{
+}
+
+cNamedValue::cNamedValue(const char *Name, const char *Value)
+ : name(strdup(Name))
+ , value(Value ? strdup(Value) : NULL)
+{
+}
+
+cNamedValue::cNamedValue(const cNamedValue &other)
+ : name(strdup(other.name))
+ , value(other.value ? strdup(other.value) : NULL)
+{
+ printf(">>> OUPS - just cloned a named value with name<%s> and value<%s>\n", name, value);
+}
+
+cNamedValue::~cNamedValue()
+{
+ FREE(name);
+ FREE(value);
+}
+
+cNamedValue &cNamedValue::operator=(const cNamedValue &other)
+{
+ printf(">>> OUPS - I'm inside of operator = !!!\n");
+ if (&other == this) return *this;
+ FREE(name);
+ FREE(value);
+ name = strdup(other.Name());
+ if (other.value) value = strdup(other.Value());
+ else value = NULL;
+
+ return *this;
+} \ No newline at end of file
diff --git a/libs/util/src/StringBuilder.cc b/libs/util/src/StringBuilder.cc
new file mode 100644
index 0000000..8e90151
--- /dev/null
+++ b/libs/util/src/StringBuilder.cc
@@ -0,0 +1,178 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: StringBuilder.cc
+ * Created: 6. Juli 2012, 10:54
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <StringBuilder.h>
+#include <Logging.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void freeStringCallback(void *elem)
+{
+ free(elem);
+}
+
+cStringBuilder::cStringBuilder(const char *First)
+ : chunkSize(127)
+ , readOffset(0)
+ , writeOffset(0)
+ , pool(freeStringCallback)
+{
+ init();
+ if (First) Append(First);
+}
+
+cStringBuilder::cStringBuilder(int ChunkSize)
+ : chunkSize(ChunkSize)
+ , readOffset(0)
+ , writeOffset(0)
+ , pool(freeStringCallback)
+{
+ init();
+}
+
+cStringBuilder::~cStringBuilder()
+{
+}
+
+void cStringBuilder::init(void)
+{
+ char *first = (char *) malloc(chunkSize);
+
+ pool.push_back(first);
+}
+
+void cStringBuilder::Write(const char *Text)
+{
+ if (!Text) {
+ esyslog("ERROR: text to add is a NULL-ponter!");
+ return;
+ }
+ uint chunkFree = chunkSize - writeOffset;
+ char *curChunk = (char *) pool[pool.size() - 1];
+ const char *p = Text;
+
+ while (strlen(p) >= chunkFree) {
+ strncpy(curChunk + writeOffset, p, chunkFree);
+ p += chunkFree;
+
+ curChunk = (char *) malloc(chunkSize);
+ pool.push_back(curChunk);
+ writeOffset = 0;
+ chunkFree = chunkSize;
+ }
+ if (strlen(p)) {
+ strcpy(curChunk + writeOffset, p);
+ writeOffset += strlen(p);
+ }
+}
+
+size_t cStringBuilder::Size()
+{
+ return (pool.size() - 1) * chunkSize + writeOffset;
+}
+
+size_t cStringBuilder::Size() const
+{
+ return (pool.size() - 1) * chunkSize + writeOffset;
+}
+
+size_t cStringBuilder::Copy(char* Buf, size_t BufSize)
+{
+ uint chunkNo = readOffset / chunkSize;
+ uint chunkOff = readOffset % chunkSize;
+ uint bytes2Write = chunkSize;
+ char *curChunk = (char *) pool[chunkNo];
+ size_t bytesWritten = 0;
+
+ if (chunkNo == (pool.size() - 1)) bytes2Write = writeOffset;
+ while ((BufSize - bytesWritten) > (bytes2Write - chunkOff)) {
+ strncpy(Buf + bytesWritten, curChunk + chunkOff, bytes2Write - chunkOff);
+ bytesWritten += bytes2Write - chunkOff;
+
+ chunkOff = 0;
+ if (++chunkNo < (pool.size() - 1)) bytes2Write = chunkSize;
+ else bytes2Write = writeOffset;
+ if (chunkNo == pool.size()) break;
+ curChunk = (char *) pool[chunkNo];
+ }
+ readOffset += bytesWritten;
+
+ return bytesWritten;
+}
+
+cStringBuilder &cStringBuilder::Append(const char* Text)
+{
+ if (!Text) Write("(null)");
+ Write(Text);
+
+ return *this;
+}
+
+cStringBuilder &cStringBuilder::Append(bool v, const char *TrueValue, const char *FalseValue)
+{
+ if (v) Write(TrueValue);
+ else Write(FalseValue);
+
+ return *this;
+}
+
+cStringBuilder &cStringBuilder::Append(double v)
+{
+ char *elem = NULL;
+
+ asprintf(&elem, "%lg", v);
+ if (elem) {
+ Write(elem);
+ free(elem);
+ }
+ return *this;
+}
+
+cStringBuilder &cStringBuilder::Append(int v)
+{
+ char buf[12];
+
+ if (snprintf(buf, sizeof(buf), "%d", v)) Write(buf);
+
+ return *this;
+}
+
+cStringBuilder &cStringBuilder::Append(long v)
+{
+ char buf[24];
+
+ if (snprintf(buf, sizeof(buf), "%ld", v)) Write(buf);
+
+ return *this;
+}
+
+cStringBuilder &cStringBuilder::Append(size_t v)
+{
+ char buf[24];
+
+ if (snprintf(buf, sizeof(buf), "%lu", v)) Write(buf);
+
+ return *this;
+}
diff --git a/libs/util/src/util.cc b/libs/util/src/util.cc
new file mode 100644
index 0000000..8caac91
--- /dev/null
+++ b/libs/util/src/util.cc
@@ -0,0 +1,61 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: util.cc
+ * Created: 4. Juli 2012, 05:56
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libutil - base classes used by other libraries
+ *
+ * CMP - compound media player
+ *
+ * is a client/server mediaplayer intended to play any media from any workstation
+ * without the need to export or mount shares. cmps is an easy to use backend
+ * with a (ready to use) HTML-interface. Additionally the backend supports
+ * authentication via HTTP-digest authorization.
+ * cmpc is a client with vdr-like osd-menues.
+ *
+ * Copyright (c) 2012 Reinhard Mantey, some rights reserved!
+ * published under Creative Commons by-sa
+ * For details see http://creativecommons.org/licenses/by-sa/3.0/
+ *
+ * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
+ *
+ * --------------------------------------------------------------
+ */
+#include <util.h>
+#include <string.h>
+#include <ctype.h>
+
+const char * skipWhitespace(const char *Buffer)
+{
+ while (*Buffer && isspace(*Buffer)) ++Buffer;
+
+ return Buffer;
+}
+
+const char *getWord(char *buf, int bufSize, const char *src)
+{
+ const char *s = src;
+ char *d = buf;
+
+ if (!strncmp(src, "\n\n", 2) || !strncmp(src, "\r\n\r\n", 4))
+ return src;
+
+ while (*s && isspace(*s)) ++s;
+ while (*s && ((d - buf) < bufSize) && !isspace(*s)) *d++ = *s++;
+ *d = 0;
+
+ return *s ? s : NULL;
+}
+
+const char *restOfLine(char *buf, int bufSize, const char *src)
+{
+ const char *s = src;
+ char *d = buf;
+
+ while (*s && isspace(*s)) ++s;
+ while (*s && ((d - buf) < bufSize) && *s != '\n' && *s != '\r') *d++ = *s++;
+ *d = 0;
+
+ return *s ? s : NULL;
+}
diff --git a/libs/util/summary.txt b/libs/util/summary.txt
new file mode 100644
index 0000000..38b8ade
--- /dev/null
+++ b/libs/util/summary.txt
@@ -0,0 +1 @@
+libutil - base classes used by other libraries
diff --git a/libs/util/util.cbp b/libs/util/util.cbp
new file mode 100644
index 0000000..d582dc0
--- /dev/null
+++ b/libs/util/util.cbp
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="CMP.libs.util" />
+ <Option pch_mode="2" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Debug">
+ <Option output="libutil" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Debug/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-g" />
+ </Compiler>
+ </Target>
+ <Target title="Release">
+ <Option output="libutil" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Release/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Wall" />
+ <Add option="-O2" />
+ </Compiler>
+ <Linker>
+ <Add option="-s" />
+ </Linker>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi" />
+ <Add option="-D_REENTRANT" />
+ <Add option="-D_GNU_SOURCE=1" />
+ <Add directory="../vdr/include" />
+ <Add directory="include" />
+ </Compiler>
+ <Unit filename="include/AbstractListAssembler.h" />
+ <Unit filename="include/Codec.h" />
+ <Unit filename="include/JSonWriter.h" />
+ <Unit filename="include/MD5Calculator.h" />
+ <Unit filename="include/ManagedMap.h" />
+ <Unit filename="include/ManagedVector.h" />
+ <Unit filename="include/NamedValue.h" />
+ <Unit filename="include/StringBuilder.h" />
+ <Unit filename="include/util.h" />
+ <Unit filename="src/AbstractListAssembler.cc" />
+ <Unit filename="src/Codec.cc" />
+ <Unit filename="src/JSonWriter.cc" />
+ <Unit filename="src/MD5Calculator.cc" />
+ <Unit filename="src/ManagedMap.cc" />
+ <Unit filename="src/ManagedVector.cc" />
+ <Unit filename="src/NamedValue.cc" />
+ <Unit filename="src/StringBuilder.cc" />
+ <Unit filename="src/util.cc" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <lib_finder disable_auto="1" />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/libs/util/util.depend b/libs/util/util.depend
new file mode 100644
index 0000000..c4ac310
--- /dev/null
+++ b/libs/util/util.depend
@@ -0,0 +1 @@
+# depslib dependency file v1.0
diff --git a/libs/util/util.layout b/libs/util/util.layout
new file mode 100644
index 0000000..d3bb1e5
--- /dev/null
+++ b/libs/util/util.layout
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="include/JSonWriter.h" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="773" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/StringBuilder.cc" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="3065" topLine="38" />
+ </Cursor>
+ </File>
+ <File name="src/AbstractListAssembler.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/StringBuilder.h" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="560" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ManagedMap.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/ManagedMap.cc" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/JSonWriter.cc" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="294" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ManagedVector.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/util/util.layout.save b/libs/util/util.layout.save
new file mode 100644
index 0000000..94e3e2d
--- /dev/null
+++ b/libs/util/util.layout.save
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="include/ManagedMap.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/StringBuilder.cc" open="1" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/ManagedVector.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/StringBuilder.h" open="1" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/JSonWriter.cc" open="1" top="1" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/JSonWriter.h" open="1" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/ManagedMap.cc" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/AbstractListAssembler.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/vdr/.dep.inc b/libs/vdr/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/libs/vdr/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/libs/vdr/Makefile b/libs/vdr/Makefile
new file mode 100644
index 0000000..ec9de69
--- /dev/null
+++ b/libs/vdr/Makefile
@@ -0,0 +1,128 @@
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# Available make variables:
+#
+# CND_BASEDIR base directory for relative paths
+# CND_DISTDIR default top distribution directory (build artifacts)
+# CND_BUILDDIR default top build directory (object files, ...)
+# CONF name of current configuration
+# CND_PLATFORM_${CONF} platform name (current configuration)
+# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
+# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
+# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
+# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
+# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
+# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
+#
+# NOCDDL
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+
+
+# build
+build: .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post: .build-impl
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post: .clean-impl
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+# build tests
+build-tests: .build-tests-post
+
+.build-tests-pre:
+# Add your pre 'build-tests' code here...
+
+.build-tests-post: .build-tests-impl
+# Add your post 'build-tests' code here...
+
+
+# run tests
+test: .test-post
+
+.test-pre:
+# Add your pre 'test' code here...
+
+.test-post: .test-impl
+# Add your post 'test' code here...
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
+
+# include project make variables
+include nbproject/Makefile-variables.mk
diff --git a/libs/vdr/doc/Legal.Note b/libs/vdr/doc/Legal.Note
new file mode 100644
index 0000000..1a45581
--- /dev/null
+++ b/libs/vdr/doc/Legal.Note
@@ -0,0 +1,27 @@
+@@FileInfo@@
+@@AppInfo@@
+
+from "Video Disk Recorder":
+
+Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+
+The original author can be reached at kls@tvdr.de
+
+The vdr project's page is at http://www.tvdr.de
+
+@@Comment@@
diff --git a/libs/vdr/include/CharsetConv.h b/libs/vdr/include/CharsetConv.h
new file mode 100644
index 0000000..3a05f56
--- /dev/null
+++ b/libs/vdr/include/CharsetConv.h
@@ -0,0 +1,115 @@
+/**
+ * File: CharsetConv.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef CHARSETCONV_H
+#define CHARSETCONV_H
+
+#include <stddef.h>
+#include <sys/types.h>
+#include <iconv.h>
+typedef unsigned char uchar;
+
+// When handling strings that might contain UTF-8 characters, it may be necessary
+// to process a "symbol" that consists of several actual character bytes. The
+// following functions allow transparently accessing a "char *" string without
+// having to worry about what character set is actually used.
+
+int Utf8CharLen(const char *s);
+ ///< Returns the number of character bytes at the beginning of the given
+ ///< string that form a UTF-8 symbol.
+uint Utf8CharGet(const char *s, int Length = 0);
+ ///< Returns the UTF-8 symbol at the beginning of the given string.
+ ///< Length can be given from a previous call to Utf8CharLen() to avoid calculating
+ ///< it again. If no Length is given, Utf8CharLen() will be called.
+int Utf8CharSet(uint c, char *s = NULL);
+ ///< Converts the given UTF-8 symbol to a sequence of character bytes and copies
+ ///< them to the given string. Returns the number of bytes written. If no string
+ ///< is given, only the number of bytes is returned and nothing is copied.
+int Utf8SymChars(const char *s, int Symbols);
+ ///< Returns the number of character bytes at the beginning of the given
+ ///< string that form at most the given number of UTF-8 symbols.
+int Utf8StrLen(const char *s);
+ ///< Returns the number of UTF-8 symbols formed by the given string of
+ ///< character bytes.
+char *Utf8Strn0Cpy(char *Dest, const char *Src, int n);
+ ///< Copies at most n character bytes from Src to Dest, making sure that the
+ ///< resulting copy ends with a complete UTF-8 symbol. The copy is guaranteed
+ ///< to be zero terminated.
+ ///< Returns a pointer to Dest.
+int Utf8ToArray(const char *s, uint *a, int Size);
+ ///< Converts the given character bytes (including the terminating 0) into an
+ ///< array of UTF-8 symbols of the given Size. Returns the number of symbols
+ ///< in the array (without the terminating 0).
+int Utf8FromArray(const uint *a, char *s, int Size, int Max = -1);
+ ///< Converts the given array of UTF-8 symbols (including the terminating 0)
+ ///< into a sequence of character bytes of at most Size length. Returns the
+ ///< number of character bytes written (without the terminating 0).
+ ///< If Max is given, only that many symbols will be converted.
+ ///< The resulting string is always zero-terminated if Size is big enough.
+
+// When allocating buffer space, make sure we reserve enough space to hold
+// a string in UTF-8 representation:
+
+#define Utf8BufSize(s) ((s) * 4)
+
+// The following macros automatically use the correct versions of the character
+// class functions:
+
+#define Utf8to(conv, c) (cCharSetConv::SystemCharacterTable() ? to##conv(c) : tow##conv(c))
+#define Utf8is(ccls, c) (cCharSetConv::SystemCharacterTable() ? is##ccls(c) : isw##ccls(c))
+
+class cCharSetConv {
+public:
+ cCharSetConv(const char *FromCode = NULL, const char *ToCode = NULL);
+ ///< Sets up a character set converter to convert from FromCode to ToCode.
+ ///< If FromCode is NULL, the previously set systemCharacterTable is used
+ ///< (or "UTF-8" if no systemCharacterTable has been set).
+ ///< If ToCode is NULL, "UTF-8" is used.
+ ~cCharSetConv();
+ const char *Convert(const char *From, char *To = NULL, size_t ToLength = 0);
+ ///< Converts the given Text from FromCode to ToCode (as set in the constructor).
+ ///< If To is given, it is used to copy at most ToLength bytes of the result
+ ///< (including the terminating 0) into that buffer. If To is not given,
+ ///< the result is copied into a dynamically allocated buffer and is valid as
+ ///< long as this object lives, or until the next call to Convert(). The
+ ///< return value always points to the result if the conversion was successful
+ ///< (even if a fixed size To buffer was given and the result didn't fit into
+ ///< it). If the string could not be converted, the result points to the
+ ///< original From string.
+ static const char *SystemCharacterTable(void) { return systemCharacterTable; }
+ static void SetSystemCharacterTable(const char *CharacterTable);
+
+private:
+ iconv_t cd;
+ char *result;
+ size_t length;
+ static char *systemCharacterTable;
+ };
+
+#endif /* CHARSETCONV_H */
+
diff --git a/libs/vdr/include/CondWait.h b/libs/vdr/include/CondWait.h
new file mode 100644
index 0000000..1e663df
--- /dev/null
+++ b/libs/vdr/include/CondWait.h
@@ -0,0 +1,61 @@
+/**
+ * File: CondWait.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef CONDWAIT_H
+#define CONDWAIT_H
+
+#include <pthread.h>
+
+class cCondWait {
+public:
+ cCondWait(void);
+ ~cCondWait();
+
+ bool Wait(int TimeoutMs = 0);
+ ///< Waits at most TimeoutMs milliseconds for a call to Signal(), or
+ ///< forever if TimeoutMs is 0.
+ ///< \return Returns true if Signal() has been called, false it the given
+ ///< timeout has expired.
+ void Signal(void);
+ ///< Signals a caller of Wait() that the condition it is waiting for is met.
+
+ static void SleepMs(int TimeoutMs);
+ ///< Creates a cCondWait object and uses it to sleep for TimeoutMs
+ ///< milliseconds, immediately giving up the calling thread's time
+ ///< slice and thus avoiding a "busy wait".
+ ///< In order to avoid a possible busy wait, TimeoutMs will be automatically
+ ///< limited to values >2.
+
+private:
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ bool signaled;
+ };
+
+#endif /* CONDWAIT_H */
+
diff --git a/libs/vdr/include/FileNameList.h b/libs/vdr/include/FileNameList.h
new file mode 100644
index 0000000..c8bc6af
--- /dev/null
+++ b/libs/vdr/include/FileNameList.h
@@ -0,0 +1,41 @@
+/**
+ * File: FileNameList.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef FILENAMELIST_H
+#define FILENAMELIST_H
+
+#include <StringList.h>
+
+class cFileNameList : public cStringList {
+public:
+ cFileNameList(const char *Directory = NULL, bool DirsOnly = false);
+ bool Load(const char *Directory, bool DirsOnly = false);
+ };
+
+#endif /* FILENAMELIST_H */
+
diff --git a/libs/vdr/include/Logging.h b/libs/vdr/include/Logging.h
new file mode 100644
index 0000000..4dd1300
--- /dev/null
+++ b/libs/vdr/include/Logging.h
@@ -0,0 +1,45 @@
+/**
+ * File: Logging.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef LOGGING_H
+#define LOGGING_H
+
+#include <sys/syslog.h>
+
+extern int SysLogLevel;
+extern void syslog_with_tid(int priority, const char *format, ...);
+
+#define esyslog(a...) void( (SysLogLevel > 0) ? syslog_with_tid(LOG_ERR, a) : void() )
+#define isyslog(a...) void( (SysLogLevel > 1) ? syslog_with_tid(LOG_ERR, a) : void() )
+#define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_ERR, a) : void() )
+
+#define LOG_ERROR esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__)
+#define LOG_ERROR_STR(s) esyslog("ERROR (%s,%d): %s: %m", __FILE__, __LINE__, s)
+
+#endif /* LOGGING_H */
+
diff --git a/libs/vdr/include/Mutex.h b/libs/vdr/include/Mutex.h
new file mode 100644
index 0000000..5ea6cf2
--- /dev/null
+++ b/libs/vdr/include/Mutex.h
@@ -0,0 +1,63 @@
+/**
+ * File: Mutex.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef MUTEX_H
+#define MUTEX_H
+
+#include <pthread.h>
+
+class cMutex {
+public:
+ cMutex(void);
+ ~cMutex();
+ void Lock(void);
+ void Unlock(void);
+
+private:
+ pthread_mutex_t mutex;
+ int locked;
+ friend class cCondVar;
+ };
+
+// cMutexLock can be used to easily set a lock on mutex and make absolutely
+// sure that it will be unlocked when the block will be left. Several locks can
+// be stacked, so a function that makes many calls to another function which uses
+// cMutexLock may itself use a cMutexLock to make one longer lock instead of many
+// short ones.
+class cMutexLock {
+private:
+ cMutex *mutex;
+ bool locked;
+public:
+ cMutexLock(cMutex *Mutex = NULL);
+ ~cMutexLock();
+ bool Lock(cMutex *Mutex);
+ };
+
+#endif /* MUTEX_H */
+
diff --git a/libs/vdr/include/ReadDir.h b/libs/vdr/include/ReadDir.h
new file mode 100644
index 0000000..466976d
--- /dev/null
+++ b/libs/vdr/include/ReadDir.h
@@ -0,0 +1,53 @@
+/**
+ * File: ReadDir.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef READDIR_H
+#define READDIR_H
+
+#include <stddef.h>
+#include <dirent.h>
+#include <sys/types.h>
+
+class cReadDir {
+public:
+ cReadDir(const char *Directory);
+ ~cReadDir();
+ bool Ok(void) { return directory != NULL; }
+ struct dirent *Next(void);
+
+private:
+ DIR *directory;
+ struct dirent *result;
+ union { // according to "The GNU C Library Reference Manual"
+ struct dirent d;
+ char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
+ } u;
+ };
+
+#endif /* READDIR_H */
+
diff --git a/libs/vdr/include/String.h b/libs/vdr/include/String.h
new file mode 100644
index 0000000..ec03cc1
--- /dev/null
+++ b/libs/vdr/include/String.h
@@ -0,0 +1,85 @@
+/**
+ * File: String.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef STRING_H
+#define STRING_H
+
+#include <CharsetConv.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+class cString {
+public:
+ cString(const char *S = NULL, bool TakePointer = false);
+ cString(const cString &String);
+ virtual ~cString();
+ operator const void * () const { return s; } // to catch cases where operator*() should be used
+ operator const char * () const { return s; } // for use in (const char *) context
+ const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.)
+ cString &operator=(const cString &String);
+ cString &operator=(const char *String);
+ cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string).
+ static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+ static cString vsprintf(const char *fmt, va_list &ap);
+
+private:
+ char *s;
+ };
+
+char *strcpyrealloc(char *dest, const char *src);
+char *strn0cpy(char *dest, const char *src, size_t n);
+char *strreplace(char *s, char c1, char c2);
+char *strreplace(char *s, const char *s1, const char *s2); ///< re-allocates 's' and deletes the original string if necessary!
+inline char *skipspace(const char *s)
+{
+ if ((uchar)*s > ' ') // most strings don't have any leading space, so handle this case as fast as possible
+ return (char *)s;
+ while (*s && (uchar)*s <= ' ') // avoiding isspace() here, because it is much slower
+ s++;
+ return (char *)s;
+}
+char *stripspace(char *s);
+char *compactspace(char *s);
+cString strescape(const char *s, const char *chars);
+bool startswith(const char *s, const char *p);
+bool endswith(const char *s, const char *p);
+bool isempty(const char *s);
+int numdigits(int n);
+bool isnumber(const char *s);
+int64_t StrToNum(const char *s);
+ ///< Converts the given string to a number.
+ ///< The numerical part of the string may be followed by one of the letters
+ ///< K, M, G or T to abbreviate Kilo-, Mega-, Giga- or Terabyte, respectively
+ ///< (based on 1024). Everything after the first non-numeric character is
+ ///< silently ignored, as are any characters other than the ones mentioned here.
+cString itoa(int n);
+
+
+
+#endif /* STRING_H */
+
diff --git a/libs/vdr/include/StringList.h b/libs/vdr/include/StringList.h
new file mode 100644
index 0000000..fee534b
--- /dev/null
+++ b/libs/vdr/include/StringList.h
@@ -0,0 +1,61 @@
+/**
+ * File: StringList.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef STRINGLIST_H
+#define STRINGLIST_H
+
+#include <Vector.h>
+#include <string.h>
+
+inline int CompareStrings(const void *a, const void *b)
+{
+ return strcmp(*(const char **)a, *(const char **)b);
+}
+
+inline int CompareStringsIgnoreCase(const void *a, const void *b)
+{
+ return strcasecmp(*(const char **)a, *(const char **)b);
+}
+
+class cStringList : public cVector<char *> {
+public:
+ cStringList(int Allocated = 10): cVector<char *>(Allocated) {}
+ virtual ~cStringList();
+ int Find(const char *s) const;
+ void Sort(bool IgnoreCase = false)
+ {
+ if (IgnoreCase)
+ cVector<char *>::Sort(CompareStringsIgnoreCase);
+ else
+ cVector<char *>::Sort(CompareStrings);
+ }
+ virtual void Clear(void);
+ };
+
+#endif /* STRINGLIST_H */
+
diff --git a/libs/vdr/include/Thread.h b/libs/vdr/include/Thread.h
new file mode 100644
index 0000000..ce8c999
--- /dev/null
+++ b/libs/vdr/include/Thread.h
@@ -0,0 +1,101 @@
+/**
+ * File: Thread.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ * ++2012-07-04(rma):
+ * As I don't like the necessity to subclass what should work in a thread,
+ * I extended the original sources, so that an arbitrary function can be
+ * a thread kernel.
+ */
+#ifndef THREAD_H
+#define THREAD_H
+
+#include <Mutex.h>
+#include <stddef.h>
+#include <pthread.h>
+typedef pid_t tThreadId;
+
+class cThread {
+public:
+ cThread(const char *Description = NULL);
+ ///< Creates a new thread.
+ ///< If Description is present, a log file entry will be made when
+ ///< the thread starts and stops. The Start() function must be called
+ ///< to actually start the thread.
+ cThread(int (*ThreadCallback)(void *opaque, cThread *instance), void *opaque, const char *Description = NULL);
+ virtual ~cThread();
+
+ void SetDescription(const char *Description, ...) __attribute__ ((format (printf, 2, 3)));
+ bool Start(void);
+ ///< Actually starts the thread.
+ ///< If the thread is already running, nothing happens.
+ virtual void Cancel(int WaitSeconds = 0);
+ ///< Cancels the thread by first setting 'running' to false, so that
+ ///< the Action() loop can finish in an orderly fashion and then waiting
+ ///< up to WaitSeconds seconds for the thread to actually end. If the
+ ///< thread doesn't end by itself, it is killed.
+ ///< If WaitSeconds is -1, only 'running' is set to false and Cancel()
+ ///< returns immediately, without killing the thread.
+ bool Active(void);
+ ///< used from outside to check whether the thread is still alive.
+ bool Running(void) { return running; }
+ ///< used from inside the thread to check whether it may keep on running.
+ ///< Returns false if a derived cThread object shall leave its Action()
+ ///< function. Should be public and so available for callback thread kernels
+
+ static tThreadId ThreadId(void);
+ static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; }
+ static void SetMainThreadId(void);
+
+protected:
+ void SetPriority(int Priority);
+ void SetIOPriority(int Priority);
+ void Lock(void) { mutex.Lock(); }
+ void Unlock(void) { mutex.Unlock(); }
+ virtual void Action(void);
+ ///< A derived cThread class must implement the code it wants to
+ ///< execute as a separate thread in this function. If this is
+ ///< a loop, it must check Running() repeatedly to see whether
+ ///< it's time to stop.
+ ///< To support callbacks as thread kernels, default implementation now
+ ///< starts the callback
+
+private:
+ bool active;
+ bool running;
+ pthread_t childTid;
+ tThreadId childThreadId;
+ cMutex mutex;
+ char *description;
+ int (*threadCallback)(void *, cThread *);
+ void *opaque;
+ static tThreadId mainThreadId;
+ static void *StartThread(cThread *Thread);
+ friend class cThreadLock;
+ };
+
+#endif /* THREAD_H */
+
diff --git a/libs/vdr/include/TimeMs.h b/libs/vdr/include/TimeMs.h
new file mode 100644
index 0000000..dca609f
--- /dev/null
+++ b/libs/vdr/include/TimeMs.h
@@ -0,0 +1,50 @@
+/**
+ * File: TimeMs.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef TIMEMS_H
+#define TIMEMS_H
+
+#include <inttypes.h>
+
+class cTimeMs {
+public:
+ cTimeMs(int Ms = 0);
+ ///< Creates a timer with ms resolution and an initial timeout of Ms.
+ ///< If Ms is negative the timer is not initialized with the current
+ ///< time.
+ void Set(int Ms = 0);
+ bool TimedOut(void);
+ uint64_t Elapsed(void);
+ static uint64_t Now(void);
+
+private:
+ uint64_t begin;
+ };
+
+#endif /* TIMEMS_H */
+
diff --git a/libs/vdr/include/Vector.h b/libs/vdr/include/Vector.h
new file mode 100644
index 0000000..65760ac
--- /dev/null
+++ b/libs/vdr/include/Vector.h
@@ -0,0 +1,119 @@
+/**
+ * File: Vector.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <stddef.h>
+#include <Logging.h>
+#include <stdlib.h>
+
+template<class T> class cVector {
+ ///< cVector may only be used for *simple* types, like int or pointers - not for class objects that allocate additional memory!
+public:
+ cVector(int Allocated = 10)
+ {
+ allocated = 0;
+ size = 0;
+ data = NULL;
+ Realloc(Allocated);
+ }
+ virtual ~cVector() { free(data); }
+ T& At(int Index) const
+ {
+ Realloc(Index);
+ if (Index >= size)
+ size = Index + 1;
+ return data[Index];
+ }
+ const T& operator[](int Index) const
+ {
+ return At(Index);
+ }
+ T& operator[](int Index)
+ {
+ return At(Index);
+ }
+ int Size(void) const { return size; }
+ virtual void Insert(T Data, int Before = 0)
+ {
+ if (Before < size) {
+ Realloc(size);
+ memmove(&data[Before + 1], &data[Before], (size - Before) * sizeof(T));
+ size++;
+ data[Before] = Data;
+ }
+ else
+ Append(Data);
+ }
+ virtual void Append(T Data)
+ {
+ if (size >= allocated)
+ Realloc(allocated * 3 / 2); // increase size by 50%
+ data[size++] = Data;
+ }
+ virtual void Remove(int Index)
+ {
+ if (Index < size - 1)
+ memmove(&data[Index], &data[Index + 1], (size - Index) * sizeof(T));
+ size--;
+ }
+ virtual void Clear(void)
+ {
+ for (int i = 0; i < size; i++)
+ data[i] = T(0);
+ size = 0;
+ }
+ void Sort(__compar_fn_t Compare)
+ {
+ qsort(data, size, sizeof(T), Compare);
+ }
+
+private:
+ mutable int allocated;
+ mutable int size;
+ mutable T *data;
+ cVector(const cVector &Vector) {} // don't copy...
+ cVector &operator=(const cVector &Vector) { return *this; } // ...or assign this!
+ void Realloc(int Index) const
+ {
+ if (++Index > allocated) {
+ data = (T *)realloc(data, Index * sizeof(T));
+ if (!data) {
+ esyslog("ERROR: out of memory - abort!");
+ abort();
+ }
+ for (int i = allocated; i < Index; i++)
+ data[i] = T(0);
+ allocated = Index;
+ }
+ }
+ };
+
+#endif /* VECTOR_H */
+
diff --git a/libs/vdr/include/i18n.h b/libs/vdr/include/i18n.h
new file mode 100644
index 0000000..40185e4
--- /dev/null
+++ b/libs/vdr/include/i18n.h
@@ -0,0 +1,108 @@
+/**
+ * File: i18n.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef __I18N_H
+#define __I18N_H
+
+#include <stdio.h>
+
+#define I18N_DEFAULT_LOCALE "en_US"
+#define I18N_MAX_LOCALE_LEN 16 // for buffers that hold en_US etc.
+#define I18N_MAX_LANGUAGES 256 // for buffers that hold all available languages
+class cStringList;
+void I18nInitialize(const char *LocaleDir = NULL);
+ ///< Detects all available locales and loads the language names and codes.
+ ///< If LocaleDir is given, it must point to a static string that lives
+ ///< for the entire lifetime of the program.
+void I18nRegister(const char *Plugin);
+ ///< Registers the named plugin, so that it can use internationalized texts.
+void I18nSetLocale(const char *Locale);
+ ///< Sets the current locale to Locale. The default locale is "en_US".
+ ///< If no such locale has been found in the call to I18nInitialize(),
+ ///< nothing happens.
+int I18nCurrentLanguage(void);
+ ///< Returns the index of the current language. This number stays the
+ ///< same for any given language while the program is running, but may
+ ///< be different when the program is run again (for instance because
+ ///< a locale has been added or removed). The default locale ("en_US")
+ ///< always has a zero index.
+void I18nSetLanguage(int Language);
+ ///< Sets the current language index to Language. If Language is outside
+ ///< the range of available languages, nothing happens.
+int I18nNumLanguagesWithLocale(void);
+ ///< Returns the number of entries in the list returned by I18nLanguages()
+ ///< that actually have a locale.
+const cStringList *I18nLanguages(void);
+ ///< Returns the list of available languages. Values returned by
+ ///< I18nCurrentLanguage() are indexes into this list.
+ ///< Only the first I18nNumLanguagesWithLocale() entries in this list
+ ///< have an actual locale installed. The rest are just dummy entries
+ ///< to allow having three letter language codes for other languages
+ ///< that have no actual locale on this system.
+const char *I18nTranslate(const char *s, const char *Plugin = NULL) __attribute_format_arg__(1);
+ ///< Translates the given string (with optional Plugin context) into
+ ///< the current language. If no translation is available, the original
+ ///< string will be returned.
+const char *I18nLocale(int Language);
+ ///< Returns the locale code of the given Language (which is an index as
+ ///< returned by I18nCurrentLanguage()). If Language is outside the range
+ ///< of available languages, NULL is returned.
+const char *I18nLanguageCode(int Language);
+ ///< Returns the three letter language code of the given Language (which
+ ///< is an index as returned by I18nCurrentLanguage()). If Language is
+ ///< outside the range of available languages, NULL is returned.
+ ///< The returned string may consist of several alternative three letter
+ ///< language codes, separated by commas (as in "deu,ger").
+int I18nLanguageIndex(const char *Code);
+ ///< Returns the index of the language with the given three letter
+ ///< language Code. If no suitable language is found, -1 is returned.
+const char *I18nNormalizeLanguageCode(const char *Code);
+ ///< Returns a 3 letter language code that may not be zero terminated.
+ ///< If no normalized language code can be found, the given Code is returned.
+ ///< Make sure at most 3 characters are copied when using it!
+bool I18nIsPreferredLanguage(int *PreferredLanguages, const char *LanguageCode, int &OldPreference, int *Position = NULL);
+ ///< Checks the given LanguageCode (which may be something like "eng" or "eng+deu")
+ ///< against the PreferredLanguages and returns true if one is found that has an index
+ ///< smaller than OldPreference (which should be initialized to -1 before the first
+ ///< call to this function in a sequence of checks). If LanguageCode is not any of
+ ///< the PreferredLanguages, and OldPreference is less than zero, OldPreference will
+ ///< be set to a value higher than the highest language index. If Position is given,
+ ///< it will return 0 if this was a single language code (like "eng"), 1 if it was
+ ///< the first of two language codes (like "eng" out of "eng+deu") and 2 if it was
+ ///< the second one (like "deu" out of ""eng+deu").
+
+#ifdef PLUGIN_NAME_I18N
+#define tr(s) I18nTranslate(s, "vdr-" PLUGIN_NAME_I18N)
+#define trVDR(s) I18nTranslate(s) // to use a text that's in the VDR core's translation file
+#else
+#define tr(s) I18nTranslate(s)
+#endif
+
+#define trNOOP(s) (s)
+
+#endif //__I18N_H
diff --git a/libs/vdr/include/tools.h b/libs/vdr/include/tools.h
new file mode 100644
index 0000000..bb159aa
--- /dev/null
+++ b/libs/vdr/include/tools.h
@@ -0,0 +1,49 @@
+/**
+ * File: tools.h
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#ifndef TOOLS_H
+#define TOOLS_H
+
+#include <stddef.h>
+
+#define MALLOC(type, size) (type *)malloc(sizeof(type) * (size))
+
+template<class T> inline void DELETENULL(T *&p) { T *q = p; p = NULL; delete q; }
+
+#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
+#define FATALERRNO (errno && errno != EAGAIN && errno != EINTR)
+
+#ifndef __STL_CONFIG_H // in case some plugin needs to use the STL
+template<class T> inline T min(T a, T b) { return a <= b ? a : b; }
+template<class T> inline T max(T a, T b) { return a >= b ? a : b; }
+template<class T> inline int sgn(T a) { return a < 0 ? -1 : a > 0 ? 1 : 0; }
+template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; }
+#endif
+
+#endif /* TOOLS_H */
+
diff --git a/libs/vdr/nbproject/Makefile-Debug.mk b/libs/vdr/nbproject/Makefile-Debug.mk
new file mode 100644
index 0000000..af3fe72
--- /dev/null
+++ b/libs/vdr/nbproject/Makefile-Debug.mk
@@ -0,0 +1,145 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/StringList.o \
+ ${OBJECTDIR}/src/TimeMs.o \
+ ${OBJECTDIR}/src/Thread.o \
+ ${OBJECTDIR}/src/String.o \
+ ${OBJECTDIR}/src/i18n.o \
+ ${OBJECTDIR}/src/Logging.o \
+ ${OBJECTDIR}/src/ReadDir.o \
+ ${OBJECTDIR}/src/CondWait.o \
+ ${OBJECTDIR}/src/FileNameList.o \
+ ${OBJECTDIR}/src/Mutex.o \
+ ${OBJECTDIR}/src/CharsetConv.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+CXXFLAGS=-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+${OBJECTDIR}/src/StringList.o: nbproject/Makefile-${CND_CONF}.mk src/StringList.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/StringList.o src/StringList.cc
+
+${OBJECTDIR}/src/TimeMs.o: nbproject/Makefile-${CND_CONF}.mk src/TimeMs.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/TimeMs.o src/TimeMs.cc
+
+${OBJECTDIR}/src/Thread.o: nbproject/Makefile-${CND_CONF}.mk src/Thread.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Thread.o src/Thread.cc
+
+${OBJECTDIR}/src/String.o: nbproject/Makefile-${CND_CONF}.mk src/String.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/String.o src/String.cc
+
+${OBJECTDIR}/src/i18n.o: nbproject/Makefile-${CND_CONF}.mk src/i18n.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/i18n.o src/i18n.cc
+
+${OBJECTDIR}/src/Logging.o: nbproject/Makefile-${CND_CONF}.mk src/Logging.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Logging.o src/Logging.cc
+
+${OBJECTDIR}/src/ReadDir.o: nbproject/Makefile-${CND_CONF}.mk src/ReadDir.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ReadDir.o src/ReadDir.cc
+
+${OBJECTDIR}/src/CondWait.o: nbproject/Makefile-${CND_CONF}.mk src/CondWait.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/CondWait.o src/CondWait.cc
+
+${OBJECTDIR}/src/FileNameList.o: nbproject/Makefile-${CND_CONF}.mk src/FileNameList.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/FileNameList.o src/FileNameList.cc
+
+${OBJECTDIR}/src/Mutex.o: nbproject/Makefile-${CND_CONF}.mk src/Mutex.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Mutex.o src/Mutex.cc
+
+${OBJECTDIR}/src/CharsetConv.o: nbproject/Makefile-${CND_CONF}.mk src/CharsetConv.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -g -Wall -DLOCDIR=/usr/share/locale -D_GNU_SOURCE=1 -D_REENTRANT -Iinclude -I/usr/include/freetype2 -I/usr/include/fribidi -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/CharsetConv.o src/CharsetConv.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/vdr/nbproject/Makefile-Release.mk b/libs/vdr/nbproject/Makefile-Release.mk
new file mode 100644
index 0000000..af83e45
--- /dev/null
+++ b/libs/vdr/nbproject/Makefile-Release.mk
@@ -0,0 +1,145 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a -pre and a -post target defined where you can add customized code.
+#
+# This makefile implements configuration specific macros and targets.
+
+
+# Environment
+MKDIR=mkdir
+CP=cp
+GREP=grep
+NM=nm
+CCADMIN=CCadmin
+RANLIB=ranlib
+CC=gcc
+CCC=g++
+CXX=g++
+FC=gfortran
+AS=as
+
+# Macros
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+
+# Include project Makefile
+include Makefile
+
+# Object Directory
+OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}
+
+# Object Files
+OBJECTFILES= \
+ ${OBJECTDIR}/src/StringList.o \
+ ${OBJECTDIR}/src/TimeMs.o \
+ ${OBJECTDIR}/src/Thread.o \
+ ${OBJECTDIR}/src/String.o \
+ ${OBJECTDIR}/src/i18n.o \
+ ${OBJECTDIR}/src/Logging.o \
+ ${OBJECTDIR}/src/ReadDir.o \
+ ${OBJECTDIR}/src/CondWait.o \
+ ${OBJECTDIR}/src/FileNameList.o \
+ ${OBJECTDIR}/src/Mutex.o \
+ ${OBJECTDIR}/src/CharsetConv.o
+
+
+# C Compiler Flags
+CFLAGS=
+
+# CC Compiler Flags
+CCFLAGS=
+CXXFLAGS=
+
+# Fortran Compiler Flags
+FFLAGS=
+
+# Assembler Flags
+ASFLAGS=
+
+# Link Libraries and Options
+LDLIBSOPTIONS=
+
+# Build Targets
+.build-conf: ${BUILD_SUBPROJECTS}
+ "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a: ${OBJECTFILES}
+ ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+ ${AR} -rv ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a ${OBJECTFILES}
+ $(RANLIB) ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+${OBJECTDIR}/src/StringList.o: nbproject/Makefile-${CND_CONF}.mk src/StringList.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/StringList.o src/StringList.cc
+
+${OBJECTDIR}/src/TimeMs.o: nbproject/Makefile-${CND_CONF}.mk src/TimeMs.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/TimeMs.o src/TimeMs.cc
+
+${OBJECTDIR}/src/Thread.o: nbproject/Makefile-${CND_CONF}.mk src/Thread.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Thread.o src/Thread.cc
+
+${OBJECTDIR}/src/String.o: nbproject/Makefile-${CND_CONF}.mk src/String.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/String.o src/String.cc
+
+${OBJECTDIR}/src/i18n.o: nbproject/Makefile-${CND_CONF}.mk src/i18n.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/i18n.o src/i18n.cc
+
+${OBJECTDIR}/src/Logging.o: nbproject/Makefile-${CND_CONF}.mk src/Logging.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Logging.o src/Logging.cc
+
+${OBJECTDIR}/src/ReadDir.o: nbproject/Makefile-${CND_CONF}.mk src/ReadDir.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/ReadDir.o src/ReadDir.cc
+
+${OBJECTDIR}/src/CondWait.o: nbproject/Makefile-${CND_CONF}.mk src/CondWait.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/CondWait.o src/CondWait.cc
+
+${OBJECTDIR}/src/FileNameList.o: nbproject/Makefile-${CND_CONF}.mk src/FileNameList.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/FileNameList.o src/FileNameList.cc
+
+${OBJECTDIR}/src/Mutex.o: nbproject/Makefile-${CND_CONF}.mk src/Mutex.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/Mutex.o src/Mutex.cc
+
+${OBJECTDIR}/src/CharsetConv.o: nbproject/Makefile-${CND_CONF}.mk src/CharsetConv.cc
+ ${MKDIR} -p ${OBJECTDIR}/src
+ ${RM} $@.d
+ $(COMPILE.cc) -O2 -MMD -MP -MF $@.d -o ${OBJECTDIR}/src/CharsetConv.o src/CharsetConv.cc
+
+# Subprojects
+.build-subprojects:
+
+# Clean Targets
+.clean-conf: ${CLEAN_SUBPROJECTS}
+ ${RM} -r ${CND_BUILDDIR}/${CND_CONF}
+ ${RM} ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+
+# Subprojects
+.clean-subprojects:
+
+# Enable dependency checking
+.dep.inc: .depcheck-impl
+
+include .dep.inc
diff --git a/libs/vdr/nbproject/Makefile-impl.mk b/libs/vdr/nbproject/Makefile-impl.mk
new file mode 100644
index 0000000..4112c2c
--- /dev/null
+++ b/libs/vdr/nbproject/Makefile-impl.mk
@@ -0,0 +1,133 @@
+#
+# Generated Makefile - do not edit!
+#
+# Edit the Makefile in the project folder instead (../Makefile). Each target
+# has a pre- and a post- target defined where you can add customization code.
+#
+# This makefile implements macros and targets common to all configurations.
+#
+# NOCDDL
+
+
+# Building and Cleaning subprojects are done by default, but can be controlled with the SUB
+# macro. If SUB=no, subprojects will not be built or cleaned. The following macro
+# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf
+# and .clean-reqprojects-conf unless SUB has the value 'no'
+SUB_no=NO
+SUBPROJECTS=${SUB_${SUB}}
+BUILD_SUBPROJECTS_=.build-subprojects
+BUILD_SUBPROJECTS_NO=
+BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}}
+CLEAN_SUBPROJECTS_=.clean-subprojects
+CLEAN_SUBPROJECTS_NO=
+CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}}
+
+
+# Project Name
+PROJECTNAME=vdr
+
+# Active Configuration
+DEFAULTCONF=Debug
+CONF=${DEFAULTCONF}
+
+# All Configurations
+ALLCONFS=Debug Release
+
+
+# build
+.build-impl: .build-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf
+
+
+# clean
+.clean-impl: .clean-pre .validate-impl .depcheck-impl
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf
+
+
+# clobber
+.clobber-impl: .clobber-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \
+ done
+
+# all
+.all-impl: .all-pre .depcheck-impl
+ @#echo "=> Running $@..."
+ for CONF in ${ALLCONFS}; \
+ do \
+ "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \
+ done
+
+# build tests
+.build-tests-impl: .build-impl .build-tests-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf
+
+# run tests
+.test-impl: .build-tests-impl .test-pre
+ @#echo "=> Running $@... Configuration=$(CONF)"
+ "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf
+
+# dependency checking support
+.depcheck-impl:
+ @echo "# This code depends on make tool being used" >.dep.inc
+ @if [ -n "${MAKE_VERSION}" ]; then \
+ echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \
+ echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \
+ echo "include \$${DEPFILES}" >>.dep.inc; \
+ echo "endif" >>.dep.inc; \
+ else \
+ echo ".KEEP_STATE:" >>.dep.inc; \
+ echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \
+ fi
+
+# configuration validation
+.validate-impl:
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ echo ""; \
+ echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \
+ echo "See 'make help' for details."; \
+ echo "Current directory: " `pwd`; \
+ echo ""; \
+ fi
+ @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \
+ then \
+ exit 1; \
+ fi
+
+
+# help
+.help-impl: .help-pre
+ @echo "This makefile supports the following configurations:"
+ @echo " ${ALLCONFS}"
+ @echo ""
+ @echo "and the following targets:"
+ @echo " build (default target)"
+ @echo " clean"
+ @echo " clobber"
+ @echo " all"
+ @echo " help"
+ @echo ""
+ @echo "Makefile Usage:"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] build"
+ @echo " make [CONF=<CONFIGURATION>] [SUB=no] clean"
+ @echo " make [SUB=no] clobber"
+ @echo " make [SUB=no] all"
+ @echo " make help"
+ @echo ""
+ @echo "Target 'build' will build a specific configuration and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no',"
+ @echo " also clean subprojects."
+ @echo "Target 'clobber' will remove all built files from all configurations and,"
+ @echo " unless 'SUB=no', also from subprojects."
+ @echo "Target 'all' will will build all configurations and, unless 'SUB=no',"
+ @echo " also build subprojects."
+ @echo "Target 'help' prints this message."
+ @echo ""
+
diff --git a/libs/vdr/nbproject/Makefile-variables.mk b/libs/vdr/nbproject/Makefile-variables.mk
new file mode 100644
index 0000000..7b6323c
--- /dev/null
+++ b/libs/vdr/nbproject/Makefile-variables.mk
@@ -0,0 +1,35 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+CND_BASEDIR=`pwd`
+CND_BUILDDIR=build
+CND_DISTDIR=dist
+# Debug configuration
+CND_PLATFORM_Debug=GNU-Linux-x86
+CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux-x86
+CND_ARTIFACT_NAME_Debug=libvdr.a
+CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux-x86/libvdr.a
+CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Debug=vdr.tar
+CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux-x86/package/vdr.tar
+# Release configuration
+CND_PLATFORM_Release=GNU-Linux-x86
+CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux-x86
+CND_ARTIFACT_NAME_Release=libvdr.a
+CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux-x86/libvdr.a
+CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux-x86/package
+CND_PACKAGE_NAME_Release=vdr.tar
+CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux-x86/package/vdr.tar
+#
+# include compiler specific variables
+#
+# dmake command
+ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \
+ (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)
+#
+# gmake command
+.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk))
+#
+include nbproject/private/Makefile-variables.mk
diff --git a/libs/vdr/nbproject/Package-Debug.bash b/libs/vdr/nbproject/Package-Debug.bash
new file mode 100644
index 0000000..f1d82e6
--- /dev/null
+++ b/libs/vdr/nbproject/Package-Debug.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Debug
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+OUTPUT_BASENAME=libvdr.a
+PACKAGE_TOP_DIR=vdr/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/vdr/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/vdr.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/vdr.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/vdr/nbproject/Package-Release.bash b/libs/vdr/nbproject/Package-Release.bash
new file mode 100644
index 0000000..146443a
--- /dev/null
+++ b/libs/vdr/nbproject/Package-Release.bash
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+
+#
+# Generated - do not edit!
+#
+
+# Macros
+TOP=`pwd`
+CND_PLATFORM=GNU-Linux-x86
+CND_CONF=Release
+CND_DISTDIR=dist
+CND_BUILDDIR=build
+NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging
+TMPDIRNAME=tmp-packaging
+OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libvdr.a
+OUTPUT_BASENAME=libvdr.a
+PACKAGE_TOP_DIR=vdr/
+
+# Functions
+function checkReturnCode
+{
+ rc=$?
+ if [ $rc != 0 ]
+ then
+ exit $rc
+ fi
+}
+function makeDirectory
+# $1 directory path
+# $2 permission (optional)
+{
+ mkdir -p "$1"
+ checkReturnCode
+ if [ "$2" != "" ]
+ then
+ chmod $2 "$1"
+ checkReturnCode
+ fi
+}
+function copyFileToTmpDir
+# $1 from-file path
+# $2 to-file path
+# $3 permission
+{
+ cp "$1" "$2"
+ checkReturnCode
+ if [ "$3" != "" ]
+ then
+ chmod $3 "$2"
+ checkReturnCode
+ fi
+}
+
+# Setup
+cd "${TOP}"
+mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package
+rm -rf ${NBTMPDIR}
+mkdir -p ${NBTMPDIR}
+
+# Copy files and create directories and links
+cd "${TOP}"
+makeDirectory "${NBTMPDIR}/vdr/lib"
+copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644
+
+
+# Generate tar file
+cd "${TOP}"
+rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/vdr.tar
+cd ${NBTMPDIR}
+tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/vdr.tar *
+checkReturnCode
+
+# Cleanup
+cd "${TOP}"
+rm -rf ${NBTMPDIR}
diff --git a/libs/vdr/nbproject/configurations.xml b/libs/vdr/nbproject/configurations.xml
new file mode 100644
index 0000000..90cd3e0
--- /dev/null
+++ b/libs/vdr/nbproject/configurations.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>include/CharsetConv.h</itemPath>
+ <itemPath>include/CondWait.h</itemPath>
+ <itemPath>include/FileNameList.h</itemPath>
+ <itemPath>include/Logging.h</itemPath>
+ <itemPath>include/Mutex.h</itemPath>
+ <itemPath>include/ReadDir.h</itemPath>
+ <itemPath>include/String.h</itemPath>
+ <itemPath>include/StringList.h</itemPath>
+ <itemPath>include/Thread.h</itemPath>
+ <itemPath>include/TimeMs.h</itemPath>
+ <itemPath>include/Vector.h</itemPath>
+ <itemPath>include/i18n.h</itemPath>
+ <itemPath>include/tools.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/CharsetConv.cc</itemPath>
+ <itemPath>src/CondWait.cc</itemPath>
+ <itemPath>src/FileNameList.cc</itemPath>
+ <itemPath>src/Logging.cc</itemPath>
+ <itemPath>src/Mutex.cc</itemPath>
+ <itemPath>src/ReadDir.cc</itemPath>
+ <itemPath>src/String.cc</itemPath>
+ <itemPath>src/StringList.cc</itemPath>
+ <itemPath>src/Thread.cc</itemPath>
+ <itemPath>src/TimeMs.cc</itemPath>
+ <itemPath>src/i18n.cc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="TestFiles"
+ displayName="Test Files"
+ projectFiles="false"
+ kind="TEST_LOGICAL_FOLDER">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false"
+ kind="IMPORTANT_FILES_FOLDER">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <ccTool>
+ <incDir>
+ <pElem>include</pElem>
+ <pElem>/usr/include/freetype2</pElem>
+ <pElem>/usr/include/fribidi</pElem>
+ </incDir>
+ <commandLine>-std=gnu++0x -fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi</commandLine>
+ <preprocessorList>
+ <Elem>LOCDIR=/usr/share/locale</Elem>
+ <Elem>_GNU_SOURCE=1</Elem>
+ <Elem>_REENTRANT</Elem>
+ </preprocessorList>
+ <warningLevel>2</warningLevel>
+ </ccTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>default</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ </ccTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <asmTool>
+ <developmentMode>5</developmentMode>
+ </asmTool>
+ <archiverTool>
+ </archiverTool>
+ </compileType>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/vdr/nbproject/private/Makefile-variables.mk b/libs/vdr/nbproject/private/Makefile-variables.mk
new file mode 100644
index 0000000..a64183e
--- /dev/null
+++ b/libs/vdr/nbproject/private/Makefile-variables.mk
@@ -0,0 +1,7 @@
+#
+# Generated - do not edit!
+#
+# NOCDDL
+#
+# Debug configuration
+# Release configuration
diff --git a/libs/vdr/nbproject/private/configurations.xml b/libs/vdr/nbproject/private/configurations.xml
new file mode 100644
index 0000000..fa15dc7
--- /dev/null
+++ b/libs/vdr/nbproject/private/configurations.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configurationDescriptor version="80">
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ <conf name="Release" type="3">
+ <toolsSet>
+ <developmentServer>localhost</developmentServer>
+ <platform>2</platform>
+ </toolsSet>
+ <dbx_gdbdebugger version="1">
+ <gdb_pathmaps>
+ </gdb_pathmaps>
+ <gdb_interceptlist>
+ <gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
+ </gdb_interceptlist>
+ <gdb_options>
+ <DebugOptions>
+ </DebugOptions>
+ </gdb_options>
+ <gdb_buildfirst gdb_buildfirst_overriden="false" gdb_buildfirst_old="false"/>
+ </dbx_gdbdebugger>
+ <nativedebugger version="1">
+ <engine>gdb</engine>
+ </nativedebugger>
+ <runprofile version="9">
+ <runcommandpicklist>
+ <runcommandpicklistitem>"${OUTPUT_PATH}"</runcommandpicklistitem>
+ </runcommandpicklist>
+ <runcommand>"${OUTPUT_PATH}"</runcommand>
+ <rundir></rundir>
+ <buildfirst>true</buildfirst>
+ <terminal-type>0</terminal-type>
+ <remove-instrumentation>0</remove-instrumentation>
+ <environment>
+ </environment>
+ </runprofile>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/libs/vdr/nbproject/private/private.xml b/libs/vdr/nbproject/private/private.xml
new file mode 100644
index 0000000..5ee2703
--- /dev/null
+++ b/libs/vdr/nbproject/private/private.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
+ <data xmlns="http://www.netbeans.org/ns/make-project-private/1">
+ <activeConfTypeElem>3</activeConfTypeElem>
+ <activeConfIndexElem>0</activeConfIndexElem>
+ </data>
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+</project-private>
diff --git a/libs/vdr/nbproject/project.xml b/libs/vdr/nbproject/project.xml
new file mode 100644
index 0000000..c87a53a
--- /dev/null
+++ b/libs/vdr/nbproject/project.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>vdr</name>
+ <c-extensions/>
+ <cpp-extensions>cc</cpp-extensions>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>Debug</name>
+ <type>3</type>
+ </confElem>
+ <confElem>
+ <name>Release</name>
+ <type>3</type>
+ </confElem>
+ </confList>
+ </data>
+ </configuration>
+</project>
diff --git a/libs/vdr/src/CharsetConv.cc b/libs/vdr/src/CharsetConv.cc
new file mode 100644
index 0000000..ed50dee
--- /dev/null
+++ b/libs/vdr/src/CharsetConv.cc
@@ -0,0 +1,294 @@
+/**
+ * File: CharsetConv.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <CharsetConv.h>
+#include <Logging.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <tools.h>
+
+static uint SystemToUtf8[128] = { 0 };
+
+int Utf8CharLen(const char *s)
+{
+ if (cCharSetConv::SystemCharacterTable())
+ return 1;
+#define MT(s, m, v) ((*(s) & (m)) == (v)) // Mask Test
+ if (MT(s, 0xE0, 0xC0) && MT(s + 1, 0xC0, 0x80))
+ return 2;
+ if (MT(s, 0xF0, 0xE0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80))
+ return 3;
+ if (MT(s, 0xF8, 0xF0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80) && MT(s + 3, 0xC0, 0x80))
+ return 4;
+ return 1;
+}
+
+uint Utf8CharGet(const char *s, int Length)
+{
+ if (cCharSetConv::SystemCharacterTable())
+ return (uchar)*s < 128 ? *s : SystemToUtf8[(uchar)*s - 128];
+ if (!Length)
+ Length = Utf8CharLen(s);
+ switch (Length) {
+ case 2: return ((*s & 0x1F) << 6) | (*(s + 1) & 0x3F);
+ case 3: return ((*s & 0x0F) << 12) | ((*(s + 1) & 0x3F) << 6) | (*(s + 2) & 0x3F);
+ case 4: return ((*s & 0x07) << 18) | ((*(s + 1) & 0x3F) << 12) | ((*(s + 2) & 0x3F) << 6) | (*(s + 3) & 0x3F);
+ default: break;
+ }
+ return *s;
+}
+
+int Utf8CharSet(uint c, char *s)
+{
+ if (c < 0x80 || cCharSetConv::SystemCharacterTable()) {
+ if (s)
+ *s = c;
+ return 1;
+ }
+ if (c < 0x800) {
+ if (s) {
+ *s++ = ((c >> 6) & 0x1F) | 0xC0;
+ *s = (c & 0x3F) | 0x80;
+ }
+ return 2;
+ }
+ if (c < 0x10000) {
+ if (s) {
+ *s++ = ((c >> 12) & 0x0F) | 0xE0;
+ *s++ = ((c >> 6) & 0x3F) | 0x80;
+ *s = (c & 0x3F) | 0x80;
+ }
+ return 3;
+ }
+ if (c < 0x110000) {
+ if (s) {
+ *s++ = ((c >> 18) & 0x07) | 0xF0;
+ *s++ = ((c >> 12) & 0x3F) | 0x80;
+ *s++ = ((c >> 6) & 0x3F) | 0x80;
+ *s = (c & 0x3F) | 0x80;
+ }
+ return 4;
+ }
+ return 0; // can't convert to UTF-8
+}
+
+int Utf8SymChars(const char *s, int Symbols)
+{
+ if (cCharSetConv::SystemCharacterTable())
+ return Symbols;
+ int n = 0;
+ while (*s && Symbols--) {
+ int sl = Utf8CharLen(s);
+ s += sl;
+ n += sl;
+ }
+ return n;
+}
+
+int Utf8StrLen(const char *s)
+{
+ if (cCharSetConv::SystemCharacterTable())
+ return strlen(s);
+ int n = 0;
+ while (*s) {
+ s += Utf8CharLen(s);
+ n++;
+ }
+ return n;
+}
+
+extern char *strn0cpy(char *dest, const char *src, size_t n);
+
+char *Utf8Strn0Cpy(char *Dest, const char *Src, int n)
+{
+ if (cCharSetConv::SystemCharacterTable())
+ return strn0cpy(Dest, Src, n);
+ char *d = Dest;
+ while (*Src) {
+ int sl = Utf8CharLen(Src);
+ n -= sl;
+ if (n > 0) {
+ while (sl--)
+ *d++ = *Src++;
+ }
+ else
+ break;
+ }
+ *d = 0;
+ return Dest;
+}
+
+int Utf8ToArray(const char *s, uint *a, int Size)
+{
+ int n = 0;
+ while (*s && --Size > 0) {
+ if (cCharSetConv::SystemCharacterTable())
+ *a++ = (uchar)(*s++);
+ else {
+ int sl = Utf8CharLen(s);
+ *a++ = Utf8CharGet(s, sl);
+ s += sl;
+ }
+ n++;
+ }
+ if (Size > 0)
+ *a = 0;
+ return n;
+}
+
+int Utf8FromArray(const uint *a, char *s, int Size, int Max)
+{
+ int NumChars = 0;
+ int NumSyms = 0;
+ while (*a && NumChars < Size) {
+ if (Max >= 0 && NumSyms++ >= Max)
+ break;
+ if (cCharSetConv::SystemCharacterTable()) {
+ *s++ = *a++;
+ NumChars++;
+ }
+ else {
+ int sl = Utf8CharSet(*a);
+ if (NumChars + sl <= Size) {
+ Utf8CharSet(*a, s);
+ a++;
+ s += sl;
+ NumChars += sl;
+ }
+ else
+ break;
+ }
+ }
+ if (NumChars < Size)
+ *s = 0;
+ return NumChars;
+}
+
+// --- cCharSetConv ----------------------------------------------------------
+
+char *cCharSetConv::systemCharacterTable = NULL;
+
+cCharSetConv::cCharSetConv(const char *FromCode, const char *ToCode)
+{
+ if (!FromCode)
+ FromCode = systemCharacterTable ? systemCharacterTable : "UTF-8";
+ if (!ToCode)
+ ToCode = "UTF-8";
+ cd = iconv_open(ToCode, FromCode);
+ result = NULL;
+ length = 0;
+}
+
+cCharSetConv::~cCharSetConv()
+{
+ free(result);
+ iconv_close(cd);
+}
+
+void cCharSetConv::SetSystemCharacterTable(const char *CharacterTable)
+{
+ free(systemCharacterTable);
+ systemCharacterTable = NULL;
+ if (!strcasestr(CharacterTable, "UTF-8")) {
+ // Set up a map for the character values 128...255:
+ char buf[129];
+ for (int i = 0; i < 128; i++)
+ buf[i] = i + 128;
+ buf[128] = 0;
+ cCharSetConv csc(CharacterTable);
+ const char *s = csc.Convert(buf);
+ int i = 0;
+ while (*s) {
+ int sl = Utf8CharLen(s);
+ SystemToUtf8[i] = Utf8CharGet(s, sl);
+ s += sl;
+ i++;
+ }
+ systemCharacterTable = strdup(CharacterTable);
+ }
+}
+
+const char *cCharSetConv::Convert(const char *From, char *To, size_t ToLength)
+{
+ if (cd != (iconv_t)-1 && From && *From) {
+ char *FromPtr = (char *)From;
+ size_t FromLength = strlen(From);
+ char *ToPtr = To;
+ if (!ToPtr) {
+ int NewLength = max(length, FromLength * 2); // some reserve to avoid later reallocations
+ if (char *NewBuffer = (char *)realloc(result, NewLength)) {
+ length = NewLength;
+ result = NewBuffer;
+ }
+ else {
+ esyslog("ERROR: out of memory");
+ return From;
+ }
+ ToPtr = result;
+ ToLength = length;
+ }
+ else if (!ToLength)
+ return From; // can't convert into a zero sized buffer
+ ToLength--; // save space for terminating 0
+ char *Converted = ToPtr;
+ while (FromLength > 0) {
+ if (iconv(cd, &FromPtr, &FromLength, &ToPtr, &ToLength) == size_t(-1)) {
+ if (errno == E2BIG || ((errno == EILSEQ) && (ToLength < 1))) {
+ if (To) break; // caller provided a fixed size buffer, but it was too small
+ // The result buffer is too small, so increase it:
+ size_t d = ToPtr - result;
+ size_t r = length / 2;
+ int NewLength = length + r;
+ if (char *NewBuffer = (char *)realloc(result, NewLength)) {
+ length = NewLength;
+ Converted = result = NewBuffer;
+ }
+ else {
+ esyslog("ERROR: out of memory");
+ return From;
+ }
+ ToLength += r;
+ ToPtr = result + d;
+ }
+ if (errno == EILSEQ) {
+ // A character can't be converted, so mark it with '?' and proceed:
+ FromPtr++;
+ FromLength--;
+ *ToPtr++ = '?';
+ ToLength--;
+ }
+ else if (errno != E2BIG)
+ return From; // unknown error, return original string
+ }
+ }
+ *ToPtr = 0;
+ return Converted;
+ }
+ return From;
+}
diff --git a/libs/vdr/src/CondWait.cc b/libs/vdr/src/CondWait.cc
new file mode 100644
index 0000000..efa4803
--- /dev/null
+++ b/libs/vdr/src/CondWait.cc
@@ -0,0 +1,101 @@
+/**
+ * File: CondWait.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <CondWait.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <errno.h>
+#include <tools.h>
+
+static bool GetAbsTime(struct timespec *Abstime, int MillisecondsFromNow)
+{
+ struct timeval now;
+ if (gettimeofday(&now, NULL) == 0) { // get current time
+ now.tv_sec += MillisecondsFromNow / 1000; // add full seconds
+ now.tv_usec += (MillisecondsFromNow % 1000) * 1000; // add microseconds
+ if (now.tv_usec >= 1000000) { // take care of an overflow
+ now.tv_sec++;
+ now.tv_usec -= 1000000;
+ }
+ Abstime->tv_sec = now.tv_sec; // seconds
+ Abstime->tv_nsec = now.tv_usec * 1000; // nano seconds
+ return true;
+ }
+ return false;
+}
+
+cCondWait::cCondWait(void)
+{
+ signaled = false;
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond, NULL);
+}
+
+cCondWait::~cCondWait()
+{
+ pthread_cond_broadcast(&cond); // wake up any sleepers
+ pthread_cond_destroy(&cond);
+ pthread_mutex_destroy(&mutex);
+}
+
+void cCondWait::SleepMs(int TimeoutMs)
+{
+ cCondWait w;
+ w.Wait(max(TimeoutMs, 3)); // making sure the time is >2ms to avoid a possible busy wait
+}
+
+bool cCondWait::Wait(int TimeoutMs)
+{
+ pthread_mutex_lock(&mutex);
+ if (!signaled) {
+ if (TimeoutMs) {
+ struct timespec abstime;
+ if (GetAbsTime(&abstime, TimeoutMs)) {
+ while (!signaled) {
+ if (pthread_cond_timedwait(&cond, &mutex, &abstime) == ETIMEDOUT)
+ break;
+ }
+ }
+ }
+ else
+ pthread_cond_wait(&cond, &mutex);
+ }
+ bool r = signaled;
+ signaled = false;
+ pthread_mutex_unlock(&mutex);
+ return r;
+}
+
+void cCondWait::Signal(void)
+{
+ pthread_mutex_lock(&mutex);
+ signaled = true;
+ pthread_cond_broadcast(&cond);
+ pthread_mutex_unlock(&mutex);
+}
diff --git a/libs/vdr/src/FileNameList.cc b/libs/vdr/src/FileNameList.cc
new file mode 100644
index 0000000..74dc4f2
--- /dev/null
+++ b/libs/vdr/src/FileNameList.cc
@@ -0,0 +1,70 @@
+/**
+ * File: FileNameList.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <FileNameList.h>
+#include <ReadDir.h>
+#include <String.h>
+#include <sys/stat.h>
+
+
+cString AddDirectory(const char *DirName, const char *FileName)
+{
+ return cString::sprintf("%s/%s", DirName && *DirName ? DirName : ".", FileName);
+}
+
+// TODO better GetFileNames(const char *Directory, cStringList *List)?
+cFileNameList::cFileNameList(const char *Directory, bool DirsOnly)
+{
+ Load(Directory, DirsOnly);
+}
+
+bool cFileNameList::Load(const char *Directory, bool DirsOnly)
+{
+ Clear();
+ if (Directory) {
+ cReadDir d(Directory);
+ struct dirent *e;
+ if (d.Ok()) {
+ while ((e = d.Next()) != NULL) {
+ if (DirsOnly) {
+ struct stat ds;
+ if (stat(AddDirectory(Directory, e->d_name), &ds) == 0) {
+ if (!S_ISDIR(ds.st_mode))
+ continue;
+ }
+ }
+ Append(strdup(e->d_name));
+ }
+ Sort();
+ return true;
+ }
+ else
+ LOG_ERROR_STR(Directory);
+ }
+ return false;
+}
diff --git a/libs/vdr/src/Logging.cc b/libs/vdr/src/Logging.cc
new file mode 100644
index 0000000..4db516b
--- /dev/null
+++ b/libs/vdr/src/Logging.cc
@@ -0,0 +1,46 @@
+/**
+ * File: Logging.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <Logging.h>
+#include <Thread.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+int SysLogLevel = 3;
+
+#define MAXSYSLOGBUF 256
+
+void syslog_with_tid(int priority, const char *format, ...)
+{
+ va_list ap;
+ char fmt[MAXSYSLOGBUF];
+ snprintf(fmt, sizeof(fmt), "[%d] %s", cThread::ThreadId(), format);
+ va_start(ap, format);
+ vsyslog(priority, fmt, ap);
+ va_end(ap);
+}
diff --git a/libs/vdr/src/Mutex.cc b/libs/vdr/src/Mutex.cc
new file mode 100644
index 0000000..cb100c7
--- /dev/null
+++ b/libs/vdr/src/Mutex.cc
@@ -0,0 +1,81 @@
+/**
+ * File: Mutex.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <Mutex.h>
+
+cMutex::cMutex(void)
+{
+ locked = 0;
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
+ pthread_mutex_init(&mutex, &attr);
+}
+
+cMutex::~cMutex()
+{
+ pthread_mutex_destroy(&mutex);
+}
+
+void cMutex::Lock(void)
+{
+ pthread_mutex_lock(&mutex);
+ locked++;
+}
+
+void cMutex::Unlock(void)
+{
+ if (!--locked)
+ pthread_mutex_unlock(&mutex);
+}
+
+// --- cMutexLock ------------------------------------------------------------
+
+cMutexLock::cMutexLock(cMutex *Mutex)
+{
+ mutex = NULL;
+ locked = false;
+ Lock(Mutex);
+}
+
+cMutexLock::~cMutexLock()
+{
+ if (mutex && locked)
+ mutex->Unlock();
+}
+
+bool cMutexLock::Lock(cMutex *Mutex)
+{
+ if (Mutex && !mutex) {
+ mutex = Mutex;
+ Mutex->Lock();
+ locked = true;
+ return true;
+ }
+ return false;
+}
diff --git a/libs/vdr/src/ReadDir.cc b/libs/vdr/src/ReadDir.cc
new file mode 100644
index 0000000..a837f35
--- /dev/null
+++ b/libs/vdr/src/ReadDir.cc
@@ -0,0 +1,53 @@
+/**
+ * File: ReadDir.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <ReadDir.h>
+#include <stddef.h>
+#include <string.h>
+
+cReadDir::cReadDir(const char *Directory)
+{
+ directory = opendir(Directory);
+}
+
+cReadDir::~cReadDir()
+{
+ if (directory)
+ closedir(directory);
+}
+
+struct dirent *cReadDir::Next(void)
+{
+ if (directory) {
+ while (readdir_r(directory, &u.d, &result) == 0 && result) {
+ if (strcmp(result->d_name, ".") && strcmp(result->d_name, ".."))
+ return result;
+ }
+ }
+ return NULL;
+}
diff --git a/libs/vdr/src/String.cc b/libs/vdr/src/String.cc
new file mode 100644
index 0000000..0729c77
--- /dev/null
+++ b/libs/vdr/src/String.cc
@@ -0,0 +1,379 @@
+/**
+ * File: String.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <String.h>
+#include <Logging.h>
+#include <i18n.h>
+#include <tools.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <ctype.h>
+
+char *strcpyrealloc(char *dest, const char *src)
+{
+ if (src) {
+ int l = max(dest ? strlen(dest) : 0, strlen(src)) + 1; // don't let the block get smaller!
+ dest = (char *)realloc(dest, l);
+ if (dest)
+ strcpy(dest, src);
+ else
+ esyslog("ERROR: out of memory");
+ }
+ else {
+ free(dest);
+ dest = NULL;
+ }
+ return dest;
+}
+
+char *strn0cpy(char *dest, const char *src, size_t n)
+{
+ char *s = dest;
+ for ( ; --n && (*dest = *src) != 0; dest++, src++) ;
+ *dest = 0;
+ return s;
+}
+
+char *strreplace(char *s, char c1, char c2)
+{
+ if (s) {
+ char *p = s;
+ while (*p) {
+ if (*p == c1)
+ *p = c2;
+ p++;
+ }
+ }
+ return s;
+}
+
+char *strreplace(char *s, const char *s1, const char *s2)
+{
+ char *p = strstr(s, s1);
+ if (p) {
+ int of = p - s;
+ int l = strlen(s);
+ int l1 = strlen(s1);
+ int l2 = strlen(s2);
+ if (l2 > l1) {
+ if (char *NewBuffer = (char *)realloc(s, l + l2 - l1 + 1))
+ s = NewBuffer;
+ else {
+ esyslog("ERROR: out of memory");
+ return s;
+ }
+ }
+ char *sof = s + of;
+ if (l2 != l1)
+ memmove(sof + l2, sof + l1, l - of - l1 + 1);
+ strncpy(sof, s2, l2);
+ }
+ return s;
+}
+
+char *stripspace(char *s)
+{
+ if (s && *s) {
+ for (char *p = s + strlen(s) - 1; p >= s; p--) {
+ if (!isspace(*p))
+ break;
+ *p = 0;
+ }
+ }
+ return s;
+}
+
+char *compactspace(char *s)
+{
+ if (s && *s) {
+ char *t = stripspace(skipspace(s));
+ char *p = t;
+ while (p && *p) {
+ char *q = skipspace(p);
+ if (q - p > 1)
+ memmove(p + 1, q, strlen(q) + 1);
+ p++;
+ }
+ if (t != s)
+ memmove(s, t, strlen(t) + 1);
+ }
+ return s;
+}
+
+cString strescape(const char *s, const char *chars)
+{
+ char *buffer;
+ const char *p = s;
+ char *t = NULL;
+ while (*p) {
+ if (strchr(chars, *p)) {
+ if (!t) {
+ buffer = MALLOC(char, 2 * strlen(s) + 1);
+ t = buffer + (p - s);
+ s = strcpy(buffer, s);
+ }
+ *t++ = '\\';
+ }
+ if (t)
+ *t++ = *p;
+ p++;
+ }
+ if (t)
+ *t = 0;
+ return cString(s, t != NULL);
+}
+
+bool startswith(const char *s, const char *p)
+{
+ while (*p) {
+ if (*p++ != *s++)
+ return false;
+ }
+ return true;
+}
+
+bool endswith(const char *s, const char *p)
+{
+ const char *se = s + strlen(s) - 1;
+ const char *pe = p + strlen(p) - 1;
+ while (pe >= p) {
+ if (*pe-- != *se-- || (se < s && pe >= p))
+ return false;
+ }
+ return true;
+}
+
+bool isempty(const char *s)
+{
+ return !(s && *skipspace(s));
+}
+
+int numdigits(int n)
+{
+ int res = 1;
+ while (n >= 10) {
+ n /= 10;
+ res++;
+ }
+ return res;
+}
+
+bool isnumber(const char *s)
+{
+ if (!s || !*s)
+ return false;
+ do {
+ if (!isdigit(*s))
+ return false;
+ } while (*++s);
+ return true;
+}
+
+int64_t StrToNum(const char *s)
+{
+ char *t = NULL;
+ int64_t n = strtoll(s, &t, 10);
+ if (t) {
+ switch (*t) {
+ case 'T': n *= 1024;
+ case 'G': n *= 1024;
+ case 'M': n *= 1024;
+ case 'K': n *= 1024;
+ }
+ }
+ return n;
+}
+
+cString itoa(int n)
+{
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%d", n);
+ return buf;
+}
+
+// --- cString ---------------------------------------------------------------
+
+cString::cString(const char *S, bool TakePointer)
+{
+ s = TakePointer ? (char *)S : S ? strdup(S) : NULL;
+}
+
+cString::cString(const cString &String)
+{
+ s = String.s ? strdup(String.s) : NULL;
+}
+
+cString::~cString()
+{
+ free(s);
+}
+
+cString &cString::operator=(const cString &String)
+{
+ if (this == &String)
+ return *this;
+ free(s);
+ s = String.s ? strdup(String.s) : NULL;
+ return *this;
+}
+
+cString &cString::operator=(const char *String)
+{
+ if (s == String)
+ return *this;
+ free(s);
+ s = String ? strdup(String) : NULL;
+ return *this;
+}
+
+cString &cString::Truncate(int Index)
+{
+ int l = strlen(s);
+ if (Index < 0)
+ Index = l + Index;
+ if (Index >= 0 && Index < l)
+ s[Index] = 0;
+ return *this;
+}
+
+cString cString::sprintf(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ char *buffer;
+ if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
+ esyslog("error in vasprintf('%s', ...)", fmt);
+ buffer = strdup("???");
+ }
+ va_end(ap);
+ return cString(buffer, true);
+}
+
+cString cString::vsprintf(const char *fmt, va_list &ap)
+{
+ char *buffer;
+ if (!fmt || vasprintf(&buffer, fmt, ap) < 0) {
+ esyslog("error in vasprintf('%s', ...)", fmt);
+ buffer = strdup("???");
+ }
+ return cString(buffer, true);
+}
+
+cString WeekDayName(int WeekDay)
+{
+ char buffer[16];
+ WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with Monday==0!
+ if (0 <= WeekDay && WeekDay <= 6) {
+ // TRANSLATORS: abbreviated weekdays, beginning with monday (must all be 3 letters!)
+ const char *day = tr("MonTueWedThuFriSatSun");
+ day += Utf8SymChars(day, WeekDay * 3);
+ strn0cpy(buffer, day, min(Utf8SymChars(day, 3) + 1, int(sizeof(buffer))));
+ return buffer;
+ }
+ else
+ return "???";
+}
+
+cString WeekDayName(time_t t)
+{
+ struct tm tm_r;
+ return WeekDayName(localtime_r(&t, &tm_r)->tm_wday);
+}
+
+cString WeekDayNameFull(int WeekDay)
+{
+ WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with Monday==0!
+ switch (WeekDay) {
+ case 0: return tr("Monday");
+ case 1: return tr("Tuesday");
+ case 2: return tr("Wednesday");
+ case 3: return tr("Thursday");
+ case 4: return tr("Friday");
+ case 5: return tr("Saturday");
+ case 6: return tr("Sunday");
+ default: return "???";
+ }
+}
+
+cString WeekDayNameFull(time_t t)
+{
+ struct tm tm_r;
+ return WeekDayNameFull(localtime_r(&t, &tm_r)->tm_wday);
+}
+
+cString DayDateTime(time_t t)
+{
+ char buffer[32];
+ if (t == 0)
+ time(&t);
+ struct tm tm_r;
+ tm *tm = localtime_r(&t, &tm_r);
+ snprintf(buffer, sizeof(buffer), "%s %02d.%02d. %02d:%02d", *WeekDayName(tm->tm_wday), tm->tm_mday, tm->tm_mon + 1, tm->tm_hour, tm->tm_min);
+ return buffer;
+}
+
+cString TimeToString(time_t t)
+{
+ char buffer[32];
+ if (ctime_r(&t, buffer)) {
+ buffer[strlen(buffer) - 1] = 0; // strip trailing newline
+ return buffer;
+ }
+ return "???";
+}
+
+cString DateString(time_t t)
+{
+ char buf[32];
+ struct tm tm_r;
+ tm *tm = localtime_r(&t, &tm_r);
+ char *p = stpcpy(buf, WeekDayName(tm->tm_wday));
+ *p++ = ' ';
+ strftime(p, sizeof(buf) - (p - buf), "%d.%m.%Y", tm);
+ return buf;
+}
+
+cString ShortDateString(time_t t)
+{
+ char buf[32];
+ struct tm tm_r;
+ tm *tm = localtime_r(&t, &tm_r);
+ strftime(buf, sizeof(buf), "%d.%m.%y", tm);
+ return buf;
+}
+
+cString TimeString(time_t t)
+{
+ char buf[25];
+ struct tm tm_r;
+ strftime(buf, sizeof(buf), "%R", localtime_r(&t, &tm_r));
+ return buf;
+}
diff --git a/libs/vdr/src/StringList.cc b/libs/vdr/src/StringList.cc
new file mode 100644
index 0000000..5b3adf5
--- /dev/null
+++ b/libs/vdr/src/StringList.cc
@@ -0,0 +1,50 @@
+/**
+ * File: StringList.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <StringList.h>
+
+cStringList::~cStringList()
+{
+ Clear();
+}
+
+int cStringList::Find(const char *s) const
+{
+ for (int i = 0; i < Size(); i++) {
+ if (!strcmp(s, At(i)))
+ return i;
+ }
+ return -1;
+}
+
+void cStringList::Clear(void)
+{
+ for (int i = 0; i < Size(); i++)
+ free(At(i));
+ cVector<char *>::Clear();
+}
diff --git a/libs/vdr/src/Thread.cc b/libs/vdr/src/Thread.cc
new file mode 100644
index 0000000..25d23e3
--- /dev/null
+++ b/libs/vdr/src/Thread.cc
@@ -0,0 +1,209 @@
+/**
+ * File: Thread.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <Thread.h>
+#include <TimeMs.h>
+#include <CondWait.h>
+#include <Logging.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/resource.h>
+tThreadId cThread::mainThreadId = 0;
+
+cThread::cThread(const char *Description)
+ : active(false)
+ , running(false)
+ , childTid(0)
+ , childThreadId(0)
+ , description(NULL)
+ , threadCallback(NULL)
+ , opaque(NULL)
+{
+ if (Description) SetDescription("%s", Description);
+}
+
+cThread::cThread(int (*ThreadCallback)(void *, cThread *), void *Opaque, const char *Description)
+ : active(false)
+ , running(false)
+ , childTid(0)
+ , childThreadId(0)
+ , description(NULL)
+ , threadCallback(ThreadCallback)
+ , opaque(Opaque)
+{
+ if (Description) SetDescription("%s", Description);
+}
+
+cThread::~cThread()
+{
+ Cancel(); // just in case the derived class didn't call it
+ free(description);
+}
+
+void cThread::SetPriority(int Priority)
+{
+ if (setpriority(PRIO_PROCESS, 0, Priority) < 0)
+ LOG_ERROR;
+}
+
+void cThread::SetIOPriority(int Priority)
+{
+ if (syscall(SYS_ioprio_set, 1, 0, (Priority & 0xff) | (2 << 13)) < 0) // best effort class
+ LOG_ERROR;
+}
+
+void cThread::SetDescription(const char *Description, ...)
+{
+ free(description);
+ description = NULL;
+ if (Description) {
+ va_list ap;
+ va_start(ap, Description);
+ vasprintf(&description, Description, ap);
+ va_end(ap);
+ }
+}
+
+void *cThread::StartThread(cThread *Thread)
+{
+ Thread->childThreadId = ThreadId();
+ if (Thread->description) {
+ dsyslog("%s thread started (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+#ifdef PR_SET_NAME
+ if (prctl(PR_SET_NAME, Thread->description, 0, 0, 0) < 0)
+ esyslog("%s thread naming failed (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+#endif
+ }
+ Thread->Action();
+ if (Thread->description)
+ dsyslog("%s thread ended (pid=%d, tid=%d)", Thread->description, getpid(), Thread->childThreadId);
+ Thread->running = false;
+ Thread->active = false;
+
+ return NULL;
+}
+
+#define THREAD_STOP_TIMEOUT 3000 // ms to wait for a thread to stop before newly starting it
+#define THREAD_STOP_SLEEP 30 // ms to sleep while waiting for a thread to stop
+
+bool cThread::Start(void)
+{
+ if (!running) {
+ if (active) {
+ // Wait until the previous incarnation of this thread has completely ended
+ // before starting it newly:
+ cTimeMs RestartTimeout;
+ while (!running && active && RestartTimeout.Elapsed() < THREAD_STOP_TIMEOUT)
+ cCondWait::SleepMs(THREAD_STOP_SLEEP);
+ }
+ if (!active) {
+ active = running = true;
+ if (pthread_create(&childTid, NULL, (void *(*) (void *))&StartThread, (void *)this) == 0) {
+ pthread_detach(childTid); // auto-reap
+ }
+ else {
+ LOG_ERROR;
+ active = running = false;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void cThread::Action()
+{
+ if (!threadCallback) *((char *)0) = 0;
+ ///< if not used the callback constructor, cThread must be subclassed, so stop application here!
+
+ threadCallback(opaque, this); // passing this as parameter allows the callback
+ // use the public interface of this instance.
+}
+
+bool cThread::Active(void)
+{
+ if (active) {
+ //
+ // Single UNIX Spec v2 says:
+ //
+ // The pthread_kill() function is used to request
+ // that a signal be delivered to the specified thread.
+ //
+ // As in kill(), if sig is zero, error checking is
+ // performed but no signal is actually sent.
+ //
+ int err;
+ if ((err = pthread_kill(childTid, 0)) != 0) {
+ if (err != ESRCH)
+ LOG_ERROR;
+ childTid = 0;
+ active = running = false;
+ }
+ else
+ return true;
+ }
+ return false;
+}
+
+void cThread::Cancel(int WaitSeconds)
+{
+ running = false;
+ if (active && WaitSeconds > -1) {
+ if (WaitSeconds > 0) {
+ for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
+ if (!Active())
+ return;
+ cCondWait::SleepMs(10);
+ }
+ esyslog("ERROR: %s thread %d won't end (waited %d seconds) - canceling it...", description ? description : "", childThreadId, WaitSeconds);
+ }
+ pthread_cancel(childTid);
+ childTid = 0;
+ active = false;
+ }
+}
+
+tThreadId cThread::ThreadId(void)
+{
+ return syscall(__NR_gettid);
+}
+
+void cThread::SetMainThreadId(void)
+{
+ if (mainThreadId == 0)
+ mainThreadId = ThreadId();
+ else
+ esyslog("ERROR: attempt to set main thread id to %d while it already is %d", ThreadId(), mainThreadId);
+}
diff --git a/libs/vdr/src/TimeMs.cc b/libs/vdr/src/TimeMs.cc
new file mode 100644
index 0000000..620481e
--- /dev/null
+++ b/libs/vdr/src/TimeMs.cc
@@ -0,0 +1,101 @@
+/**
+ * File: TimeMs.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ */
+#include <TimeMs.h>
+#include <Logging.h>
+#include <stddef.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+
+cTimeMs::cTimeMs(int Ms)
+{
+ if (Ms >= 0)
+ Set(Ms);
+ else
+ begin = 0;
+}
+
+uint64_t cTimeMs::Now(void)
+{
+#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
+#define MIN_RESOLUTION 5 // ms
+ static bool initialized = false;
+ static bool monotonic = false;
+ struct timespec tp;
+ if (!initialized) {
+ // check if monotonic timer is available and provides enough accurate resolution:
+ if (clock_getres(CLOCK_MONOTONIC, &tp) == 0) {
+ long Resolution = tp.tv_nsec;
+ // require a minimum resolution:
+ if (tp.tv_sec == 0 && tp.tv_nsec <= MIN_RESOLUTION * 1000000) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+ dsyslog("cTimeMs: using monotonic clock (resolution is %ld ns)", Resolution);
+ monotonic = true;
+ }
+ else
+ esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ }
+ else
+ dsyslog("cTimeMs: not using monotonic clock - resolution is too bad (%ld s %ld ns)", tp.tv_sec, tp.tv_nsec);
+ }
+ else
+ esyslog("cTimeMs: clock_getres(CLOCK_MONOTONIC) failed");
+ initialized = true;
+ }
+ if (monotonic) {
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+ return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000;
+ esyslog("cTimeMs: clock_gettime(CLOCK_MONOTONIC) failed");
+ monotonic = false;
+ // fall back to gettimeofday()
+ }
+#else
+# warning Posix monotonic clock not available
+#endif
+ struct timeval t;
+ if (gettimeofday(&t, NULL) == 0)
+ return (uint64_t(t.tv_sec)) * 1000 + t.tv_usec / 1000;
+ return 0;
+}
+
+void cTimeMs::Set(int Ms)
+{
+ begin = Now() + Ms;
+}
+
+bool cTimeMs::TimedOut(void)
+{
+ return Now() >= begin;
+}
+
+uint64_t cTimeMs::Elapsed(void)
+{
+ return Now() - begin;
+}
diff --git a/libs/vdr/src/i18n.cc b/libs/vdr/src/i18n.cc
new file mode 100644
index 0000000..a6d8d65
--- /dev/null
+++ b/libs/vdr/src/i18n.cc
@@ -0,0 +1,324 @@
+/**
+ * File: i18n.cc
+ * Project: libvdr - classes taken from vdr-project
+ *
+ * from "Video Disk Recorder":
+ *
+ * Copyright (C) 2000, 2003, 2006, 2008 Klaus Schmidinger
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ * The original author can be reached at kls@tvdr.de
+ *
+ * The vdr project's page is at http://www.tvdr.de
+ *
+ * In case an English phrase is used in more than one context (and might need
+ * different translations in other languages) it can be preceded with an
+ * arbitrary string to describe its context, separated from the actual phrase
+ * by a '$' character (see for instance "Button$Stop" vs. "Stop").
+ * Of course this means that no English phrase may contain the '$' character!
+ * If this should ever become necessary, the existing '$' would have to be
+ * replaced with something different...
+ */
+#include <i18n.h>
+#include <String.h>
+#include <StringList.h>
+#include <FileNameList.h>
+#include <Logging.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <libintl.h>
+#include <locale.h>
+#include <unistd.h>
+
+// TRANSLATORS: The name of the language, as written natively
+const char *LanguageName = trNOOP("LanguageName$English");
+// TRANSLATORS: The 3-letter code of the language
+const char *LanguageCode = trNOOP("LanguageCode$eng");
+
+#define AsString(s) #s
+
+// List of known language codes with aliases.
+// Actually we could list all codes from http://www.loc.gov/standards/iso639-2
+// here, but that would be several hundreds - and for most of them it's unlikely
+// they're ever going to be used...
+
+const char *LanguageCodeList[] = {
+ "eng,dos",
+ "deu,ger",
+ "slv,slo",
+ "ita",
+ "dut,nla,nld",
+ "prt",
+ "fra,fre",
+ "nor",
+ "fin,suo",
+ "pol",
+ "esl,spa",
+ "ell,gre",
+ "sve,swe",
+ "rom,rum",
+ "hun",
+ "cat,cln",
+ "rus",
+ "srb,srp,scr,scc",
+ "hrv",
+ "est",
+ "dan",
+ "cze,ces",
+ "tur",
+ "ukr",
+ "ara",
+ NULL
+ };
+
+static const char *I18nLocaleDir = AsString(LOCDIR);
+
+static cStringList LanguageLocales;
+static cStringList LanguageNames;
+static cStringList LanguageCodes;
+
+static int NumLocales = 1;
+static int CurrentLanguage = 0;
+
+static bool ContainsCode(const char *Codes, const char *Code)
+{
+ while (*Codes) {
+ int l = 0;
+ for ( ; l < 3 && Code[l]; l++) {
+ if (Codes[l] != tolower(Code[l]))
+ break;
+ }
+ if (l == 3)
+ return true;
+ Codes++;
+ }
+ return false;
+}
+
+static const char *SkipContext(const char *s)
+{
+ const char *p = strchr(s, '$');
+ return p ? p + 1 : s;
+}
+
+static void SetEnvLanguage(const char *Locale)
+{
+ setenv("LANGUAGE", Locale, 1);
+ extern int _nl_msg_cat_cntr;
+ ++_nl_msg_cat_cntr;
+}
+
+void I18nInitialize(const char *LocaleDir)
+{
+ if (LocaleDir)
+ I18nLocaleDir = LocaleDir;
+ LanguageLocales.Append(strdup(I18N_DEFAULT_LOCALE));
+ LanguageNames.Append(strdup(SkipContext(LanguageName)));
+ LanguageCodes.Append(strdup(LanguageCodeList[0]));
+ textdomain("vdr");
+ bindtextdomain("vdr", I18nLocaleDir);
+ cFileNameList Locales(I18nLocaleDir, true);
+ if (Locales.Size() > 0) {
+ char *OldLocale = strdup(setlocale(LC_MESSAGES, NULL));
+ for (int i = 0; i < Locales.Size(); i++) {
+ cString FileName = cString::sprintf("%s/%s/LC_MESSAGES/vdr.mo", I18nLocaleDir, Locales[i]);
+ if (access(FileName, F_OK) == 0) { // found a locale with VDR texts
+ if (NumLocales < I18N_MAX_LANGUAGES - 1) {
+ SetEnvLanguage(Locales[i]);
+ const char *TranslatedLanguageName = gettext(LanguageName);
+ if (TranslatedLanguageName != LanguageName) {
+ NumLocales++;
+ if (strstr(OldLocale, Locales[i]) == OldLocale)
+ CurrentLanguage = LanguageLocales.Size();
+ LanguageLocales.Append(strdup(Locales[i]));
+ LanguageNames.Append(strdup(TranslatedLanguageName));
+ const char *Code = gettext(LanguageCode);
+ for (const char **lc = LanguageCodeList; *lc; lc++) {
+ if (ContainsCode(*lc, Code)) {
+ Code = *lc;
+ break;
+ }
+ }
+ LanguageCodes.Append(strdup(Code));
+ }
+ }
+ else {
+ esyslog("ERROR: too many locales - increase I18N_MAX_LANGUAGES!");
+ break;
+ }
+ }
+ }
+ SetEnvLanguage(LanguageLocales[CurrentLanguage]);
+ free(OldLocale);
+ dsyslog("found %d locales in %s", NumLocales - 1, I18nLocaleDir);
+ }
+ // Prepare any known language codes for which there was no locale:
+ for (const char **lc = LanguageCodeList; *lc; lc++) {
+ bool Found = false;
+ for (int i = 0; i < LanguageCodes.Size(); i++) {
+ if (strcmp(*lc, LanguageCodes[i]) == 0) {
+ Found = true;
+ break;
+ }
+ }
+ if (!Found) {
+ dsyslog("no locale for language code '%s'", *lc);
+ LanguageLocales.Append(strdup(I18N_DEFAULT_LOCALE));
+ LanguageNames.Append(strdup(*lc));
+ LanguageCodes.Append(strdup(*lc));
+ }
+ }
+}
+
+void I18nRegister(const char *Plugin)
+{
+ cString Domain = cString::sprintf("vdr-%s", Plugin);
+ bindtextdomain(Domain, I18nLocaleDir);
+}
+
+void I18nSetLocale(const char *Locale)
+{
+ if (Locale && *Locale) {
+ int i = LanguageLocales.Find(Locale);
+ if (i >= 0) {
+ CurrentLanguage = i;
+ SetEnvLanguage(Locale);
+ }
+ else
+ dsyslog("unknown locale: '%s'", Locale);
+ }
+}
+
+int I18nCurrentLanguage(void)
+{
+ return CurrentLanguage;
+}
+
+void I18nSetLanguage(int Language)
+{
+ if (Language < LanguageNames.Size()) {
+ CurrentLanguage = Language;
+ I18nSetLocale(I18nLocale(CurrentLanguage));
+ }
+}
+
+int I18nNumLanguagesWithLocale(void)
+{
+ return NumLocales;
+}
+
+const cStringList *I18nLanguages(void)
+{
+ return &LanguageNames;
+}
+
+const char *I18nTranslate(const char *s, const char *Plugin)
+{
+ if (!s)
+ return s;
+ if (CurrentLanguage) {
+ const char *t = Plugin ? dgettext(Plugin, s) : gettext(s);
+ if (t != s)
+ return t;
+ }
+ return SkipContext(s);
+}
+
+const char *I18nLocale(int Language)
+{
+ return 0 <= Language && Language < LanguageLocales.Size() ? LanguageLocales[Language] : NULL;
+}
+
+const char *I18nLanguageCode(int Language)
+{
+ return 0 <= Language && Language < LanguageCodes.Size() ? LanguageCodes[Language] : NULL;
+}
+
+int I18nLanguageIndex(const char *Code)
+{
+ for (int i = 0; i < LanguageCodes.Size(); i++) {
+ if (ContainsCode(LanguageCodes[i], Code))
+ return i;
+ }
+ //dsyslog("unknown language code: '%s'", Code);
+ return -1;
+}
+
+const char *I18nNormalizeLanguageCode(const char *Code)
+{
+ for (int i = 0; i < 3; i++) {
+ if (Code[i]) {
+ // ETSI EN 300 468 defines language codes as consisting of three letters
+ // according to ISO 639-2. This means that they are supposed to always consist
+ // of exactly three letters in the range a-z - no digits, UTF-8 or other
+ // funny characters. However, some broadcasters apparently don't have a
+ // copy of the DVB standard (or they do, but are perhaps unable to read it),
+ // so they put all sorts of non-standard stuff into the language codes,
+ // like nonsense as "2ch" or "A 1" (yes, they even go as far as using
+ // blanks!). Such things should go into the description of the EPG event's
+ // ComponentDescriptor.
+ // So, as a workaround for this broadcaster stupidity, let's ignore
+ // language codes with unprintable characters...
+ if (!isprint(Code[i])) {
+ //dsyslog("invalid language code: '%s'", Code);
+ return "???";
+ }
+ // ...and replace blanks with underlines (ok, this breaks the 'const'
+ // of the Code parameter - but hey, it's them who started this):
+ if (Code[i] == ' ')
+ *((char *)&Code[i]) = '_';
+ }
+ else
+ break;
+ }
+ int n = I18nLanguageIndex(Code);
+ return n >= 0 ? I18nLanguageCode(n) : Code;
+}
+
+bool I18nIsPreferredLanguage(int *PreferredLanguages, const char *LanguageCode, int &OldPreference, int *Position)
+{
+ int pos = 1;
+ bool found = false;
+ while (LanguageCode) {
+ int LanguageIndex = I18nLanguageIndex(LanguageCode);
+ for (int i = 0; i < LanguageCodes.Size(); i++) {
+ if (PreferredLanguages[i] < 0)
+ break; // the language is not a preferred one
+ if (PreferredLanguages[i] == LanguageIndex) {
+ if (OldPreference < 0 || i < OldPreference) {
+ OldPreference = i;
+ if (Position)
+ *Position = pos;
+ found = true;
+ break;
+ }
+ }
+ }
+ if ((LanguageCode = strchr(LanguageCode, '+')) != NULL) {
+ LanguageCode++;
+ pos++;
+ }
+ else if (pos == 1 && Position)
+ *Position = 0;
+ }
+ if (OldPreference < 0) {
+ OldPreference = LanguageCodes.Size(); // higher than the maximum possible value
+ return true; // if we don't find a preferred one, we take the first one
+ }
+ return found;
+}
diff --git a/libs/vdr/summary.txt b/libs/vdr/summary.txt
new file mode 100644
index 0000000..a2a3582
--- /dev/null
+++ b/libs/vdr/summary.txt
@@ -0,0 +1 @@
+libvdr - classes taken from vdr-project
diff --git a/libs/vdr/vdr.cbp b/libs/vdr/vdr.cbp
new file mode 100644
index 0000000..82be645
--- /dev/null
+++ b/libs/vdr/vdr.cbp
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+ <FileVersion major="1" minor="6" />
+ <Project>
+ <Option title="CMP.libs.vdr" />
+ <Option pch_mode="2" />
+ <Option compiler="gcc" />
+ <Build>
+ <Target title="Debug">
+ <Option output="libvdr" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Debug/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-fomit-frame-pointer" />
+ <Add option="-Winit-self" />
+ <Add option="-Wredundant-decls" />
+ <Add option="-std=c++0x" />
+ <Add option="-Wall" />
+ <Add option="-g" />
+ </Compiler>
+ </Target>
+ <Target title="Release">
+ <Option output="libvdr" prefix_auto="1" extension_auto="1" />
+ <Option working_dir="" />
+ <Option object_output="obj/Release/" />
+ <Option type="2" />
+ <Option compiler="gcc" />
+ <Option createDefFile="1" />
+ <Compiler>
+ <Add option="-Winit-self" />
+ <Add option="-Wredundant-decls" />
+ <Add option="-Wmissing-declarations" />
+ <Add option="-Wmissing-include-dirs" />
+ <Add option="-std=c++0x" />
+ <Add option="-Wextra" />
+ <Add option="-Wall" />
+ </Compiler>
+ </Target>
+ </Build>
+ <Compiler>
+ <Add option="-fomit-frame-pointer -fPIC -pthread -Wall -Wno-parentheses -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=implicit-function-declaration -ansi" />
+ <Add option="-D_REENTRANT" />
+ <Add option="-D_GNU_SOURCE=1" />
+ <Add option="-DLOCDIR=/usr/share/locale" />
+ <Add directory="include" />
+ <Add directory="/usr/include/freetype2" />
+ <Add directory="/usr/include/fribidi" />
+ </Compiler>
+ <Unit filename="include/CharsetConv.h" />
+ <Unit filename="include/CondWait.h" />
+ <Unit filename="include/FileNameList.h" />
+ <Unit filename="include/Logging.h" />
+ <Unit filename="include/Mutex.h" />
+ <Unit filename="include/ReadDir.h" />
+ <Unit filename="include/String.h" />
+ <Unit filename="include/StringList.h" />
+ <Unit filename="include/Thread.h" />
+ <Unit filename="include/TimeMs.h" />
+ <Unit filename="include/Vector.h" />
+ <Unit filename="include/i18n.h" />
+ <Unit filename="include/tools.h" />
+ <Unit filename="src/CharsetConv.cc" />
+ <Unit filename="src/CondWait.cc" />
+ <Unit filename="src/FileNameList.cc" />
+ <Unit filename="src/Logging.cc" />
+ <Unit filename="src/Mutex.cc" />
+ <Unit filename="src/ReadDir.cc" />
+ <Unit filename="src/String.cc" />
+ <Unit filename="src/StringList.cc" />
+ <Unit filename="src/Thread.cc" />
+ <Unit filename="src/TimeMs.cc" />
+ <Unit filename="src/i18n.cc" />
+ <Extensions>
+ <code_completion />
+ <envvars />
+ <lib_finder disable_auto="1" />
+ <debugger />
+ </Extensions>
+ </Project>
+</CodeBlocks_project_file>
diff --git a/libs/vdr/vdr.depend b/libs/vdr/vdr.depend
new file mode 100644
index 0000000..c4ac310
--- /dev/null
+++ b/libs/vdr/vdr.depend
@@ -0,0 +1 @@
+# depslib dependency file v1.0
diff --git a/libs/vdr/vdr.layout b/libs/vdr/vdr.layout
new file mode 100644
index 0000000..43b8191
--- /dev/null
+++ b/libs/vdr/vdr.layout
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/i18n.cc" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/Thread.cc" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/CharsetConv.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/Thread.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>
diff --git a/libs/vdr/vdr.layout.save b/libs/vdr/vdr.layout.save
new file mode 100644
index 0000000..52982d9
--- /dev/null
+++ b/libs/vdr/vdr.layout.save
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_layout_file>
+ <ActiveTarget name="Debug" />
+ <File name="src/i18n.cc" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="include/Thread.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/Thread.cc" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+ <File name="src/CharsetConv.cc" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
+ <Cursor>
+ <Cursor1 position="0" topLine="0" />
+ </Cursor>
+ </File>
+</CodeBlocks_layout_file>