]> git.stg.codes - stg.git/commitdiff
Authorization protocol stress test utility
authorMaxim Mamontov <faust@gts.dp.ua>
Wed, 4 May 2011 15:09:22 +0000 (18:09 +0300)
committerMaxim Mamontov <faust@gts.dp.ua>
Wed, 4 May 2011 15:09:22 +0000 (18:09 +0300)
projects/sgauthstress/Makefile [new file with mode: 0644]
projects/sgauthstress/build [new file with mode: 0755]
projects/sgauthstress/main.cpp [new file with mode: 0644]
projects/sgauthstress/settings_impl.cpp [new file with mode: 0644]
projects/sgauthstress/settings_impl.h [new file with mode: 0644]
projects/sgauthstress/sgauth.conf [new file with mode: 0644]
projects/sgauthstress/store_loader.cpp [new file with mode: 0644]
projects/sgauthstress/store_loader.h [new file with mode: 0644]

diff --git a/projects/sgauthstress/Makefile b/projects/sgauthstress/Makefile
new file mode 100644 (file)
index 0000000..1a007ec
--- /dev/null
@@ -0,0 +1,71 @@
+include ../../Makefile.conf
+
+PROG = sgauthstress
+
+SRCS = ./main.cpp \
+       ./settings_impl.cpp \
+       ./store_loader.cpp
+
+STGLIBS =  -lstgcrypto \
+           -lstgcommon \
+           -ldotconfpp \
+           -lstgia
+
+LIBS += $(LIB_THREAD)
+
+ifeq ($(OS),linux)
+LIBS += -ldl
+else
+LIBS += -lintl \
+        -lc
+endif
+
+SEARCH_DIRS = -I $(DIR_INCLUDE)
+
+OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
+
+CXXFLAGS += -Wall
+LDFLAGS += -Wl,-E -L$(DIR_LIB) -Wl,-rpath,$(PREFIX)/usr/lib/stg -Wl,-rpath-link,$(DIR_LIB)
+
+vpath %.so $(DIR_LIB)
+
+.PHONY: all clean distclean libs plugins
+all: libs plugins $(PROG) ../../Makefile.conf
+
+libs:
+       $(MAKE) -C $(DIR_LIBSRC)
+
+plugins: libs 
+       $(MAKE) -C $(DIR_PLUGINS)
+
+$(PROG): $(OBJS) $(STGLIBS) 
+       $(CC) $^ $(LDFLAGS) -o $(PROG) $(LIBS)
+
+clean:
+       rm -f deps $(PROG) *.o tags *.*~ .OS
+       rm -f .OS
+       rm -f .store
+       rm -f .db.sql
+       rm -f core*
+       rm -f css.h
+       $(MAKE) -C $(DIR_LIBSRC) clean
+
+distclean: clean
+       rm -f ../../Makefile.conf
+
+ifneq ($(MAKECMDGOALS),distclean)
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(MAKECMDGOALS),uninstall)
+-include deps
+endif
+endif
+endif
+
+deps:  $(SRCS) ../../Makefile.conf
+       $(MAKE) -C $(DIR_LIBSRC) includes
+       @>deps ;\
+       ./make_css.sh
+       for file in $(SRCS); do\
+         echo "`$(CC) $(CXXFLAGS) $(SEARCH_DIRS) -MM $$file` Makefile" >> deps ;\
+         echo -e '\t$$(CC) -c $$< $(CXXFLAGS) $(SEARCH_DIRS) $(DEFS)' >> deps ;\
+       done
diff --git a/projects/sgauthstress/build b/projects/sgauthstress/build
new file mode 100755 (executable)
index 0000000..e4b4281
--- /dev/null
@@ -0,0 +1,287 @@
+#!/bin/sh
+
+#   $Author: faust $
+#   $Revision: 1.24 $
+#   $Date: 2010/04/14 08:59:02 $
+######################################################
+
+OS=unknown
+sys=`uname -s`
+release=`uname -r | cut -b1`
+BUILD_DIR=`pwd`
+CONFFILE="../../Makefile.conf"
+PREFIX="/"
+BIN_MODE=0755
+DATA_MODE=0644
+DIR_MODE=0755
+OWNER=root
+
+if [ -z $1 ]
+then
+    MAKEOPTS="-j1"
+else
+    if [ "$1" = "debug" ]
+    then
+        DEFS="-DDEBUG"
+        MAKEOPTS="-j1"
+        CXXFLAGS="$CXXFLAGS -g3 -W -Wall"
+    else
+        MAKEOPTS="-j1"
+    fi
+fi
+
+CXXFLAGS="$CXXFLAGS -I/usr/local/include"
+LDFLAGS="$CXXFLAGS -L/usr/local/lib"
+
+if [ "$sys" = "Linux" ]
+then
+    OS=linux
+    release=""
+    MAKE="make"
+fi
+
+if [ "$sys" = "FreeBSD" ]
+then
+    case $release in
+        4) OS=bsd;;
+        5) OS=bsd5;;
+        6) OS=bsd5;;
+        7) OS=bsd7;;
+        8) OS=bsd7;;
+        *) OS=unknown;;
+    esac
+    MAKE="gmake"
+fi
+
+if [ "$OS" = "unknown" ]
+then 
+    echo "################################################################################"
+    echo "# Sorry, but sgauthstress currently supported by Linux, FreeBSD 4.x-8.x        #"
+    echo "################################################################################"
+    exit 1
+fi
+
+echo "#############################################################################"
+echo "       Building sgauthstress for $sys $release"
+echo "#############################################################################"
+
+STG_LIBS="logger.lib
+          locker.lib
+          crypto.lib 
+         common.lib 
+          dotconfpp.lib
+         ia.lib"
+
+PLUGINS="store/files"
+
+if [ "$OS" = "linux" ]
+then
+    DEFS="$DEFS -DLINUX"
+    LIB_THREAD=-lpthread
+    SHELL="/bin/bash"
+else
+    if [ "$OS" = "bsd" ]
+    then
+        DEFS="$DEFS -DFREE_BSD"
+        LIB_THREAD=-lc_r
+    else
+        DEFS="$DEFS -DFREE_BSD5"
+        if [ "$OS" = "bsd7" ]
+        then
+            LIB_THREAD=-lpthread
+        else
+            LIB_THREAD=-lc_r
+        fi
+    fi
+    SHELL="/usr/local/bin/bash"
+fi
+
+echo -n "Checking gcc... "
+gcc --version > /dev/null 2> /dev/null
+if [ $? != 0 ]
+then
+    echo "FAIL!"
+    echo "gcc not found"
+    exit;
+fi
+echo "found"
+echo -n "Checking g++... "
+g++ --version > /dev/null 2> /dev/null
+if [ $? != 0 ]
+then
+    echo "FAIL!"
+    echo "g++ not found"
+    exit;
+fi
+echo "found"
+
+echo -n "Checking endianess... "
+echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+gcc $CXXFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
+if [ $? != 0 ]
+then
+    echo "FAIL!"
+    echo "Endianess checking failed"
+    exit;
+else
+    ./fake
+    if [ $? = 1 ]
+    then
+        ARCH=le
+        CXXFLAGS="$CXXFLAGS -DARCH_LE"
+        echo "Little Endian"
+    else
+        ARCH=be
+        CXXFLAGS="$CXXFLAGS -DARCH_BE"
+        echo "Big Endian"
+    fi
+fi
+rm -f fake
+rm -f build_check.c
+
+echo -n "Checking for -lfbclient... "
+gcc $CXXFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
+if [ $? != 0 ]
+then
+    CHECK_FBCLIENT=no
+    echo "no"
+else
+    CHECK_FBCLIENT=yes
+    echo "yes"
+fi
+rm -f fake
+
+echo -n "Checking for mysql_config... "
+MYSQL_VERSION=`mysql_config --version 2> /dev/null`
+if [ $? != 0 ]
+then
+    echo "no";
+    echo -n "Checking for -lmysqlclient... "
+    gcc $CXXFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
+    if [ $? != 0 ]
+    then
+        CHECK_MYSQLCLIENT=no
+        echo "no"
+    else
+        CHECK_MYSQLCLIENT=yes
+        echo "yes"
+    fi
+    rm -f fake
+else
+    echo "yes"
+    echo -n "Checking for mysql_config --cflags... "
+    MYSQL_CFLAGS=`mysql_config --cflags 2> /dev/null`
+    if [ $? != 0 ]
+    then
+        CHECK_MYSQLCLIENT=no
+        echo "no"
+    else
+        #CXXFLAGS="$CXXFLAGS $MYSQL_CFLAGS"
+        echo "[$MYSQL_CFLAGS]"
+        echo -n "Checking for mysql_config --libs_r... "
+        MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
+        if [ $? != 0 ]
+        then
+            CHECK_MYSQLCLIENT=no
+            echo "no"
+        else
+            CHECK_MYSQLCLIENT=yes
+            #LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS"
+            echo "[$MYSQL_LDFLAGS]"
+        fi
+    fi
+fi
+
+echo -n "Checking for pg_config... "
+PG_VERSION=`pg_config --version 2> /dev/null`
+if [ $? != 0 ]
+then
+    echo "no";
+    echo -n "Checking for -lpq... "
+    gcc $CXXFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
+    if [ $? != 0 ]
+    then
+        CHECK_PQ=no
+        echo "no"
+    else
+        CHECK_PQ=yes
+        echo "yes"
+    fi
+    rm -f fake
+else
+    echo "yes";
+    echo -n "Checking for pg_config --includedir... "
+    PG_CFLAGS=`pg_config --includedir 2> /dev/null`
+    if [ $? != 0 ]
+    then
+        CHECK_PQ=no
+        echo "no"
+    else
+        echo "[$PG_CFLAGS]"
+        echo -n "Checking for pg_config --libdir... "
+        PG_LDFLAGS=`pg_config --libdir 2> /dev/null`
+        if [ $? != 0 ]
+        then
+            CHECK_PQ=no
+            echo "no"
+        else
+            CHECK_PQ=yes
+            echo "[$PG_LDFLAGS]"
+        fi
+    fi
+fi
+
+rm -f build_check.c
+
+if [ "$CHECK_FBCLIENT" = "yes" ]
+then
+    STG_LIBS="$STG_LIBS
+          ibpp.lib"
+    PLUGINS="$PLUGINS
+         store/firebird"
+fi
+
+if [ "$CHECK_PQ" = "yes" ]
+then
+    PLUGINS="$PLUGINS
+             store/postgresql"
+fi
+
+if [ "$CHECK_MYSQLCLIENT" = "yes" ]
+then
+    PLUGINS="$PLUGINS
+         store/mysql"
+fi
+
+echo "OS=$OS" > $CONFFILE
+echo "STG_TIME=yes" >> $CONFFILE
+echo "DIR_BUILD=$BUILD_DIR" >> $CONFFILE
+echo "DIR_LIB=\$(DIR_BUILD)/../../lib" >> $CONFFILE
+echo "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs" >> $CONFFILE
+echo "DIR_INCLUDE=\$(DIR_BUILD)/../../include" >> $CONFFILE
+echo "DIR_MOD=\$(DIR_BUILD)/../stargazer/modules" >> $CONFFILE
+echo "DIR_PLUGINS=\$(DIR_BUILD)/../stargazer/plugins" >> $CONFFILE
+echo "ARCH=$ARCH" >> $CONFFILE
+echo "DEFS=$DEFS" >> $CONFFILE
+echo -n "STG_LIBS=" >> $CONFFILE
+for lib in $STG_LIBS
+do
+    echo -n "$lib " >> $CONFFILE
+done
+echo "" >> $CONFFILE
+echo -n "PLUGINS=" >> $CONFFILE
+for plugin in $PLUGINS
+do
+    echo -n "$plugin " >> $CONFFILE
+done
+echo "" >> $CONFFILE
+echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
+echo "SHELL=$SHELL" >> $CONFFILE
+echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
+echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
+echo "PREFIX=$PREFIX" >> $CONFFILE
+echo "BIN_MODE=$BIN_MODE" >> $CONFFILE
+echo "DATA_MODE=$DATA_MODE" >> $CONFFILE
+echo "DIR_MODE=$DIR_MODE" >> $CONFFILE
+echo "OWNER=$OWNER" >> $CONFFILE
+$MAKE $MAKEOPTS
diff --git a/projects/sgauthstress/main.cpp b/projects/sgauthstress/main.cpp
new file mode 100644 (file)
index 0000000..96c5820
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ *    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
+ */
+
+/*
+ *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.13 $
+ $Date: 2010/04/14 09:01:29 $
+ $Author: faust $
+ */
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <csignal>
+#include <cstdio>
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+#include "stg/ia.h"
+#include "stg/common.h"
+#include "web.h"
+#include "settings_impl.h"
+
+int mes;
+char infoText[256];
+char messageText[256];
+
+const int winKOI = 0;
+
+IA_CLIENT_PROT * clnp;
+WEB * web = NULL;
+
+using namespace std;
+
+time_t stgTime;
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+void Usage()
+{
+printf("sgauth <path_to_config>\n");
+}
+//-----------------------------------------------------------------------------
+void SetDirName(const vector<string> & dn, void *)
+{
+for (int j = 0; j < DIR_NUM; j++)
+    {
+    if (winKOI)
+        {
+        string dir;
+        KOIToWin(dn[j], &dir);
+        if (web)
+            web->SetDirName(dir, j);
+        }
+    else
+        {
+        if (web)
+            web->SetDirName(dn[j], j);
+        }
+    }
+}
+//-----------------------------------------------------------------------------
+void StatUpdate(const LOADSTAT & ls, void *)
+{
+if (web)
+    web->UpdateStat(ls);
+}
+//-----------------------------------------------------------------------------
+void StatusChanged(int, void *)
+{
+}
+//-----------------------------------------------------------------------------
+void ShowMessage(const string & message, int i, int, int, void *)
+{
+if (web)
+    web->AddMessage(message, i);
+}
+//-----------------------------------------------------------------------------
+void ShowError(const string & message, int, void *)
+{
+if (web)
+     web->AddMessage(message, 0);
+}
+//-----------------------------------------------------------------------------
+void CatchUSR1(int)
+{
+if (clnp->GetAuthorized())
+    {
+    cout << "Connect" << endl;
+    clnp->Connect();
+    }
+}
+//-----------------------------------------------------------------------------
+void CatchUSR2(int)
+{
+cout << "Disconnect" << endl;
+clnp->Disconnect();
+}
+//-----------------------------------------------------------------------------
+void CatchTERM(int)
+{
+cout << "Terminated" << endl;
+clnp->Disconnect();
+sleep(2);
+exit(0);
+}
+//-----------------------------------------------------------------------------
+static void SetSignalHandlers()
+{
+struct sigaction newsa, oldsa;
+sigset_t sigmask;
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGTERM);
+newsa.sa_handler = CatchTERM;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGTERM, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGINT);
+newsa.sa_handler = CatchTERM;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGINT, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGUSR1);
+newsa.sa_handler = CatchUSR1;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGUSR1, &newsa, &oldsa);
+
+sigemptyset(&sigmask);
+sigaddset(&sigmask, SIGUSR2);
+newsa.sa_handler = CatchUSR2;
+newsa.sa_mask = sigmask;
+newsa.sa_flags = 0;
+sigaction(SIGUSR2, &newsa, &oldsa);
+
+return;
+}
+//-----------------------------------------------------------------------------
+int main(int argc, char *argv[])
+{
+SETTINGS_IMPL settings;
+
+if (argc == 2)
+    {
+    settings.SetConfFile(argv[1]);
+    }
+else
+    {
+    // Usage
+    }
+
+if (settings.ReadSettings())
+    {
+    printf("ReadSettingsError\n");
+    printf("%s\n", settings.GetStrError().c_str());
+    exit(-1);
+    }
+settings.Print();
+
+if (settings.GetDaemon())
+    {
+    switch (fork())
+        {
+        case -1:
+            exit(1);
+            break;
+
+        case 0:
+            setsid();
+            break;
+
+        default:
+            exit(0);
+            break;
+        }
+    }
+
+clnp = new IA_CLIENT_PROT(settings.GetServerName(), settings.GetServerPort(), settings.GetLocalPort());
+
+if (!settings.GetNoWeb())
+    {
+    web = new WEB();
+    web->SetRefreshPagePeriod(settings.GetRefreshPeriod());
+    web->SetListenAddr(settings.GetListenWebIP());
+    web->Start();
+    }
+
+clnp->SetLogin(settings.GetLogin());
+clnp->SetPassword(settings.GetPassword());
+
+clnp->SetStatusChangedCb(StatusChanged, NULL);
+clnp->SetInfoCb(ShowMessage, NULL);
+clnp->SetErrorCb(ShowError, NULL);
+clnp->SetDirNameCb(SetDirName, NULL);
+clnp->SetStatChangedCb(StatUpdate, NULL);
+clnp->SetReconnect(settings.GetReconnect());
+
+clnp->Start();
+
+SetSignalHandlers();
+
+#ifdef LINUX
+for (int i = 1; i < argc; i++)
+    memset(argv[i], 0, strlen(argv[i]));
+
+if(argc > 1)
+    strcpy(argv[1], "Connecting...");
+#endif
+
+#ifdef FREEBSD
+setproctitle("Connecting...");
+#endif
+clnp->Connect();
+
+while (1)
+    {
+    usleep(200000);
+
+    char state[20];
+
+    if (clnp->GetAuthorized())
+        {
+        if (settings.GetShowPid())
+            sprintf(state, "On %d", getpid());
+        else
+            strcpy(state, "Online");
+        }
+    else
+        {
+        if (settings.GetShowPid())
+            sprintf(state, "Off %d", getpid());
+        else
+            strcpy(state, "Offline");
+        }
+
+    #ifdef LINUX
+    for (int i = 1; i < argc; i++)
+        memset(argv[i], 0, strlen(argv[i]));
+    if(argc > 1)
+        strcpy(argv[1], state);
+    #endif
+
+    #ifdef FREEBSD
+    setproctitle(state);
+    #endif
+
+    #ifdef FREEBSD_5
+    setproctitle(state);
+    #endif
+    }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
diff --git a/projects/sgauthstress/settings_impl.cpp b/projects/sgauthstress/settings_impl.cpp
new file mode 100644 (file)
index 0000000..c203ca3
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *    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
+ */
+
+/*
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include <cstring>
+
+#include "stg/dotconfpp.h"
+#include "stg/module_settings.h"
+#include "stg/common.h"
+
+#include "settings_impl.h"
+
+SETTINGS_IMPL::SETTINGS_IMPL()
+    : port(0),
+      localPort(0),
+      listenWebIP(0),
+      refreshPeriod(0),
+      daemon(false),
+      noWeb(false),
+      reconnect(false),
+      showPid(false),
+      confFile("/etc/sgauth.conf")
+{
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseYesNo(const string & value, bool * val)
+{
+if (0 == strcasecmp(value.c_str(), "yes"))
+    {
+    *val = true;
+    return 0;
+    }
+if (0 == strcasecmp(value.c_str(), "no"))
+    {
+    *val = false;
+    return 0;
+    }
+
+strError = "Incorrect value \'" + value + "\'.";
+return -1;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseInt(const string & value, int * val)
+{
+if (str2x<int>(value, *val))
+    {
+    strError = "Cannot convert \'" + value + "\' to integer.";
+    return -1;
+    }
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseUnsigned(const string & value, unsigned * val)
+{
+if (str2x<unsigned>(value, *val))
+    {
+    strError = "Cannot convert \'" + value + "\' to unsigned integer.";
+    return -1;
+    }
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseIntInRange(const string & value, int min, int max, int * val)
+{
+if (ParseInt(value, val) != 0)
+    return -1;
+
+if (*val < min || *val > max)
+    {
+    strError = "Value \'" + value + "\' out of range.";
+    return -1;
+    }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseUnsignedInRange(const string & value, unsigned min, unsigned max, unsigned * val)
+{
+if (ParseUnsigned(value, val) != 0)
+    return -1;
+
+if (*val < min || *val > max)
+    {
+    strError = "Value \'" + value + "\' out of range.";
+    return -1;
+    }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ParseModuleSettings(const DOTCONFDocumentNode * node, std::vector<PARAM_VALUE> * params)
+{
+if (!node)
+    return 0;
+
+PARAM_VALUE pv;
+
+pv.param = node->getName();
+
+if (node->getValue(1))
+    {
+    strError = "Unexpected value \'" + std::string(node->getValue(1)) + "\'.";
+    printfd(__FILE__, "SETTINGS_IMPL::ParseModuleSettings() - %s\n", strError.c_str());
+    return -1;
+    }
+
+const char * value = node->getValue(0);
+
+if (!value)
+    {
+    strError = "Module name expected.";
+    printfd(__FILE__, "SETTINGS_IMPL::ParseModuleSettings() - %s\n", strError.c_str());
+    return -1;
+    }
+
+const DOTCONFDocumentNode * childNode = node->getChildNode();
+while (childNode)
+    {
+    pv.param = childNode->getName();
+    int i = 0;
+    while ((value = childNode->getValue(i)) != NULL)
+        {
+        pv.value.push_back(value);
+        ++i;
+        }
+    params->push_back(pv);
+    pv.value.clear();
+    childNode = childNode->getNextNode();
+    }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int SETTINGS_IMPL::ReadSettings()
+{
+const char * requiredOptions[] = {
+    "ModulesPath",
+    "StoreModule",
+    "Login",
+    "Password",
+    "ServerName",
+    "ServerPort"
+    NULL
+    };
+int storeModulesCount = 0;
+
+DOTCONFDocument conf(DOTCONFDocument::CASEINSENSITIVE);
+conf.setRequiredOptionNames(requiredOptions);
+
+if(conf.setContent(confFile.c_str()) != 0)
+    {
+    strError = "Cannot read file " + confFile + ".";
+    printfd(__FILE__, "SETTINGS_IMPL::ReadSettings() - %s\n", strError.c_str());
+    return -1;
+    }
+
+const DOTCONFDocumentNode * node = conf.getFirstNode();
+
+while (node)
+    {
+    if (strcasecmp(node->getName(), "ModulesPath") == 0)
+        {
+        modulesPath = node->getValue(0);
+        }
+
+    if (strcasecmp(node->getName(), "StoreModule") == 0)
+        {
+        if (node->getValue(1))
+            {
+            strError = "Unexpected \'" + std::string(node->getValue(1)) + "\'.";
+            printfd(__FILE__, "SETTINGS_IMPL::ReadSettings() - %s\n", strError.c_str());
+            return -1;
+            }
+
+        if (storeModulesCount)
+            {
+            strError = "Should be only one source StoreModule.";
+            printfd(__FILE__, "SETTINGS_IMPL::ReadSettings() - %s\n", strError.c_str());
+            return -1;
+            }
+        ++storeModulesCount;
+
+        storeModuleSettings.moduleName = node->getValue(0);
+        ParseModuleSettings(node, &storeModuleSettings.moduleParams);
+        }
+
+    node = node->getNextNode();
+    }
+
+CONFIGFILE cf(confFile);
+
+if (cf.Error())
+    {
+    strError = "Cannot read file '" + confFile + "'";
+    return -1;
+    }
+
+cf.ReadString("Login", &login, "/?--?--?*");
+if (login == "/?--?--?*")
+    {
+    strError = "Parameter 'Login' not found.";
+    return -1;
+    }
+
+cf.ReadString("Password", &password, "/?--?--?*");
+if (login == "/?--?--?*")
+    {
+    strError = "Parameter 'Password' not found.";
+    return -1;
+    }
+
+cf.ReadString("ServerName", &serverName, "?*?*?");
+if (serverName == "?*?*?")
+    {
+    strError = "Parameter 'ServerName' not found.";
+    return -1;
+    }
+
+cf.ReadString("ServerPort", &temp, "5555");
+if (ParseIntInRange(temp, 1, 65535, &port))
+    {
+    strError = "Parameter 'ServerPort' is not valid.";
+    return -1;
+    }
+
+cf.ReadString("LocalPort", &temp, "0");
+if (ParseIntInRange(temp, 0, 65535, &localPort))
+    {
+    strError = "Parameter 'LocalPort' is not valid.";
+    return -1;
+    }
+
+return 0;
+}
diff --git a/projects/sgauthstress/settings_impl.h b/projects/sgauthstress/settings_impl.h
new file mode 100644 (file)
index 0000000..8035aba
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *    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
+ */
+
+/*
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef SETTINGS_IMPL_H
+#define SETTINGS_IMPL_H
+
+#include <string>
+#include <vector>
+
+#include "stg/os_int.h"
+
+struct MODULE_SETTINGS;
+class DOTCONFDocumentNode;
+
+class SETTINGS_IMPL {
+public:
+                        SETTINGS_IMPL();
+                        ~SETTINGS_IMPL() {}
+    int                 Reload() { return 0; }
+    void                SetConfFile(const std::string cf) { confFile = cf; }
+    int                 ReadSettings();
+
+    const std::string & GetStrError() const { return strError; }
+
+    const std::string & GetServerName() const { return serverName; }
+    uint16_t            GetServerPort() const { return port; }
+    uint16_t            GetLocalPort() const { return localPort; }
+
+    const std::string & GetLogin() const { return login; }
+    const std::string & GetPassword() const { return password; }
+
+    const std::string & GetConfDir() const;
+    const std::string & GetModulesPath() const { return modulesPath; }
+    const MODULE_SETTINGS & GetStoreModuleSettings() const { return storeModuleSettings; }
+
+private:
+    int ParseInt(const std::string & value, int * val);
+    int ParseUnsigned(const std::string & value, unsigned * val);
+    int ParseIntInRange(const std::string & value, int min, int max, int * val);
+    int ParseUnsignedInRange(const std::string & value, unsigned min, unsigned max, unsigned * val);
+    int ParseYesNo(const std::string & value, bool * val);
+    int ParseModuleSettings(const DOTCONFDocumentNode * dirNameNode, std::vector<PARAM_VALUE> * params);
+
+    std::string login;
+    std::string password;
+    std::string serverName;
+    int         port;
+    int         localPort;
+
+    std::string confFile;
+    std::string strError;
+    std::string modulesPath;
+
+    MODULE_SETTINGS storeModuleSettings;
+};
+
+#endif
diff --git a/projects/sgauthstress/sgauth.conf b/projects/sgauthstress/sgauth.conf
new file mode 100644 (file)
index 0000000..0368ec0
--- /dev/null
@@ -0,0 +1,37 @@
+#Stargazer server ip
+ServerName=192.168.1.2
+
+#Stargazer server port
+#Default value 5555
+ServerPort=5555
+
+#User's login
+Login=test
+
+#
+#
+LocalPort=12345
+
+#User's password
+Password=1234567
+
+#
+#Default value yes
+#Reconnect=no
+
+#
+#Default value yes
+#Daemon=yes
+
+#Refresh web page period
+#Default value 10
+#RefreshPeriod=10
+
+#
+#Default value 127.0.0.1
+ListenWebIP=127.0.0.1
+
+#Default value no
+DisableWeb=no
+
+#ShowPid=no
diff --git a/projects/sgauthstress/store_loader.cpp b/projects/sgauthstress/store_loader.cpp
new file mode 100644 (file)
index 0000000..c54bdb3
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ *    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
+ */
+
+/*
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.6 $
+ $Date: 2010/03/04 12:24:19 $
+ $Author: faust $
+ */
+
+/*
+ *  An implementation of RAII store plugin loader
+ */
+
+#include <dlfcn.h>
+
+#include "stg/common.h"
+#include "stg/store.h"
+#include "store_loader.h"
+#include "settings_impl.h"
+
+STORE_LOADER::STORE_LOADER(const SETTINGS_IMPL & settings)
+    : isLoaded(false),
+      handle(NULL),
+      plugin(NULL),
+      errorStr(),
+      storeSettings(settings.GetStoreModuleSettings()),
+      pluginFileName(settings.GetModulesPath() + "/mod_" + storeSettings.moduleName + ".so")
+{
+}
+
+STORE_LOADER::~STORE_LOADER()
+{
+Unload();
+}
+
+bool STORE_LOADER::Load()
+{
+if (isLoaded)
+    {
+    errorStr = "Store plugin '" + pluginFileName + "' was already loaded!";
+    printfd(__FILE__, "STORE_LOADER::Load() - %s\n", errorStr.c_str());
+    return false;
+    }
+
+if (pluginFileName.empty())
+    {
+    errorStr = "Empty store plugin filename";
+    printfd(__FILE__, "STORE_LOADER::Load() - %s\n", errorStr.c_str());
+    return true;
+    }
+
+handle = dlopen(pluginFileName.c_str(), RTLD_NOW);
+
+if (!handle)
+    {
+    errorStr = "Error loading plugin '"
+        + pluginFileName + "': '" + dlerror() + "'";
+    printfd(__FILE__, "STORE_LOADER::Load() - %s\n", errorStr.c_str());
+    return true;
+    }
+
+isLoaded = true;
+
+STORE * (*GetStore)();
+GetStore = (STORE * (*)())dlsym(handle, "GetStore");
+if (!GetStore)
+    {
+    errorStr = std::string("GetStore() not found! ") + dlerror();
+    printfd(__FILE__, "STORE_LOADER::Load() - %s\n", errorStr.c_str());
+    return true;
+    }
+
+plugin = GetStore();
+
+if (!plugin)
+    {
+    errorStr = "Plugin was not created!";
+    printfd(__FILE__, "STORE_LOADER::Load() - %s\n");
+    return true;
+    }
+
+plugin->SetSettings(storeSettings);
+if (plugin->ParseSettings())
+    {
+    errorStr = plugin->GetStrError();
+    printfd(__FILE__, "STORE_LOADER::Load() - Failed to parse settings. Plugin reports: '%s'\n", errorStr.c_str());
+    return true;
+    }
+
+return false;
+}
+
+bool STORE_LOADER::Unload()
+{
+printfd(__FILE__, "STORE_LOADER::Unload()\n");
+if (!isLoaded)
+    {
+    return true;
+    }
+
+if (dlclose(handle))
+    {
+    errorStr = "Failed to unload plugin '";
+    errorStr += pluginFileName + "': ";
+    errorStr += dlerror();
+    printfd(__FILE__, "STORE_LOADER::Unload() - %s\n", errorStr.c_str());
+    return true;
+    }
+
+isLoaded = false;
+
+return false;
+}
diff --git a/projects/sgauthstress/store_loader.h b/projects/sgauthstress/store_loader.h
new file mode 100644 (file)
index 0000000..c7911ee
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *    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
+ */
+
+/*
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.3 $
+ $Date: 2010/03/04 12:24:19 $
+ $Author: faust $
+ */
+
+/*
+ *  Header file for RAII store plugin loader
+ */
+
+#ifndef __STORE_LOADER_H__
+#define __STORE_LOADER_H__
+
+#include <string>
+
+#include "stg/module_settings.h"
+#include "stg/noncopyable.h"
+
+class STORE;
+class SETTINGS_IMPL;
+
+class STORE_LOADER : private NONCOPYABLE {
+public:
+    STORE_LOADER(const SETTINGS_IMPL & settings);
+    ~STORE_LOADER();
+
+    bool Load();
+    bool Unload();
+
+    STORE * GetStore() { return plugin; }
+
+    const std::string & GetStrError() const { return errorStr; }
+private:
+    bool isLoaded;
+    void * handle;
+    STORE * plugin;
+    std::string errorStr;
+    MODULE_SETTINGS storeSettings;
+    std::string pluginFileName;
+};
+
+#endif