HSAdmin Backend Domains, E-Mail, Datenbanken
Christof Donat
2012-04-24 c64ab570a19423c51b6b8b5937fc8e6d08f63821
added more or less resurrected C++ cli client. This will need a lot of
work.

please note, that I would do quite some things differently nowadays. I
home to get those things in via refactoring


22 files added
5833 ■■■■■ changed files
hsacppcli/Makefile 70 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/CMakeLists.txt 129 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/doc/Doxyfile.in 1679 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/doc/logo.png patch | view | raw | blame | history
hsacppcli/hsadminc/source/CMakeLists.txt 11 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/abstractcmdlineparser.cpp 22 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/abstractcmdlineparser.h 417 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/cmdlineparser.cpp 772 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/cmdlineparser.h 386 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/configfile.cpp 257 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/configfile.h 94 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/hsadminc.cpp 155 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/httpclient.cpp 146 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/httpclient.h 163 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/logger.cpp 136 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/logger.h 68 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/sslclient.cpp 171 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/sslclient.h 73 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/transaction.cpp 502 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/transaction.h 77 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/xmlparser.cpp 209 ●●●●● patch | view | raw | blame | history
hsacppcli/hsadminc/source/xmlparser.h 296 ●●●●● patch | view | raw | blame | history
hsacppcli/Makefile
New file
@@ -0,0 +1,70 @@
#
# (c) okunah gmbh
#
# name: Makefile
#
# description: description
#
# written by: Christof Donat
#
# changes:
#    05.11.11 (Christof Donat): created this file
#
#
# includes
#
#
# defines
#
#
# rules
#
all: release
debug-test: debug
    cd build/Debug; make test
debug: debug-env
    cd build/Debug; make
debug-dir:
    if [ ! -d build/Debug ]; then mkdir -p build/Debug; fi
debug-env: debug-dir
    cd build/Debug; cmake -DCMAKE_BUILD_TYPE="Debug" ../../hsadminc/
test: release
    cd build/Release; make test
release: release-env
    cd build/Release; make
release-env: release-dir
    cd build/Release; cmake -DCMAKE_BUILD_TYPE="Release" ../../hsadminc/
release-dir:
    if [ ! -d build/Release ]; then mkdir -p build/Release; fi
small-test: small
    cd build/MinSizeRel; make test
small: small-env
    cd build/MinSizeRel; make
small-env: small-dir
    cd build/MinSizeRel; cmake -DCMAKE_BUILD_TYPE="MinSizeRel" ../../hsadminc/
small-dir:
    if [ ! -d build/MinSizeRel ]; then mkdir -p build/MinSizeRel; fi
clean:
    rm -rf build
# end Makefile
hsacppcli/hsadminc/CMakeLists.txt
New file
@@ -0,0 +1,129 @@
PROJECT( hsadminc )
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
#
# look for packages needed for the build to succeed
#
# find boost libraries
SET(Boost_USE_MULTITHREADED      ON)
SET(Boost_USE_STATIC_RUNTIME    OFF)
FIND_PACKAGE( Boost 1.44 REQUIRED COMPONENTS date_time filesystem iostreams regex system unit_test_framework thread )
# find doxygen
FIND_PACKAGE( Doxygen 1.7.3 )
# find GnuTLS
FIND_PACKAGE( GnuTLS 2.8.6 REQUIRED )
#
# set compiler and linker flags
#
# compiler
SET( CMAKE_CXX_FLAGS_DEBUG "-g3 -O0" )
SET( CMAKE_CXX_FLAGS_RELEASE "-O3" )
SET( CMAKE_CXX_FLAGS_RELWITHDEBINFO "-g3 -O3" )
SET( CMAKE_CXX_FLAGS_MINSIZEREL "-Os" )
# gcc specific
IF( CMAKE_COMPILER_IS_GNUCC )
    SET( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wold-style-cast -pedantic -Wall -Wextra -Winit-self -Wshadow -Wconversion -Wlogical-op -Wnormalized=nfc -Winline -std=c++0x" )
    SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++0x" )
    SET( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -std=c++0x" )
    SET( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -std=c++0x" )
ENDIF()
#linker
SET( CMAKE_LINK_FLAGS_DEBUG "-g -O0" )
SET( CMAKE_LINK_FLAGS_RELEASE "-O3" )
SET( CMAKE_LINK_FLAGS_RELWITHDEBINFO "-g -O3" )
SET( CMAKE_LINK_FLAGS_MINSIZEREL "-O3" )
# GNU ld specific
IF( CMAKE_COMPILER_IS_GNUCC )
    SET( CMAKE_LINK_FLAGS_DEBUG "${CMAKE_LINK_FLAGS_RELEASE} --relax" )
    SET( CMAKE_LINK_FLAGS_RELEASE "${CMAKE_LINK_FLAGS_RELEASE} --relax" )
    SET( CMAKE_LINK_FLAGS_RELWITHDEBINFO "${CMAKE_LINK_FLAGS_RELWITHDEBINFO} --relax" )
    SET( CMAKE_LINK_FLAGS_MINSIZEREL "${CMAKE_LINK_FLAGS_MINSIZEREL} -s --gc-sections --relax" )
ENDIF()
# build the release as default
SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_RELEASE} )
SET( CMAKE_LINK_FLAGS ${CMAKE_LINK_FLAGS_RELEASE} )
# make sure the boost include files are available
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
# all libs that will be linked to hsadminc
SET( HSADMINC_LIB ${Boost_LIBRARIES} gnutls )
# now this is where the source is
ADD_SUBDIRECTORY( source )
# packaging
IF( ${UNIX} )
    SET( CPACK_GNERATOR "DEB;RPM;" )
    SET( CPACK_PACKAGE_DESCRIPTION "hsadmin command line client" )
    SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY "a command line tool to access servers of the configuration tool hsadmin developed by Hostsharing e.G." )
    SET( CPACK_PACKAGE_NAME "hsadminc" )
    SET( CPACK_DEBIAN_PACKAGE_DEPENDS "boost (>= 1.44), gnutls (>= 2.8.6)" )
    SET( CPACK_PACKAGE_CONTACT "Christof Donat" )
    SET( CPACK_PACKAGE_VENDOR "Hostsharing e.G." )
    SET( CPACK_PACKAGE_VERSION_MAJOR "0" )
    SET( CPACK_PACKAGE_VERSION_MINOR "0" )
    SET( CPACK_PACKAGE_VERSION_PATCH "1" )
    SET( VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}" )
ENDIF()
# currently WIN32 is not supported
#IF( ${WIN32} )
#    SET( CPACK_GNERATOR "NSIS;" )
#    SET( CPACK_NSIS_MUI_ICON "" )
#    SET( CPACK_NSIS_MUI_UNIICON "" )
#    SET( CPACK_PACKAGE_ICON "" )
#    SET( CPACK_NSIS_EXTRA_INSTALL_COMMANDS "" )
#    SET( CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "" )
#    SET( CPACK_NSIS_COMPRESSOR "" )
#    SET( CPACK_NSIS_MODIFY_PATH "" )
#    SET( CPACK_NSIS_DISPLAY_NAME "" )
#    SET( CPACK_NSIS_INSTALLED_ICON_NAME "" )
#    SET( CPACK_NSIS_HELP_LINK "" )
#    SET( CPACK_NSIS_URL_INFO_ABOUT "" )
#    SET( CPACK_NSIS_CONTACT "" )
#    SET( CPACK_NSIS_CREATE_ICONS_EXTRA "" )
#    SET( CPACK_NSIS_DELETE_ICONS_EXTRA "" )
#    SET( CPACK_NSIS_MENU_LINKS "" )
#    SET( CPACK_NSIS_MUI_FINISHPAGE_RUN "" )
#ENDIF()
# currently OSX is not supported
#IF( ${APPLE} )
#    SET( CPACK_GNERATOR "MACOSX_BUNDLE;" )
#    SET( CPACK_PACKAGE_FILE_NAME "" )
#    SET( CPACK_PACKAGE_ICON "" )
#    SET( CPACK_BUNDLE_NAME "" )
#    SET( CPACK_BUNDLE_ICON "" )
#    SET( CPACK_BUNDLE_PLIST "" )
#    SET( CPACK_BUNDLE_STARTUP_COMMAND "" )
#ENDIF()
#
# doxygen documentation
#
CONFIGURE_FILE( doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile )
ADD_CUSTOM_TARGET( doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile )
SET_PROPERTY( DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CKEAN_FILES doc )
GET_TARGET_PROPERTY( DOC_TARGET doc TYPE )
IF( NOT DOC_TARGET )
    ADD_CUSTOM_TARGET( doc )
ENDIF()
ADD_DEPENDENCIES( doc doxygen )
SET( DOC_PATH "share/doc/${CPACK_PACKAGE_NAME}-${VERSION}" )
INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION DOC_PATH )
hsacppcli/hsadminc/doc/Doxyfile.in
New file
@@ -0,0 +1,1679 @@
# Doxyfile 1.7.3
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a hash (#) is considered a comment and will be ignored.
# The format is:
#       TAG = value [value, ...]
# For lists items can also be appended using:
#       TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.
DOXYFILE_ENCODING      = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME           = ${CPACK_PACKAGE_NAME}
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER         = ${VERSION}
# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF          = ${CPACK_PACKAGE_DESCRIPTION}
# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory.
PROJECT_LOGO           = ${CMAKE_CURRENT_SOURCE_DIR}/doc/logo.png
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY       = doc
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
CREATE_SUBDIRS         = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
OUTPUT_LANGUAGE        = English
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC      = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF           = YES
# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
# in this list, if found as the leading text of the brief description, will be
# stripped from the text and the result after processing the whole list, is
# used as the annotated text. Otherwise, the brief description is used as-is.
# If left blank, the following values are used ("$name" is automatically
# replaced with the name of the entity): "The $name class" "The $name widget"
# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"
ABBREVIATE_BRIEF       =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC    = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
INLINE_INHERITED_MEMB  = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES        = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH        =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
# the reader which header file to include in order to use a class.
# If left blank only the name of the header file containing the class
# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH    =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES            = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF      = NO
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF           = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS           = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.
SEPARATE_MEMBER_PAGES  = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE               = 8
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES                =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C  = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.
OPTIMIZE_OUTPUT_JAVA   = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.
OPTIMIZE_FOR_FORTRAN   = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.
OPTIMIZE_OUTPUT_VHDL   = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given extension.
# Doxygen has a built-in mapping, but you can override or extend it using this
# tag. The format is ext=language, where ext is a file extension, and language
# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
EXTENSION_MAPPING      =
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also makes the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT    = YES
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
CPP_CLI_SUPPORT        = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.
SIP_SUPPORT            = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT   = NO
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC   = NO
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
# the same type (for instance a group of public functions) to be put as a
# subgroup of that type (e.g. under the Public Functions section). Set it to
# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING            = YES
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
TYPEDEF_HIDES_STRUCT   = NO
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is
# probably good enough. For larger projects a too small cache size can cause
# doxygen to be busy swapping symbols to and from disk most of the time
# causing a significant performance penalty.
# If the system has enough physical memory increasing the cache will improve the
# performance by keeping more symbols in memory. Note that the value works on
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols
SYMBOL_CACHE_SIZE      = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL            = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE        = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC         = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES  = YES
# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS  = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespaces are hidden.
EXTRACT_ANON_NSPACES   = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS     = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES     = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS  = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
# documentation blocks found inside the body of a function.
# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.
HIDE_IN_BODY_DOCS      = NO
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS          = NO
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower-case letters. If set to YES upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
CASE_SENSE_NAMES       = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES       = NO
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES     = YES
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
# rather than with sharp brackets.
FORCE_LOCAL_INCLUDES   = NO
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO            = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS       = NO
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
# brief documentation of file, namespace and class members alphabetically
# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS        = NO
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
# will sort the (brief and detailed) documentation of class members so that
# constructors and destructors are listed first. If set to NO (the default)
# the constructors will appear in the respective orders defined by
# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
SORT_MEMBERS_CTORS_1ST = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
# the group names will appear in their defined order.
SORT_GROUP_NAMES       = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
# sorted by fully-qualified names, including namespaces. If set to
# NO (the default), the class list will be sorted only by class name,
# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the
# alphabetical list.
SORT_BY_SCOPE_NAME     = NO
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a
# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
# will still accept a match between prototype and implementation in such cases.
STRICT_PROTO_MATCHING  = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST      = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST      = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST       = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS       =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or macro consists of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and macros in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES  = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES        = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES       = NO
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.
SHOW_FILES             = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page.
# This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.
SHOW_NAMESPACES        = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command <command> <input-file>, where <command> is the value of
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.
FILE_VERSION_FILTER    =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. The create the layout file
# that represents doxygen's defaults, run doxygen with the -l option.
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.
LAYOUT_FILE            =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET                  = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS               = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED   = YES
# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some
# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.
WARN_IF_DOC_ERROR      = YES
# The WARN_NO_PARAMDOC option can be enabled to get warnings for
# functions that are documented, but have no documentation for their parameters
# or return value. If set to NO (the default) doxygen will only warn about
# wrong or incomplete parameter documentation, but not about the absence of
# documentation.
WARN_NO_PARAMDOC       = NO
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text. Optionally the format may contain
# $version, which will be replaced by the version of the file (if it could
# be obtained via FILE_VERSION_FILTER)
WARN_FORMAT            = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE           =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT                  = ${CMAKE_CURRENT_SOURCE_DIR}/source
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
# the list of possible encodings.
INPUT_ENCODING         = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl
FILE_PATTERNS          =
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE              = NO
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE                = ${CMAKE_CURRENT_SOURCE_DIR}/source/test
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
EXCLUDE_SYMLINKS       = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories. Note that the wildcards are matched
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS       =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS        =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH           =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS       =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE      = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH             =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
# If FILTER_PATTERNS is specified, this tag will be
# ignored.
INPUT_FILTER           =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis.
# Doxygen will compare the file name with each pattern and apply the
# filter if there is a match.
# The filters are a list of the form:
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
# info on how filters are used. If FILTER_PATTERNS is empty or if
# non of the patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS        =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES    = NO
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
# and it is also possible to disable source filtering for a specific pattern
# using *.ext= (so without naming a filter). This option only has effect when
# FILTER_SOURCE_FILES is enabled.
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER         = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES         = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS    = YES
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = NO
# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION    = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
# link to the source code.
# Otherwise they will link to the documentation.
REFERENCES_LINK_SOURCE = YES
# If the USE_HTAGS tag is set to YES then the references to source code
# will point to the HTML generated by the htags(1) tool instead of doxygen
# built-in source browser. The htags tool is part of GNU's global source
# tagging system (see http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.
USE_HTAGS              = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS       = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX     = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX    = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX          =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML          = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT            = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION    = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER            =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER            =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET        =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://en.wikipedia.org/wiki/Hue for more information.
# For instance the value 0 represents red, 60 is yellow, 120 is green,
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.
HTML_COLORSTYLE_HUE    = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
# grayscales only. A value of 255 will produce the most vivid colors.
HTML_COLORSTYLE_SAT    = 100
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
# the luminance component of the colors in the HTML output. Values below
# 100 gradually make the output lighter, whereas values above 100 make
# the output darker. The value divided by 100 is the actual gamma applied,
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
# and 100 does not change the gamma.
HTML_COLORSTYLE_GAMMA  = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP         = NO
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS     = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS  = NO
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
# integrated development environment, introduced with OSX 10.5 (Leopard).
# To create a documentation set, doxygen will generate a Makefile in the
# HTML output directory. Running make will produce the docset in that
# directory and running "make install" will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
# it at startup.
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
GENERATE_DOCSET        = NO
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# feed. A documentation feed provides an umbrella under which multiple
# documentation sets from a single provider (such as a company or product suite)
# can be grouped.
DOCSET_FEEDNAME        = "Doxygen generated docs"
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
# should uniquely identify the documentation set bundle. This should be a
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
# will append .docset to the name.
DOCSET_BUNDLE_ID       = org.doxygen.Project
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
DOCSET_PUBLISHER_NAME  = Publisher
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP      = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
# written to the html output directory.
CHM_FILE               =
# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
# be used to specify the location (absolute path including file name) of
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.
HHC_LOCATION           =
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI           = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.
CHM_INDEX_ENCODING     =
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC             = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND             = NO
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
# that can be used as input for Qt's qhelpgenerator to generate a
# Qt Compressed Help (.qch) of the generated HTML documentation.
GENERATE_QHP           = NO
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
# be used to specify the file name of the resulting .qch file.
# The path specified is relative to the HTML output folder.
QCH_FILE               =
# The QHP_NAMESPACE tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace
QHP_NAMESPACE          = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
QHP_VIRTUAL_FOLDER     = doc
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
# add. For more information please see
# http://doc.trolltech.com/qthelpproject.html#custom-filters
QHP_CUST_FILTER_NAME   =
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
# Qt Help Project / Custom Filters</a>.
QHP_CUST_FILTER_ATTRS  =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's
# filter section matches.
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
# Qt Help Project / Filter Attributes</a>.
QHP_SECT_FILTER_ATTRS  =
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
# be used to specify the location of Qt's qhelpgenerator.
# If non-empty doxygen will try to run qhelpgenerator on the generated
# .qhp file.
QHG_LOCATION           =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
#  will be generated, which together with the HTML files, form an Eclipse help
# plugin. To install this plugin and make it available under the help contents
# menu in Eclipse, the contents of the directory containing the HTML and XML
# files needs to be copied into the plugins directory of eclipse. The name of
# the directory within the plugins directory should be the same as
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.
GENERATE_ECLIPSEHELP   = NO
# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
# this name.
ECLIPSE_DOC_ID         = org.doxygen.Project
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX          = NO
# This tag can be used to set the number of enum values (range [0,1..20])
# that doxygen will group on one line in the generated HTML documentation.
# Note that a value of 0 will completely suppress the enum values from appearing in the overview section.
ENUM_VALUES_PER_LINE   = 4
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to YES, a side panel will be generated
# containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
# Windows users are probably better off using the HTML help feature.
GENERATE_TREEVIEW      = NO
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
# and Class Hierarchy pages using a tree view instead of an ordered list.
USE_INLINE_TREES       = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH         = 250
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
# links to external symbols imported via tag files in a separate window.
EXT_LINKS_IN_WINDOW    = NO
# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# when you change the font size after a successful doxygen run you need
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.
FORMULA_FONTSIZE       = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
# in the HTML output before the changes have effect.
FORMULA_TRANSPARENT    = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
# (see http://www.mathjax.org) which uses client side Javascript for the
# rendering instead of using prerendered bitmaps. Use this if you do not
# have LaTeX installed or if you want to formulas look prettier in the HTML
# output. When enabled you also need to install MathJax separately and
# configure the path to it using the MATHJAX_RELPATH option.
USE_MATHJAX            = NO
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
# directory is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing
# MathJax, but it is strongly recommended to install a local copy of MathJax
# before deployment.
MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
# (GENERATE_DOCSET) there is already a search function so this one should
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
SEARCHENGINE           = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvantages are that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH    = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX         = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT           = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.
LATEX_CMD_NAME         = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME     = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX          = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE             = a4
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES         =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER           =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS         = YES
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX           = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE        = NO
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES     = NO
# If LATEX_SOURCE_CODE is set to YES then doxygen will include
# source code with syntax highlighting in the LaTeX output.
# Note that which sources are shown also depends on other settings
# such as SOURCE_BROWSER.
LATEX_SOURCE_CODE      = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF           = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT             = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF            = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS         = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE    =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE    =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN           = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT             = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION          = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS              = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML           = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.
XML_OUTPUT             = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA             =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD                =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING     = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF   = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES Doxygen will
# generate a Perl module file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_PERLMOD       = NO
# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.
PERLMOD_LATEX          = NO
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
# nicely formatted so it can be parsed by a human reader.
# This is useful
# if you want to understand what is going on.
# On the other hand, if this
# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.
PERLMOD_PRETTY         = YES
# The names of the make variables in the generated doxyrules.make file
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING   = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION        = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
EXPAND_ONLY_PREDEF     = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES        = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH           =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS  =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. To prevent a macro definition from being
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
PREDEFINED             =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code.
EXPAND_AS_DEFINED      =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all references to function-like macros
# that are alone on a line, have an all uppercase name, and do not end with a
# semicolon, because these will confuse the parser if not removed.
SKIP_FUNCTION_MACROS   = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
# The TAGFILES option can be used to specify one or more tagfiles.
# Optionally an initial location of the external documentation
# can be added for each tagfile. The format of a tag file without
# this location is as follows:
#
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
#
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where "loc1" and "loc2" can be relative or absolute paths or
# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.
TAGFILES               =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE       =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS           = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS        = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH              = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
# or super classes. Setting the tag to NO turns the diagrams off. Note that
# this option also works with HAVE_DOT disabled, but it is recommended to
# install and use dot, since it yields more powerful graphs.
CLASS_DIAGRAMS         = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH            =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS   = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT               = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) doxygen will
# base this on the number of processors available in the system. You can set it
# explicitly to a value larger than 0 to get control over the balance
# between CPU load and processing speed.
DOT_NUM_THREADS        = 0
# By default doxygen will write a font called Helvetica to the output
# directory and reference it in all dot files that doxygen generates.
# When you want a differently looking font you can specify the font name
# using DOT_FONTNAME. You need to make sure dot is able to find the font,
# which can be done by putting it in a standard location or by setting the
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
# containing the font.
DOT_FONTNAME           = Helvetica
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.
DOT_FONTSIZE           = 10
# By default doxygen will tell dot to use the output directory to look for the
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
# different font using DOT_FONTNAME you can set the path where dot
# can find it using this tag.
DOT_FONTPATH           =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH            = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH    = YES
# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies
GROUP_GRAPHS           = YES
# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
UML_LOOK               = YES
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS     = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH          = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH      = YES
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable call graphs
# for selected functions only using the \callgraph command.
CALL_GRAPH             = NO
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
# doxygen will generate a caller dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable caller
# graphs for selected functions only using the \callergraph command.
CALLER_GRAPH           = NO
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will generate a graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY    = YES
# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
# then doxygen will show the dependencies a directory has on other directories
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.
DIRECTORY_GRAPH        = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, svg, gif or svg.
# If left blank png will be used.
DOT_IMAGE_FORMAT       = png
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
DOT_PATH               =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS           =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the
# \mscfile command).
MSCFILE_DIRS           =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
# nodes that will be shown in the graph. If the number of nodes in a graph
# becomes larger than this value, doxygen will truncate the graph, which is
# visualized by representing a node as a red box. Note that doxygen if the
# number of direct children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
DOT_GRAPH_MAX_NODES    = 50
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes
# that lay further from the root node will be omitted. Note that setting this
# option to 1 or 2 may greatly reduce the computation time needed for large
# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
MAX_DOT_GRAPH_DEPTH    = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not
# seem to support this out of the box. Warning: Depending on the platform used,
# enabling this option may lead to badly anti-aliased labels on the edges of
# a graph (i.e. they become hard to read).
DOT_TRANSPARENT        = NO
# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
DOT_MULTI_TARGETS      = YES
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND        = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP            = YES
hsacppcli/hsadminc/doc/logo.png
hsacppcli/hsadminc/source/CMakeLists.txt
New file
@@ -0,0 +1,11 @@
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} )
SET( HSADMINC_SRC abstractcmdlineparser.cpp cmdlineparser.cpp configfile.cpp hsadminc.cpp httpclient.cpp logger.cpp sslclient.cpp transaction.cpp xmlparser.cpp )
ADD_EXECUTABLE( hsadminc ${HSADMINC_SRC} )
TARGET_LINK_LIBRARIES( hsadminc ${HSADMINC_LIB} )
INSTALL( TARGETS hsadminc RUNTIME DESTINATION bin )
hsacppcli/hsadminc/source/abstractcmdlineparser.cpp
New file
@@ -0,0 +1,22 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 #include "abstractcmdlineparser.h"
hsacppcli/hsadminc/source/abstractcmdlineparser.h
New file
@@ -0,0 +1,417 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <vector>
#include <string>
#include "logger.h"
#include <boost/lexical_cast.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/algorithm/string.hpp>
/** abstractcommandlineparser holds some basic stuff for making commandline-Parsers easier. */
namespace abstractcommandlineparser {
#ifndef HSADMIN_ABSTRACTCMDLINEPARSER
#define HSADMIN_ABSTRACTCMDLINEPARSER
using std::vector;
using std::string;
using boost::shared_ptr;
using boost::scoped_ptr;
using boost::starts_with;
using boost::erase_first;
/** \brief template for Commandline-Parser
 *
 *  Has two Parameters:
 *  - class Options: This class must provide a method 'parseThis()'. - see template CmdLineOption for an example
 *  - class parseResult: a shared pointer to an Object of this class is passed to the Options.
 */
template<class Options,class parserResult> class CmdLineParser {
    public:
    /** \brief this actually not only instatiates the parser but also parses Parameters.
     *
     *  takes the Options in a vector<string>
     */
    CmdLineParser(vector<string> options) : m_parsed(new parserResult), m_parseSuccessful(false) {
        Options o;
        while( options.size() > 0 )
            if( !(this->m_parseSuccessful = o.parseThis(options,m_parsed)) )
                return;
    };
    //! has the parser been successful?
    inline bool operator!() { return !this->m_parseSuccessful; }
    protected:
    shared_ptr<parserResult> m_parsed;
    bool m_parseSuccessful;
};
/** \brief base template for Option classes
 *
 * usually you would use one of the many specialisations
 * has four parameters:
 * - bool hasLongName: the Parameter has a long name (e.g. --verbose)
 * - bool hasShortName: the Parameter has a short name (e.g. -v)
 * - bool hasParameter: the Parameter is followed by another Parameter that belongs to it
 * - class parseResult: takes the Parse results
 *
 * You should implement a protected virtual method 'bool handle(string &parameter, shared_ptr<parseResult> result)'
 * if you have 'hasParameter' set to true or 'bool handle(shared_ptr<parseResult> result)' otherwise. There you
 * can actually store your values in your parseResult.
 */
template <bool hasLongName, bool hasShortName, bool hasParameter,class parseResult> class CmdLineOption {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {};
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that do have long and short names as well as a value.
 *
 * You should implement a protected virtual method
 * 'bool handle(string &parameter, shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<true, true, true,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( starts_with(options[0], "-"+m_shortName) ) {
            if( rval = this->handle(options[1],result) ) {
                if( options[0] == "-"+m_shortName)
                    options.erase(options.begin(),options.begin()+2);
                else {
                    options.erase(options.begin()+1);
                    erase_first(options[0], m_shortName);
                }
            }
        } else {
            if( starts_with(options[0], "--"+m_longName+m_parameterSeparator) ) {
                string p = options[0].substr(m_longName.size()+m_parameterSeparator.size()+2);
                if( rval = this->handle(p,result) )
                    options.erase(options.begin());
            }
        }
        return rval;
    }
    protected:
    string m_longName;
    string m_shortName;
    string m_parameterSeparator;
    //! the handle function.
    virtual bool handle(string &parameter, shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that do have long and short names but no value.
 *
 * You should implement a protected virtual method
 * 'bool handle(shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<true, true, false,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( options[0] == "-"+m_shortName || options[0] == "--"+m_longName ) {
            if( rval = this->handle(result) )
                options.erase(options.begin());
        } else if( starts_with(options[0], "-"+m_shortName) && (rval = this->handle(result)) )
            erase_first(options[0], m_shortName);
        return rval;
    }
    protected:
    string m_longName;
    string m_shortName;
    //! the handle function.
    virtual bool handle(shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that only have a long name and a value but no short name.
 *
 * You should implement a protected virtual method
 * 'bool handle(string &parameter, shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<true, false, true,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( starts_with(options[0], "--"+m_longName+m_parameterSeparator) ) {
            string p = options[0].substr(m_longName.size()+m_parameterSeparator.size()+2);
            if ( rval = this->handle(p, result) )
                options.erase(options.begin());
        }
        return rval;
    }
    protected:
    string m_longName;
    string m_parameterSeparator;
    //! the handle function.
    virtual bool handle(string &parameter, shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that only have a long name but no value or short name.
 *
 * You should implement a protected virtual method
 * 'bool handle(shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<true, false, false,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( options[0] == "--"+m_longName && (rval = this->handle(result)) )
            options.erase(options.begin());
        return rval;
    }
    protected:
    string m_longName;
    //! the handle function.
    virtual bool handle(shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that only have short name and a value but no long name.
 *
 * You should implement a protected virtual method
 * 'bool handle(string &parameter, shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<false, true, true,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( starts_with(options[0], "-"+m_shortName) && (rval = this->handle(options[1],result)) ) {
            if( options[0] == "-"+m_shortName)
                options.erase(options.begin(),options.begin()+2);
            else {
                options.erase(options.begin()+1);
                erase_first(options[0], m_shortName);
            }
        }
        return rval;
    }
    protected:
    string m_shortName;
    //! the handle function.
    virtual bool handle(string &parameter, shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that only have short name bot no value or long name.
 *
 * You should implement a protected virtual method
 * 'bool handle(shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<false, true, false,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( starts_with(options[0], "-"+m_shortName) && (rval = this->handle(result)) ) {
            if( options[0] == "-"+m_shortName )
                options.erase(options.begin());
            else
                erase_first(options[0], m_shortName);
        }
        return rval;
    }
    protected:
    string m_shortName;
    //! the handle function.
    virtual bool handle(shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that only have  a value but neither a long or short name.
 *
 * You should implement a protected virtual method
 * 'bool handle(string &parameter, shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<false, false, true,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( !starts_with(options[0], "-") && (rval = this->handle(options[0],result)) )
            options.erase(options.begin());
        return rval;
    }
    protected:
    //! the handle function.
    virtual bool handle(string &parameter, shared_ptr<parseResult> result) { return true; };
};
/** \brief base template for Option classes - specialisation
 *
 * this is the specialisation for Parameters that neither have a value, a long or short name.
 *
 * You should implement a protected virtual method
 * 'bool handle(shared_ptr<parseResult> result)'.
 * There you can actually store your values in your parseResult.
 */
template <class parseResult> class CmdLineOption<false, false, false,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        bool rval = false;
        if( !starts_with(options[0], "-") && (rval = this->handle(result)) )
            options.erase(options.begin());
        return rval;
    }
    protected:
    //! the handle function.
    virtual bool handle(shared_ptr<parseResult> result) { return true; };
};
//! just needed for typelists
class nullType {};
//! typelist for multiple Options parser
template<class CAR, class CDR> class typelist {
    public:
    typedef CAR car;
    typedef CDR cdr;
};
/** \brief A Commandline-Option for CmdLineParser that works with a typelist of Options.
 *
 * this is meant to combine multiple Parameters in a typelist to build a complex Command Line parser
 */
template<class tl, class parseResult> class CmdLineOptionList : public CmdLineOption<false,false,false,parseResult> {
    public:
    //! the actual parser function.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        return m_first.parseThis(options,result) || m_second.parseThis(options,result);
    }
    private:
    typename tl::car                                 m_first;
    CmdLineOptionList<typename tl::cdr,parseResult>  m_second;
};
/** \brief specialisation for empty type list
 */
template<class parseResult> class CmdLineOptionList<nullType,parseResult> : public CmdLineOption<false,false,false,parseResult> {
    public:
    //! the actual parser function; always returns false.
    bool parseThis(vector<string>& options, shared_ptr<parseResult> result) {
        return false;
    }
};
#define Parameterlist1(t1) \
    abstractcommandlineparser::typelist<t1,abstractcommandlineparser::nullType>
#define Parameterlist2(t1,t2) \
    abstractcommandlineparser::typelist<t1,Parameterlist1(t2) >
#define Parameterlist3(t1,t2,t3) \
    abstractcommandlineparser::typelist<t1,Parameterlist2(t2,t3) >
#define Parameterlist4(t1,t2,t3,t4) \
    abstractcommandlineparser::typelist<t1,Parameterlist3(t2,t3,t4) >
#define Parameterlist5(t1,t2,t3,t4,t5) \
    abstractcommandlineparser::typelist<t1,Parameterlist4(t2,t3,t4,t5) >
#define Parameterlist6(t1,t2,t3,t4,t5,t6) \
    abstractcommandlineparser::typelist<t1,Parameterlist5(t2,t3,t4,t5,t6) >
#define Parameterlist7(t1,t2,t3,t4,t5,t6,t7) \
    abstractcommandlineparser::typelist<t1,Parameterlist6(t2,t3,t4,t5,t6,t7) >
#define Parameterlist8(t1,t2,t3,t4,t5,t6,t7,t8) \
    abstractcommandlineparser::typelist<t1,Parameterlist7(t2,t3,t4,t5,t6,t7,t8) >
#define Parameterlist9(t1,t2,t3,t4,t5,t6,t7,t8,t9) \
    abstractcommandlineparser::typelist<t1,Parameterlist8(t2,t3,t4,t5,t6,t7,t8,t9) >
#define Parameterlist10(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) \
    abstractcommandlineparser::typelist<t1,Parameterlist9(t2,t3,t4,t5,t6,t7,t8,t9,t10) >
#define Parameterlist11(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) \
    abstractcommandlineparser::typelist<t1,Parameterlist10(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) >
#define Parameterlist12(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) \
    abstractcommandlineparser::typelist<t1,Parameterlist11(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) >
#define Parameterlist13(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13) \
    abstractcommandlineparser::typelist<t1,Parameterlist12(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13) >
#define Parameterlist14(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14) \
    abstractcommandlineparser::typelist<t1,Parameterlist13(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14) >
#define Parameterlist15(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15) \
    abstractcommandlineparser::typelist<t1,Parameterlist14(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15) >
#define Parameterlist16(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16) \
    abstractcommandlineparser::typelist<t1,Parameterlist15(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16) >
#define Parameterlist17(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17) \
    abstractcommandlineparser::typelist<t1,Parameterlist16(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17) >
#define Parameterlist18(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18) \
    abstractcommandlineparser::typelist<t1,Parameterlist17(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18) >
#define Parameterlist19(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19) \
    abstractcommandlineparser::typelist<t1,Parameterlist18(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19) >
#define Parameterlist20(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20) \
    abstractcommandlineparser::typelist<t1,Parameterlist19(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20) >
#define Parameterlist21(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21) \
    abstractcommandlineparser::typelist<t1,Parameterlist20(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21) >
#define Parameterlist22(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22) \
    abstractcommandlineparser::typelist<t1,Parameterlist21(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22) >
#define Parameterlist23(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23) \
    abstractcommandlineparser::typelist<t1,Parameterlist22(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23) >
#define Parameterlist24(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24) \
    abstractcommandlineparser::typelist<t1,Parameterlist23(t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24) >
#else
template<class Options,class parseResult> class CmdLineParser;
template <bool hasLongName, bool hasShortName, bool hasParameter,class parseResult> class CmdLineOption;
class nullType;
template<class CAR, class CDR> class typelist;
template<class tl, class parseResult> class CmdLineOptionList;
#endif /* HSADMIN_ABSTRACTCMDLINEPARSER */
};
hsacppcli/hsadminc/source/cmdlineparser.cpp
New file
@@ -0,0 +1,772 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <iostream>
#include <sstream>
#include <fstream>
#include "cmdlineparser.h"
#include "logger.h"
#include <termios.h>
#include <unistd.h>
namespace commandline {
using std::cout;
using std::cin;
using std::flush;
using std::ifstream;
using std::ostringstream;
using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::shared_ptr;
using boost::scoped_ptr;
using boost::starts_with;
using boost::erase_first;
// dynamic cast needs this
vector<string> callParameter::parseDisplayspec() {
    vector<string> rval;
    boost::regex pattern("\\$\\{([^\\}]*)\\}");
    boost::sregex_iterator end;
    for(boost::sregex_iterator i(this->m_display.begin(),this->m_display.end(),pattern); i != end; i++ )
        rval.insert(rval.end(),(*i)[1]);
    Logger::log(Logger::DEBUG,"have parsed displayspec Parameter '"+this->m_display+"'");
    return rval;
}
string callParameter::evalDisplay(const map<string, string> &values) {
    string rval = this->m_display;
    string::size_type pos;
    for( map<string,string>::const_iterator i = values.begin(); i != values.end(); i++ ) {
        string pattstring = "${"+i->first+"}";
        while( (pos = rval.find(pattstring,0)) != string::npos ) rval.replace(pos,pattstring.length(),i->second);
    }
    while( (pos = rval.find("\\n",0)) != string::npos ) rval.replace(pos,2,"\n");
    while( (pos = rval.find("\\t",0)) != string::npos ) rval.replace(pos,2,"\t");
    while( (pos = rval.find("\\r",0)) != string::npos ) rval.replace(pos,2,"\r");
    Logger::log(Logger::DEBUG,"have evaluated displayspec Parameter '"+this->m_display+"': '"+rval+"'");
    return rval;
}
string setParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) {
    string rpccall = "<struct>";
    rpccall += "<member><name>property</name><value>"+m_property+"</value></member>";
    rpccall += "<member><name>value</name><value>"+m_value+"</value></member>";
    rpccall += "</struct>";
    return rpccall;
}
string whereParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) {
    string rpccall = "<struct>";
    rpccall += "<member><name>property</name><value>"+m_property+"</value></member>";
    rpccall += "<member><name>value</name><value>"+m_pattern+"</value></member>";
    rpccall += "</struct>";
    return rpccall;
}
string orderParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) {
    string rpccall = "<struct>";
    rpccall += "<member><name>property</name><value>"+m_property+"</value></member>";
    rpccall += "<member><name>ascending</name><value><boolean>";
    rpccall += string((m_ascending?"1":"0"))+"</boolean></value></member>";
    rpccall += "</struct>";
    return rpccall;
}
string callParameter::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) {
    string rpccall = "<struct>";
    rpccall += "<member>";
    rpccall += "<name>module</name>";
    rpccall += "<value>"+m_module+"</value>";
    rpccall += "</member>";
    rpccall += "<member>";
    rpccall += "<name>function</name>";
    rpccall += "<value>"+m_function+"</value>";
    rpccall += "</member>";
    if( m_force ) {
        rpccall += "<member>";
        rpccall += "<name>force</name>";
        rpccall += "<value><boolean>1</boolean></value>";
        rpccall += "</member>";
    }
    if( m_ignoreerror ) {
        rpccall += "<member>";
        rpccall += "<name>ignoreerror</name>";
        rpccall += "<value><boolean>1</boolean></value>";
        rpccall += "</member>";
    }
    // read
    vector<string> reads = parseDisplayspec();
    if(reads.size()) {
        rpccall += "<member>";
        rpccall += "<name>read</name>";
        rpccall += "<value><array><data>";
        for(vector<string>::iterator j = reads.begin(); j != reads.end(); j++ )
            rpccall += "<value>"+(*j)+"</value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    if( m_where.size() ) {
        rpccall += "<member>";
        rpccall += "<name>where</name>";
        rpccall += "<value><array><data>";
        for(vector<shared_ptr<whereParameter> >::iterator j = m_where.begin(); j != m_where.end(); j++ )
            rpccall += "<value>"+((*j)->toXML(username,cfgfile))+"</value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    if( m_set.size() ) {
        rpccall += "<member>";
        rpccall += "<name>set</name>";
        rpccall += "<value><array><data>";
        for(vector<shared_ptr<setParameter> >::iterator j = m_set.begin(); j != m_set.end(); j++ )
            rpccall += "<value>"+((*j)->toXML(username,cfgfile))+"</value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    if( m_order.size() ) {
        rpccall += "<member>";
        rpccall += "<name>order</name>";
        rpccall += "<value><array><data>";
        for(vector<shared_ptr<orderParameter> >::iterator j = m_order.begin(); j != m_order.end(); j++ )
            rpccall += "<value>"+((*j)->toXML(username,cfgfile))+"</value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    if( m_objects.size() ) {
        rpccall += "<member>";
        rpccall += "<name>objectid</name>";
        rpccall += "<value><array><data>";
        for(vector<string>::iterator j = m_objects.begin(); j != m_objects.end(); j++ )
            rpccall += "<value>"+(*j)+"</value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    if( m_unset.size() ) {
        rpccall += "<member>";
        rpccall += "<name>unset</name>";
        rpccall += "<value><array><data>";
        for(vector<string>::iterator j = m_unset.begin(); j != m_unset.end(); j++ )
            rpccall += "<value><struct><member><name>property</name><value>"+(*j)+"</value></member></struct></value>";
        rpccall += "</data></array></value>";
        rpccall += "</member>";
    }
    rpccall += "</struct>";
    return rpccall;
}
parsedParameters::parsedParameters():
    m_error(NOERROR),
    m_user(""),
    m_ticket(""),
    m_defaultDisplay(""),
    m_addConfigFile(""),
    m_test(false),
    m_ignoreerrors(false) {}
string parsedParameters::toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile) {
    // begin method call
    string rpccall = "<?xml version=\"1.0\"?><methodCall><methodName>hsadmin.transaction</methodName><params>";
    // ticket
    rpccall += "<param><value><string>";
    if( this->m_ticket != "" ) {
        string ticket;
        ifstream file(this->m_ticket.c_str());
        if( ! file ) {
            string msg = Logger::getMessageFormatString(Logger::CouldNotOpenFile);
            boost::format fmt(msg);
            fmt % this->m_ticket;
            Logger::log(Logger::FATAL,fmt.str());
            exit(-1);
        }
        char ch;
        while(file.get(ch)) ticket += ch;
        boost::regex findticket(".*\\n---\\n");
        ticket = boost::regex_replace(ticket,findticket,"");
        if( ticket[ticket.size()-1] == '\0' ) ticket = ticket.substr(0,ticket.size()-2);
        rpccall += ticket;
    } else {
        rpccall += cfgfile->getTicket(username);
    }
    Logger::log(Logger::DEBUG,"have read ticket");
    rpccall += "</string></value></param>";
    // global Parameters
    rpccall += "<param><value><struct>";
    if( this->m_test )
        rpccall += "<member><name>test</name><value><boolean>1</boolean></value></member>";
    rpccall += "</struct></value></param>";
    // calls Array
    rpccall += "<param><value><array><data>";
    for( vector<shared_ptr<callParameter> >::iterator c = m_call.begin(); c != m_call.end(); c++ )
        rpccall += "<value>"+((*c)->toXML(username,cfgfile))+"</value>";
    rpccall += "</data></array></value></param>";
    rpccall += "</params></methodCall>\n";
    return rpccall;
}
// specific Parser for --runas-Option
bool VerbosityOption::parseThis(vector<string>& options, shared_ptr<parsedParameters> result) {
    bool rval = false;
    if( starts_with(options[0], "-v") ) {
        if( options[1] == "none" ||
            options[1] == "normal" ||
            options[1] == "high" ||
            options[1] == "debug" ||
            options[1] == "debugXML" ||
            options[1] == "debugAll" ) {
            if( rval = this->handle(options[1], result) ) {
                if( options[0] == "-v" )
                    options.erase(options.begin(),options.begin()+2);
                else {
                    erase_first(options[0], "v");
                    options.erase(options.begin()+1);
                }
            }
        } else {
            string p;
            if( rval = this->handle(p, result) ) {
                if( options[0] == "-v" )
                    options.erase(options.begin());
                else
                    erase_first(options[0], "v");
            }
        }
    }
    if( starts_with(options[0], "--verbosity=") ) {
        string p = options[0].substr(12);
        if( rval = this->handle(p, result) )
            options.erase(options.begin());
    }
    return rval;
}
// constuctors
TestOption::TestOption() {
    m_longName = "test";
    m_shortName = "t";
}
IgnoreErrorOption::IgnoreErrorOption() {
    m_longName = "ignoreerror";
    m_shortName = "e";
}
IgnoreErrorsOption::IgnoreErrorsOption() {
    m_longName = "ignoreerrors";
    m_shortName = "E";
}
VerbosityOption::VerbosityOption() {
    m_longName = "verbosity";
    m_shortName = "v";
    m_parameterSeparator = "=";
}
RunAsOption::RunAsOption() {
    m_longName = "runas";
    m_shortName = "r";
    m_parameterSeparator = "=";
}
TicketOption::TicketOption() {
    m_longName = "ticket";
    m_shortName = "T";
    m_parameterSeparator = "=";
}
ConfigOption::ConfigOption() {
    m_longName = "config";
    m_shortName = "C";
    m_parameterSeparator = "=";
}
ForceOption::ForceOption() {
    m_longName = "force";
}
GlobalsOption::GlobalsOption() {
    m_longName = "globals";
    m_shortName = "l";
}
WhereOption::WhereOption() {
    m_longName = "where";
    m_shortName = "w";
    m_parameterSeparator = ":";
}
OnlyOption::OnlyOption() {
    m_longName = "only";
    m_shortName = "W";
    m_parameterSeparator = ":";
}
SetOption::SetOption() {
    m_longName = "set";
    m_shortName = "s";
    m_parameterSeparator = ":";
}
SetAllOption::SetAllOption() {
    m_longName = "setall";
    m_shortName = "S";
    m_parameterSeparator = ":";
}
InfileOption::InfileOption() {
    m_longName = "infile";
    m_shortName = "f";
    m_parameterSeparator = ":";
}
OrderOption::OrderOption() {
    m_longName = "order";
    m_shortName = "o";
    m_parameterSeparator = ":";
}
GlobalOrderOption::GlobalOrderOption() {
    m_longName = "global-order";
    m_shortName = "O";
    m_parameterSeparator = ":";
}
InputOption::InputOption() {
    m_longName = "input";
    m_shortName = "i";
    m_parameterSeparator = ":";
}
PassInputOption::PassInputOption() {
    m_longName = "passinput";
    m_shortName = "p";
    m_parameterSeparator = ":";
}
DisplayOption::DisplayOption() {
    m_longName = "display";
    m_shortName = "d";
    m_parameterSeparator = ":";
}
DefaultDisplayOption::DefaultDisplayOption() {
    m_longName = "default-display";
    m_shortName = "D";
    m_parameterSeparator = ":";
}
CallOption::CallOption() {
    m_longName = "call";
    m_shortName = "c";
    m_parameterSeparator = ":";
}
UnsetOption::UnsetOption() {
    m_longName = "unset";
    m_shortName = "u";
    m_parameterSeparator = ":";
}
UnsetAllOption::UnsetAllOption() {
    m_longName = "unsetall";
    m_shortName = "U";
    m_parameterSeparator = ":";
}
ObjectID::ObjectID() { };
// handle functions
bool TestOption::handle(shared_ptr<parsedParameters> result) {
    result->m_test = true;
    Logger::log(Logger::DEBUG," found test Option");
    return true;
}
bool IgnoreErrorOption::handle(shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_ignoreerror = true;
    Logger::log(Logger::DEBUG," found ignoreerror Option");
    return true;
}
bool IgnoreErrorsOption::handle(shared_ptr<parsedParameters> result) {
    result->m_ignoreerrors = true;
    Logger::log(Logger::DEBUG," found ignoreerrors Option");
    return true;
}
bool VerbosityOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( parameter == "none" )         Logger::setLevel(0);
    else if( parameter == "normal")   Logger::setLevel(1);
    else if( parameter == "high")     Logger::setLevel(2);
    else if( parameter == "debug")    Logger::setLevel(3);
    else if( parameter == "debugXML") Logger::setLevel(4);
    else if( parameter == "debugAll") Logger::setLevel(5);
    else                              Logger::incrementLevel();
    Logger::log(Logger::DEBUG," set Verbosity Level to "+lexical_cast<string>(Logger::level));
    return true;
}
bool QuietOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    Logger::decrementLevel();
    Logger::log(Logger::DEBUG," set Verbosity Level to "+lexical_cast<string>(Logger::level));
    return true;
}
bool RunAsOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    result->m_user = parameter;
    Logger::log(Logger::DEBUG," found runas Option: "+parameter);
    return true;
}
bool TicketOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    result->m_ticket = parameter;
    Logger::log(Logger::DEBUG," found ticket Option: "+parameter);
    return true;
}
bool ConfigOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    result->m_addConfigFile = parameter;
    Logger::log(Logger::DEBUG," found config Option: "+parameter);
    return true;
}
bool ForceOption::handle(shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_force = true;
    Logger::log(Logger::DEBUG," found force Option");
    return true;
}
bool GlobalsOption::handle(shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_globalOrderIndex = result->m_call.back()->m_order.size();
    Logger::log(Logger::DEBUG," found globals Option");
    return true;
}
bool WhereOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    string::size_type pos = parameter.find('=');
    string property(parameter,0,pos);
    string pattern(parameter,(pos != string::npos)?(pos+1):(string::npos));
    whereParameter *where = new whereParameter();
    where->m_property = property;
    where->m_pattern  = pattern;
    result->m_call.back()->m_where.push_back(shared_ptr<whereParameter>(where));
    Logger::log(Logger::DEBUG," found where Option: "+parameter);
    return true;
}
bool OnlyOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    string::size_type pos = parameter.find('=');
    string property(parameter,0,pos);
    string pattern(parameter,(pos != string::npos)?(pos+1):(string::npos));
    whereParameter *where = new whereParameter();
    where->m_property = property;
    where->m_pattern  = pattern;
    result->m_only.push_back(shared_ptr<whereParameter>(where));
    Logger::log(Logger::DEBUG," found only Option: "+parameter);
    return true;
}
bool UnsetOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_unset.push_back(parameter);
    Logger::log(Logger::DEBUG," found unset Option: "+parameter);
    return true;
}
bool UnsetAllOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    result->m_unsetall.push_back(parameter);
    Logger::log(Logger::DEBUG," found unsetall Option: "+parameter);
    return true;
}
bool OrderOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    string::size_type pos = parameter.find('=');
    string *property;
    string * direction;
    if( pos != string::npos ) {
        property = new string(parameter,0,pos);
        direction = new string(parameter,(pos != string::npos)?(pos+1):(string::npos));
    } else {
        property = new string(parameter);
        direction = new string("a");
    }
    orderParameter *order = new orderParameter();
    order->m_property = *property;
    order->m_ascending  = ((*direction)[0] == 'a');
    result->m_call.back()->m_order.push_back(shared_ptr<orderParameter>(order));
    Logger::log(Logger::DEBUG," found order Option: "+parameter);
    return true;
}
bool GlobalOrderOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    string::size_type pos = parameter.find('=');
    string *property;
    string * direction;
    if( pos != string::npos ) {
        property = new string(parameter,0,pos);
        direction = new string(parameter,(pos != string::npos)?(pos+1):(string::npos));
    } else {
        property = new string(parameter);
        direction = new string("a");
    }
    orderParameter *order = new orderParameter();
    order->m_property = *property;
    order->m_ascending  = ((*direction)[0] == 'a');
    result->m_globalOrder.push_back(shared_ptr<orderParameter>(order));
    Logger::log(Logger::DEBUG," found global order Option: "+parameter);
    return true;
}
bool SetOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    string::size_type pos = parameter.find('=');
    string property(parameter,0,pos);
    string value(parameter,(pos != string::npos)?(pos+1):(string::npos));
    setParameter *set = new setParameter();
    set->m_property = property;
    set->m_value  = value;
    result->m_call.back()->m_set.push_back(shared_ptr<setParameter>(set));
    Logger::log(Logger::DEBUG," found set Option: "+parameter);
    return true;
}
bool SetAllOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    string::size_type pos = parameter.find('=');
    string property(parameter,0,pos);
    string value(parameter,(pos != string::npos)?(pos+1):(string::npos));
    setParameter *set = new setParameter();
    set->m_property = property;
    set->m_value  = value;
    result->m_setall.push_back(shared_ptr<setParameter>(set));
    Logger::log(Logger::DEBUG," found setall Option: "+parameter);
    return true;
}
bool InfileOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    string::size_type pos = parameter.find('=');
    string property(parameter,0,pos);
    string filename(parameter,(pos != string::npos)?(pos+1):(string::npos));
    setParameter *set = new setParameter();
    set->m_property = property;
    ifstream file(filename.c_str());
    if( ! file ) {
        string msg = Logger::getMessageFormatString(Logger::CouldNotOpenFile);
        boost::format fmt(msg);
        fmt % filename;
        Logger::log(Logger::FATAL,fmt.str());
        exit(-1);
    }
    char ch;
    while(file.get(ch)) set->m_value += ch;
    result->m_call.back()->m_set.push_back(shared_ptr<setParameter>(set));
    Logger::log(Logger::DEBUG," found infile Option: "+parameter);
    return true;
}
bool InputOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    setParameter *set = new setParameter();
    set->m_property = parameter;
    cout << "Eingabe (" << parameter << "): " << flush;
    std::getline(cin, set->m_value);
    result->m_call.back()->m_set.push_back(shared_ptr<setParameter>(set));
    Logger::log(Logger::DEBUG," found input Option: "+parameter);
    return true;
}
string readPasswd() {
    string rval = "";
    struct termios t, t2;
    tcgetattr(0,&t);
    t2 = t;
    t2.c_lflag &= ~ECHO;
    tcsetattr(0,TCSANOW,&t2);
    std::getline(cin, rval);
    tcsetattr(0,TCSANOW,&t);
    return rval;
}
bool PassInputOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    setParameter *set = new setParameter();
    set->m_property = parameter;
    cout << "Passworteingabe (" << parameter << "): " << flush;
    set->m_value = readPasswd();
    result->m_call.back()->m_set.push_back(shared_ptr<setParameter>(set));
    Logger::log(Logger::DEBUG," found password-input Option: "+parameter);
    return true;
}
bool DisplayOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_display = parameter;
    Logger::log(Logger::DEBUG," found display Option: "+parameter);
    return true;
}
bool DefaultDisplayOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    result->m_defaultDisplay = parameter;
    Logger::log(Logger::DEBUG," found default display Option: "+parameter);
    return true;
}
bool ObjectID::handle(string &parameter, shared_ptr<parsedParameters> result) {
    if( result->m_call.size() <= 0 ) {
        result->m_error = NeedCall;
        return false;
    }
    result->m_call.back()->m_objects.push_back(parameter);
    Logger::log(Logger::DEBUG," found an ObjectID: "+parameter);
    return true;
}
bool CallOption::handle(string &parameter, shared_ptr<parsedParameters> result) {
    string::size_type pos = parameter.find('.');
    string module(parameter,0,pos);
    string function(parameter,(pos != string::npos)?(pos+1):(string::npos));
    callParameter *call = new callParameter();
    call->m_module   = module;
    call->m_function = function;
    result->m_call.push_back(shared_ptr<callParameter>(call));
    Logger::log(Logger::DEBUG," found call Option: "+parameter);
    return true;
}
};
hsacppcli/hsadminc/source/cmdlineparser.h
New file
@@ -0,0 +1,386 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <vector>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include "abstractcmdlineparser.h"
#include "configfile.h"
//! here comes the commandline-Parser - with help of the abstractcommandlineparser.
namespace commandline {
#ifndef HSADMIN_CMDLINEPARSER
#define HSADMIN_CMDLINEPARSER
using std::vector;
using std::string;
using std::map;
using boost::shared_ptr;
using boost::scoped_ptr;
// Parameter Objects are the resultof each Parser step and used in second step.
//! parsed values of a --setall, --set, --input, --passinput or a --infile option
class setParameter {
    public:
    string m_property;
    string m_value;
    string toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile);
};
//! parsed values of a --only or a --where option
class whereParameter {
    public:
    string m_property;
    string m_pattern;
    string toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile);
};
//! parsed values of a --global-order or a --order option
class orderParameter {
    public:
    string m_property;
    bool m_ascending;
    string toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile);
};
//! a whole parsed --call Option which holds all the relevant other options
class callParameter {
    public:
    callParameter(): m_module(""), m_function(""), m_display(""), m_ignoreerror(false), m_force(false), m_globalOrderIndex(-1) { };
    string m_module;
    string m_function;
    string m_display;
    vector<shared_ptr<setParameter> >   m_set;
    vector<shared_ptr<whereParameter> > m_where;
    vector<shared_ptr<orderParameter> > m_order;
    vector<string> m_objects;
    vector<string> m_unset;
    bool   m_ignoreerror;
    bool   m_force;
    int    m_globalOrderIndex;
    vector<string> parseDisplayspec();
    string evalDisplay(const map<string, string> &values);
    string toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile);
};
enum parseError { NOERROR = 0, NeedCall = 1 };
//! all the parsed values
class parsedParameters {
    public:
    parsedParameters();
    parseError m_error;
    string m_user;
    string m_ticket;
    string m_defaultDisplay;
    string m_addConfigFile;
    bool m_test;
    bool m_ignoreerrors;
    vector<shared_ptr<whereParameter> > m_only;
    vector<shared_ptr<setParameter> >   m_setall;
    vector<shared_ptr<orderParameter> > m_globalOrder;
    vector<shared_ptr<callParameter> >  m_call;
    vector<string> m_unsetall;
    string toXML(string &username, shared_ptr< ::ConfigFileParser > cfgfile);
};
// Option classes are used in first Parse step
//! --test
class TestOption: public abstractcommandlineparser::CmdLineOption<true,true,false,parsedParameters> {
    public:
    TestOption();
    protected:
    virtual bool handle(shared_ptr<parsedParameters> result);
};
//! --ignoreerror
class IgnoreErrorOption: public abstractcommandlineparser::CmdLineOption<true,true,false,parsedParameters> {
    public:
    IgnoreErrorOption();
    protected:
    virtual bool handle(shared_ptr<parsedParameters> result);
};
//! --ignoreerrors
class IgnoreErrorsOption: public IgnoreErrorOption {
    public:
    IgnoreErrorsOption();
    protected:
    virtual bool handle(shared_ptr<parsedParameters> result);
};
//! --verbosity
class VerbosityOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    VerbosityOption();
    bool parseThis(vector<string>& options, shared_ptr<parsedParameters> result);
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --quiet
class QuietOption: public abstractcommandlineparser::CmdLineOption<true,true,false,parsedParameters> {
    public:
    QuietOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --runas
class RunAsOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    RunAsOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --ticket
class TicketOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    TicketOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --config
class ConfigOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    ConfigOption();
    protected:
    virtual bool handle(string & parameter, shared_ptr<parsedParameters> result);
};
//! --force
class ForceOption: public abstractcommandlineparser::CmdLineOption<true,false,false,parsedParameters> {
    public:
    ForceOption();
    protected:
    virtual bool handle(shared_ptr<parsedParameters> result);
};
//! --globals
class GlobalsOption: public abstractcommandlineparser::CmdLineOption<true,true,false,parsedParameters> {
    public:
    GlobalsOption();
    protected:
    virtual bool handle(shared_ptr<parsedParameters> result);
};
//! --where
class WhereOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    WhereOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --only
class OnlyOption: public WhereOption {
    public:
    OnlyOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --set
class SetOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    SetOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --setall
class SetAllOption: public SetOption {
    public:
    SetAllOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --infile
class InfileOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    InfileOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --order
class OrderOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    OrderOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --global-order
class GlobalOrderOption: public OrderOption {
    public:
    GlobalOrderOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --input
class InputOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    InputOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --passinput
class PassInputOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    PassInputOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --display
class DisplayOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    DisplayOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --default-display
class DefaultDisplayOption: public DisplayOption {
    public:
    DefaultDisplayOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --call
class CallOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    CallOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --unset
class UnsetOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    UnsetOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! --unsetall
class UnsetAllOption: public abstractcommandlineparser::CmdLineOption<true,true,true,parsedParameters> {
    public:
    UnsetAllOption();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! all other parameters are objectIDs.
class ObjectID: public abstractcommandlineparser::CmdLineOption<false,false,true,parsedParameters> {
    public:
    ObjectID();
    protected:
    virtual bool handle(string &parameter, shared_ptr<parsedParameters> result);
};
//! putting it all together in a typelist
typedef Parameterlist24(
    TestOption,
    IgnoreErrorsOption,
    VerbosityOption,
    RunAsOption,
    TicketOption,
    ConfigOption,
    SetAllOption,
    UnsetAllOption,
    OnlyOption,
    GlobalOrderOption,
    DefaultDisplayOption,
    IgnoreErrorOption,
    ForceOption,
    GlobalsOption,
    WhereOption,
    SetOption,
    InfileOption,
    OrderOption,
    InputOption,
    PassInputOption,
    UnsetOption,
    DisplayOption,
    ObjectID,
    CallOption ) allParameters;
//! generating a class with parse()-function from the list of Options
typedef abstractcommandlineparser::CmdLineOptionList<allParameters, parsedParameters> Parameters;
#else
class parsedParameters;
class setParameter;
class whereParameter;
class orderParameter;
class callParameter;
class TestOption;
class IgnoreErrorOption;
class IgnoreErrorsOption;
class VerbosityOption;
class RunAsOption;
class TicketOption;
class ConfigOption;
class SetAllOption;
class OnlyOption;
class UnsetAllOption;
class GlobalOrderOption;
class DefaultDisplayOption;
class ForceOption;
class GlobalsOption;
class WhereOption;
class SetOption;
class InfileOption;
class OrderOption;
class InputOption;
class PassInputOption;
class DisplayOption;
class unsetOption;
class CallOption;
class ObjectID;
#endif /* HSADMIN_CMDLINEPARSER */
};
hsacppcli/hsadminc/source/configfile.cpp
New file
@@ -0,0 +1,257 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "configfile.h"
#include "logger.h"
#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/format.hpp>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <assert.h>
using std::ostringstream;
using std::istringstream;
using std::ifstream;
using std::fstream;
using std::string;
using boost::lexical_cast;
using boost::bad_lexical_cast;
ConfigFileFinder::ConfigFileFinder(Transaction& t): vector<string*>() {
    try {
        boost::filesystem::path general("/etc/hsadminc.conf");
        if( boost::filesystem::exists(general) && !boost::filesystem::is_directory(general) )
            this->loadFile(general.native());
    } catch(boost::filesystem::filesystem_error) {}
    string priv = getenv("HOME");
    try {
        boost::filesystem::path p( priv + "/.hsadmin.conf");
        if( boost::filesystem::exists(p) && !boost::filesystem::is_directory(p) )
            this->loadFile(p.native());
    } catch(boost::filesystem::filesystem_error) {}
    shared_ptr<commandline::parsedParameters> params = t.getParsed();
    if( params->m_addConfigFile != "" ) try {
        boost::filesystem::path c( params->m_addConfigFile);
        if( boost::filesystem::exists(c) && !boost::filesystem::is_directory(c) )
            this->loadFile(c.native());
    } catch(boost::filesystem::filesystem_error) {}
}
void ConfigFileFinder::loadFile(string filename) {
    ifstream file(filename.c_str(),std::ios::in);
    ostringstream reader;
    reader << file.rdbuf();
    string *tmp = new string(reader.str());
    this->insert(this->end(),tmp);
}
void ConfigFileParser::parse(string& text) {
    vector<string> lines;
    config * current = &(this->basic);
    vector<config> configs;
    boost::split(lines,text,boost::is_any_of("\n"));
    if( current->pattern != ".*" ) {
        current->pattern = ".*";
        current->ticketcommand = "hsadmint \\0";
        current->server = "http://localhost:7777/RPC2";
        current->shell = "/bin/sh";
        current->askpass = false;
    }
    for( vector<string>::iterator i = lines.begin(); i != lines.end(); i++ ) {
        string& line = *i;
        // ignore coments and empty lines
        boost::trim_left(line);
        if( line[0] == '#' || line == ""  )
            continue;
        // is this a section?
        if( line[0] == '[' ) {
            line.erase(0,1);
            line.erase(line.rfind(']'));
            if( current != &(this->basic) ) {
                configs.insert(configs.end(),*current);
                delete(current);
            }
            current = new config;
            *current = this->basic;
            current->pattern = line;
        } else {
            string::size_type equals = line.find('=');
            string name = boost::trim_copy(line.substr(0,equals));
            string value = boost::trim_copy(line.substr(equals+1));
            // trim name and value
            boost::trim(name);
            boost::trim(value);
            if( name == "ticket" )
                current->ticketcommand = value;
            else if( name == "server" )
                current->server = value;
            else if( name == "shell" )
                current->shell = value;
            else if( name == "askpass" && value == "true" )
                current->askpass = true;
            else if( name == "askpass" && value == "false" )
                current->askpass = false;
        }
    }
    if( current != &(this->basic) ) {
        configs.insert(configs.end(),*current);
        delete(current);
    }
    this->configs.insert(this->configs.begin(),configs.begin(),configs.end());
}
string ConfigFileParser::replaceStringMatches(string &userpattern, string username, string content) {
    if( username == "" ) {
        char* u = (char*)malloc(L_cuserid+1);;
        cuserid(u);
         if( u != 0 ) username = u;
    }
    boost::regex pattern(userpattern);
    boost::cmatch results;
    if( !boost::regex_match(username.c_str(),results,pattern) ) return content;
    for(int j = 0; j < results.size(); j++) {
        ostringstream p;
        p << "^\\\\" << j << "|([^\\\\])\\\\" << j;
        boost::regex pat(p.str());
        string replace = "$1";
        if( results[j].matched ) for( const char* i = results[j].first; i != results[j].second; i++ )
            replace += *i;
        content = boost::regex_replace(content,pat,replace);
    }
    return content;
}
string ConfigFileParser::getTicket(string &username) {
    string ticketstring = "";
    config cfg = this->getConfig(username);
    string command = cfg.getTicketcommand(username);
    Logger::log(Logger::DEBUG,"use '"+command+"' as command");
    pid_t pid;
    pid_t parentpid = getpid();
    int cmdout[2];
    if(pipe(cmdout) || (pid=fork()) == -1)
        return "";
    if(!pid) {
        close(1);
        close(cmdout[0]);
        dup(cmdout[1]);
        //command = cfg.shell+" -c \""+command+"\"";
        // this should never return.
        execlp(cfg.shell.c_str(),cfg.shell.c_str(),"-c",command.c_str(),(char*)0);
        // if we have reached this something has gone wrong.
        string msg = Logger::getMessageFormatString(Logger::ErrorWithTicketCommand);
        boost::format fmt(msg);
        fmt % cfg.shell % command % Logger::getErrnoMessage(errno);
        Logger::log(Logger::FATAL,fmt.str());
        exit(-1);
    }
    int status;
    waitpid(pid,&status,0);
    close(cmdout[1]);
    // check if ticket has been successfully generated
    if( !WIFEXITED(status) || WEXITSTATUS(status) )
        exit(WEXITSTATUS(status));
    char buf[257];
    bzero(buf,257);
    errno = 0;
    int i = 0;
    while( (i = read(cmdout[0],buf,256)) != 0 ) {
        if( i < 0 ) {
            if( errno == EAGAIN ) {
                    usleep(20);
                    continue;
            } else if( errno == EINTR ) continue;
            else {
                string msg = Logger::getMessageFormatString(Logger::ErrorReadingTicket);
                boost::format fmt(msg);
                fmt % Logger::getErrnoMessage(errno);
                Logger::log(Logger::FATAL,fmt.str());
                exit(-1);
            }
            errno = 0;
        }
        ticketstring += buf;
        if( strlen(buf) < i ) break;
        bzero(buf,257);
    }
    return ticketstring;
}
ConfigFileParser::config &ConfigFileParser::getConfig(string &username) {
    if( username == "" ) return basic;
    for( vector<config>::iterator i = configs.begin(); i != configs.end(); i++ ) {
        boost::regex pat(i->pattern);
        if(boost::regex_match(username,pat)) return *i;
    }
    return basic;
}
hsacppcli/hsadminc/source/configfile.h
New file
@@ -0,0 +1,94 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <vector>
#include <string>
#include <iostream>
#ifndef HSADMIN_CONFIGFILE
#define HSADMIN_CONFIGFILE
#include "transaction.h"
using std::vector;
using std::string;
using std::iostream;
//! this class manages configfiles
class ConfigFileFinder: public vector<string*> {
    public:
    //! find the standard config-files
    ConfigFileFinder(Transaction& t);
    //! load a config file
    void loadFile(string filename);
};
//! parser for config files
class ConfigFileParser {
    public:
    //! parses one text
    inline ConfigFileParser(string& text) { this->parse(text); };
    //! parses multiple texts
    inline ConfigFileParser(vector<string*>* texts) { this->parse(texts); };
    inline string getTicket() { string s = ""; return getTicket(s); };
    /** \brief get a ticket for a specified user.
     *
     * this function finds the config for this user and calls the tocket-command
     * with the specified shell.
     */
    string getTicket(string &username);
    //! replaces references (\0, \1, etc.) in content with regex-matches.
    static string replaceStringMatches(string &userpattern, string username, string content);
    //! holds single config entries
    struct config {
        string pattern;
        string ticketcommand;
        string server;
        string shell;
        bool askpass;
        string getTicketcommand(string &username) { return ConfigFileParser::replaceStringMatches(pattern,username,ticketcommand); };
        string getServer(string &username) { return ConfigFileParser::replaceStringMatches(pattern,username,ticketcommand); };
        string getShell(string &username) { return ConfigFileParser::replaceStringMatches(pattern,username,ticketcommand); };
    };
    //! find the config for a specified user
    config& getConfig(string &username);
    private:
    void parse(string& text);
    inline void parse(vector<string*>* texts) {
        for( vector<string*>::iterator i = texts->begin(); i != texts->end(); i++ )
            this->parse(**i);
    }
    vector<config> configs;
    config basic;
};
#else
class ConfigFileFinder;
class ConfigFileParser;
#endif /* HSADMIN_CONFIGFILE */
hsacppcli/hsadminc/source/hsadminc.cpp
New file
@@ -0,0 +1,155 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/algorithm/string.hpp>
#include "cmdlineparser.h"
#include "configfile.h"
#include "logger.h"
#include "transaction.h"
using std::string;
using std::vector;
using std::cerr;
using std::endl;
using boost::shared_ptr;
using boost::scoped_ptr;
using boost::starts_with;
void printErrorMessage(Transaction& transact, vector<string>& options) {
    shared_ptr<commandline::parsedParameters> p = transact.getParsed();
    string FailedOption = options[0];
    if( starts_with(FailedOption,"--") )
        FailedOption = FailedOption.substr(2);
    else if( starts_with(FailedOption,"-") )
        FailedOption = FailedOption.substr(1,2);
    cerr << "Error on Commandline at Parameter '"<< FailedOption;
    if( p->m_error == commandline::NeedCall )
        cerr << ": call specific Parameter before call";
    cerr << endl;
}
void printUsage(char* cmdname) {
    cerr << "Usage: " << endl << endl;
    cerr << cmdname << " [--test|-t]" << endl;
    cerr << "[--ignoreerrors|-e]" << endl;
    cerr << "[--verbosity=<level>|-v <level>]" << endl;
    cerr << "[--quiet|-q]" << endl;
    cerr << "[--runas=<user>|-r <user>]" << endl;
    cerr << "[--ticket=<ticketfile>|-T <ticketfile>]" << endl;
    cerr << "[--config=<configfile>|-C <configfile>]" << endl;
    cerr << "[--default-display:<displaySpec>|-D <displaySpec>]" << endl;
    cerr << "[(--only:<property_1>=<expr_1>|-W <property_1>=<expr_1>)" << endl;
    cerr << " ... (--only:<property_n>=<expr_n>|-W <property_n>=<expr_n>)]" << endl;
    cerr << "[(--setall:<property_1>=<value_1>|-S <property_1>=<value_1>)" << endl;
    cerr << " ... (--setall:<property_n>=<value_n>|-S <property_n>=<value_n>)]" << endl;
    cerr << " [(--unsetall:property_1|-U property_1) ... (--unsetall:property_n|-U property_n)]" << endl;
    cerr << "[(--global-order:<property_1>[=(asc|desc|a|d)]|-O <property_1>[=(asc|desc|a|d)])" << endl;
    cerr << "    ..." << endl;
    cerr << " (--global-order:<property_n>[=(asc|desc|a|d)]|-O <property_n>[=(asc|desc|a|d)]]" << endl;
    cerr << " [--ignoreerrors|-E]" << endl;
    cerr << "(--call:<module_1>.<function_1>|-c <module_1>.<function_1>)" << endl;
    cerr << "  [--force]" << endl;
    cerr << "  [--ignoreerror|-e]" << endl;
    cerr << "  [--display:<displaySpec>|-d <displaySpec>]" << endl;
    cerr << "  [(--where:<property_1_1>=<expr_1_1>|-w <property_1_1>=<expr_1_1>)" << endl;
    cerr << "   ... (--where:<property_1_n>=<expr_1_n>|-w <property_1_n>=<expr_1_n>)]" << endl;
    cerr << "  [(--set:<property_1_1>=<value_1_1>|-s <property_1_1>=<value_1_1>)" << endl;
    cerr << "   ... (--set:<property_1_n>=<value_1_n>|-s <property_1_n>=<value_1_n>)]" << endl;
    cerr << "  [(--input:<property_1_1>|-i <property_1_1>)" << endl;
    cerr << "   ... (--input:<property_1_n>|-i <property_1_n>)]" << endl;
    cerr << "  [(--passinput:<property_1_1>|-p <property_1_1>)" << endl;
    cerr << "   ... (--passinput:<property_1_n>|-p <property_1_n>)]" << endl;
    cerr << "  [(--infile:<property_1_1>=<file_1_1>|-f <property_1_1>=<file_1_1>)" << endl;
    cerr << "    ... (--infile:<property_1_n>=<file_1_n>|-f <property_1_n>=<file_1_n>)]" << endl;
    cerr << "     [(--unset:property_1_1|-u property_1_1]) ... (--unset:property_1_n|-u property_1_n])]" << endl;
    cerr << "  [(--order:<property_1_1>[=(asc|desc|a|d)]|-o <property_1_1>[=(asc|desc|a|d)])" << endl;
    cerr << "      ..." << endl;
    cerr << "      [--globals|-l]" << endl;
    cerr << "      ..." << endl;
    cerr << "   (--order:<property_1_n>[=(asc|desc|a|d)]|-o <property_1_n>[=(asc|desc|a|d)]]" << endl;
    cerr << "  [object_1_1 ... object_1_n]" << endl;
    cerr << "..." << endl;
    cerr << "(--call:<module_m>.<function_m>|-c <module_m>.<function_m>)" << endl;
    cerr << "  [--force]" << endl;
    cerr << "  [--ignoreerror|-e]" << endl;
    cerr << "  [--display:<displaySpec>|-d <displaySpec>]" << endl;
    cerr << "  [(--where:<property_m_1>=<expr_m_1>|-w <property_m_1>=<expr_m_1>)" << endl;
    cerr << "   ... (--where:<property_m_n>=<expr_m_n>|-w <property_m_n>=<expr_m_n>)]" << endl;
    cerr << "  [(--set:<property_m_1>=<value_m_1>|-s <property_m_1>=<value_m_1>)" << endl;
    cerr << "   ... (--set:<property_m_n>=<value_m_n>|-s <property_m_n>=<value_m_n>)]" << endl;
    cerr << "  [(--input:<property_m_1>|-i <property_m_1>)" << endl;
    cerr << "   ... (--input:<property_m_n>|-i <property_m_n>)]" << endl;
    cerr << "  [(--passinput:<property_m_1>|-p <property_m_1>)" << endl;
    cerr << "   ... (--passinput:<property_m_n>|-p <property_m_n>)]" << endl;
    cerr << "  [(--infile:<property_m_1>=<file_m_1>|-f <property_m_1>=<file_m_1>)" << endl;
    cerr << "   ... (--infile:<property_m_n>=<file_m_n>|-f <property_m_n>=<file_m_n>)]" << endl;
    cerr << "     [(--unset:property_m_1|-u property_m_1]) ... (--unset:property_m_n|-u property_m_n])]" << endl;
    cerr << "  [(--order:<property_m_1>[=(asc|desc|a|d)]|-o <property_m_1>[=(asc|desc|a|d)])" << endl;
    cerr << "      ..." << endl;
    cerr << "      [--globals|-l]" << endl;
    cerr << "      ..." << endl;
    cerr << "   (--order:<property_m_n>[=(asc|desc|a|d)]|-o <property_m_n>[=(asc|desc|a|d)]]" << endl;
    cerr << "  [object_m_1 ... object_m_n]" << endl;
}
int main(int argc, char *argv[])
{
    if( argc == 1 ) {
        printUsage(*argv);
        exit(1);
    }
    vector<string> options(argv+1,argv+argc);
    Transaction transact(options);
    if( !transact ) {
        printErrorMessage(transact, options);
        printUsage(*argv);
        exit(1);
    }
    Logger::log(Logger::DEBUG,"have parsed Parameters");
    scoped_ptr<ConfigFileFinder> cfff(new ConfigFileFinder(transact));
    shared_ptr<ConfigFileParser> cfg(new ConfigFileParser(cfff.get()));
    Logger::log(Logger::DEBUG,"have read config File");
    transact(cfg);
    Logger::log(Logger::DEBUG,"have executed Transaction");
    //cout << transact.formatOutput();
    //exit(transact.errorCode());
    return 0;
}
hsacppcli/hsadminc/source/httpclient.cpp
New file
@@ -0,0 +1,146 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "httpclient.h"
#include "logger.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
using std::string;
using std::streamsize;
using std::iostream;
using boost::lexical_cast;
using boost::bad_lexical_cast;
TCPDevice::TCPDevice(const string& address, const short int port) {
    this->init(address.c_str(),port);
}
TCPDevice::TCPDevice(const char* address, const short int port) {
    this->init(address,port);
}
void TCPDevice::init(const char* address, const short int port) {
        struct sockaddr_in addr;
        bzero(&addr,sizeof(addr));
        addr.sin_family = AF_INET;
    if( (addr.sin_addr.s_addr = inet_addr(address)) == INADDR_NONE ) {
        struct hostent* hp = gethostbyname(address);
        if( hp == 0 ) throw("can't resolve hostname '"+string(address)+"'");
        bcopy(hp->h_addr, (char*) &addr.sin_addr, hp->h_length);
    }
    addr.sin_port = htons(port);
    if( (m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0 ) throw(string("can't open socket"));
    if( ::connect(m_socket, (struct sockaddr*) &addr, sizeof(addr)) < 0 ) {
        ::close(m_socket);
        throw("can't connect to '"+string(address)+"' port "+(lexical_cast<string>(port)));
    }
}
TCPDevice::TCPDevice(const int socket) : m_socket(socket) {}
TCPDevice::TCPDevice(const TCPDevice& other) : m_socket(other.m_socket) { }
TCPDevice::~TCPDevice() { }
void TCPDevice::closeSocket() { ::close(m_socket); }
streamsize TCPDevice::read(char* s, streamsize n) { return (streamsize)::read(m_socket,(void*)s,(size_t)n); }
streamsize TCPDevice::write(const char* s, streamsize n) { return (streamsize)::write(m_socket,(const void*)s,(size_t)n); }
GenericHttpClient::GenericHttpClient(const string &url, const unsigned short defaultPort = 80):
    m_url(url), m_defaultPort(defaultPort) {};
string GenericHttpClient::post(string postcontent) {
    iostream *connection;
    try { connection = this->parseUrl(); }
    catch(string &e) {
        Logger::log(Logger::FATAL,"connection failed: "+e);
        exit(-1);
    }
    if( connection == 0 ) return "";
    string outbuf = "POST "+m_path+" HTTP/1.1\r\n";
    outbuf += "Connection: close\r\n";
    outbuf += "User-Agent: hsadmin CLI client\r\n";
    outbuf += "Content-Type: text/xml\r\n";
    outbuf += "Content-Length: "+boost::lexical_cast<string>(postcontent.length())+"\r\n";
    outbuf += "Host: "+m_hostname+"\r\n\r\n";
    outbuf += postcontent;
    for( int i = 0; i < outbuf.length(); i++ )
        (*connection) << outbuf[i];;
    connection->flush();
    string reply = "";
    char buf[257];
    do {            // we simply ignore the http header in the response
        bzero(buf,257);
        connection->getline(buf,256);
    } while( string(buf) != "" && string(buf) != "\r" );
    string tmp;
    do {
        tmp = "";
        (*connection) >> tmp;
        reply += " "+tmp;
    } while( tmp.length() );
    this->close();
    delete connection;
    return reply;
};
iostream * GenericHttpClient::parseUrl() {
    int protocolend = m_url.find("://");
    m_protocol = m_url.substr(0,protocolend);
    if( ! this->checkProtocol(m_protocol) ) return (iostream *)0;
    int hostnameend = m_url.find("/",protocolend+3);
    m_hostname = m_url.substr(protocolend+3,hostnameend-(protocolend+3));
    m_port = m_defaultPort;
    m_path = m_url.substr(hostnameend);
    int portstart = m_hostname.find(":");
    if( portstart >= 0 ) {
        string portstring = m_hostname.substr(portstart+1);
        if( portstring.size() > 0 ) {
            try {
                m_port = lexical_cast<int>(portstring.c_str());
                m_hostname = m_hostname.substr(0,m_hostname.find(":"));
            } catch(bad_lexical_cast &) { }
        }
    }
    return this->getConnection(m_hostname, m_port);
};
GenericHttpClient *createHttpClient(const string &url) {
    int protocolend = url.find("://");
    string protocol = url.substr(0,protocolend);
    if( protocol == "http" )  return (GenericHttpClient *) new HttpClient<HTTP>(url);
    if( protocol == "https" ) return (GenericHttpClient *) new HttpClient<HTTPS>(url);
    return 0;
}
hsacppcli/hsadminc/source/httpclient.h
New file
@@ -0,0 +1,163 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <iosfwd>
#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/iostreams/stream.hpp>
#include "sslclient.h"
#ifndef HSADMIN_HTTPCLIENT
#define HSADMIN_HTTPCLIENT
using std::string;
using std::iostream;
using std::streamsize;
using boost::lexical_cast;
using boost::bad_lexical_cast;
//! A Socket as a Device
class TCPDevice : public boost::iostreams::device<boost::iostreams::bidirectional> {
public:
        //! create a TCP-Stream by connecting to the given port at the given address
        TCPDevice(const string& address, const short int port);
        //! create a TCP-Stream by connecting to the given port at the given address
        TCPDevice(const char* address, const short int port);
        //! create a TCP-Stream from a connected socket - use this with accept
        TCPDevice(const int socket);
    //! copy constructor
    TCPDevice(const TCPDevice& other);
        //! does not close the socket - use closeSocket before deleting the Device.
        virtual ~TCPDevice();
    //! closes the socket
    void closeSocket();
        //! read n Bytes from socket
        virtual streamsize read(char* s, streamsize n);
        //! write n Bytes to socket
        virtual streamsize write(const char* s, streamsize n);
private:
    void init(const char* address, const short int port);
        int m_socket;
};
//class SSLDevice;
const int HTTP = 0;
const int HTTPS = 1;
//! the basic HTTP Client - can only handle POST method.
class GenericHttpClient {
    public:
    //! initialize HTTP CLient with URL and default Port (usually 80)
    GenericHttpClient(const string &url, const unsigned short defaultPort);
    //! Post
    string post(string postcontent);
    protected:
    //! get a buffered iostream for the connection - must be overridden by derived classes
    virtual iostream * getConnection(const string &host, unsigned short port) = 0;
    //! check if this class can handle the protocol - must be overridden by derived classes
    virtual bool checkProtocol(const string &protocol) { return false; };
    //! close the underlying connection
    virtual void close() = 0;
    private:
    iostream * parseUrl();
    const string& m_url;
    string m_protocol;
    string m_hostname;
    string m_path;
    unsigned short m_port;
    const unsigned short m_defaultPort;
};
//! This template should usually be used in one of the specialized Versions below.
template <int protocol> class HttpClient: public GenericHttpClient {
    public:
    HttpClient(const string &url, unsigned short defaultPort = 80): GenericHttpClient(url,defaultPort) {};
    protected:
    iostream * getConnection(const string &host, unsigned short port) { return (iostream *)0; };
    bool checkProtocol(const string &p) { return false; };
    virtual void close() { };
};
//! a HTTP CLient with a plain TCP socket as transport
template <> class HttpClient<HTTP>: public GenericHttpClient {
    public:
    //! initialize HTTP CLient with URL and default Port (usually 80)
    HttpClient(const string &url, unsigned short defaultPort = 80): GenericHttpClient(url,defaultPort), device(0) {};
    protected:
    //! get a buffered iostream for the connection
    iostream * getConnection(const string &host, unsigned short port) {
        if( device == 0 ) device = new TCPDevice(host,port);
        return (iostream *) new boost::iostreams::stream<TCPDevice>(*device);
    }
    //! check if this class can handle the protocol
    bool checkProtocol(const string &protocol) { return (protocol == "http"); };
    //! close the underlying connection
    virtual void close() { device->closeSocket(); };
    private:
    TCPDevice *device;
};
//! a HTTP CLient with a SSL stream as transport
template <> class HttpClient<HTTPS>: public GenericHttpClient {
    public:
    //! initialize HTTPS CLient with URL and default Port (usually 443)
    HttpClient(const string &url, unsigned short defaultPort = 443): GenericHttpClient(url,defaultPort), device(0) {};
    protected:
    //! get a buffered iostream for the connection
    iostream * getConnection(const string &host, unsigned short port) {
        try {
            if( device == 0 ) device = new SSLDevice(host,port);
            return (iostream *) new boost::iostreams::stream<SSLDevice>(*device);
        } catch( SSLDevice::CertificateError &e ) {
            if( device != 0 ) {
                delete(device);
                device = 0;
            }
            std::cerr << e.msg << std::endl;
            return (iostream *)0;
        }
    }
    //! check if this class can handle the protocol
    bool checkProtocol(const string &protocol) { return (protocol == "https"); };
    //! close the underlying connection
    virtual void close() { device->closeSocket(); };
    private:
    SSLDevice *device;
};
/** \brief get the best HTTP client for the defined Protocol
 *
 * returns HttpClient<HTTP> or HttpClient<HTTPS> depending on the protocol
 */
GenericHttpClient *createHttpClient(const string &uri);
#else  /* HSADMIN_HTTPCLIENT */
class TCPDevice;
class GenericHttpClient;
genericHttpClient *createHttpClient(url);
extern const int HTTP  = 0;
extern const int HTTPS = 1;
#endif /* HSADMIN_HTTPCLIENT */
hsacppcli/hsadminc/source/logger.cpp
New file
@@ -0,0 +1,136 @@
/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <map>
#include <fstream>
#include <errno.h>
#include "logger.h"
namespace Logger {
const int FATAL   = 1;
const int ERROR   = 2;
const int WARNING = 4;
const int DEBUG   = 8;
const int XML     = 16;
int levels[6] = { 1, 3, 7, 15, 23, 31 };
int level = 1;