]> git.stg.codes - stg.git/commitdiff
Search parameter in map case insensitive
authorNaffanya <naffanya@naffanya.(none)>
Wed, 29 Jan 2014 21:04:05 +0000 (23:04 +0200)
committerNaffanya <naffanya@naffanya.(none)>
Wed, 29 Jan 2014 21:04:05 +0000 (23:04 +0200)
138 files changed:
doc/xmlrpc/API-tariffs.xml
doc/xmlrpc/API-user.xml
include/stg/admin_conf.h
include/stg/const.h
include/stg/corp_conf.h
include/stg/corporations.h
include/stg/os_int.h
include/stg/resetable.h
include/stg/service_conf.h
include/stg/services.h
include/stg/tariff.h
include/stg/tariff_conf.h
include/stg/user.h
include/stg/user_conf.h
include/stg/user_ips.h
include/stg/user_property.h
include/stg/user_stat.h
include/stg/user_traff.h
include/stg/users.h
include/stg/utime.h
projects/rlm_stg/build
projects/rscriptd/build
projects/sgauth/build
projects/sgauthstress/build
projects/sgconf/Makefile
projects/sgconf/action.h [new file with mode: 0644]
projects/sgconf/actions.cpp [new file with mode: 0644]
projects/sgconf/actions.h [new file with mode: 0644]
projects/sgconf/build
projects/sgconf/common_sg.cpp
projects/sgconf/common_sg.h
projects/sgconf/config.h [new file with mode: 0644]
projects/sgconf/main.cpp
projects/sgconf/options.cpp [new file with mode: 0644]
projects/sgconf/options.h [new file with mode: 0644]
projects/sgconf/parser_state.h [new file with mode: 0644]
projects/sgconf/request.h
projects/sgconf_xml/build
projects/sgconv/build
projects/stargazer/Makefile
projects/stargazer/build
projects/stargazer/inst/freebsd/etc/stargazer/conf-available.d/mod_ia.conf
projects/stargazer/inst/linux/etc/stargazer/conf-available.d/mod_ia.conf
projects/stargazer/inst/var/01-alter-02.mysql.sql [new file with mode: 0644]
projects/stargazer/inst/var/01-alter-02.postgresql.sql [new file with mode: 0644]
projects/stargazer/inst/var/01-alter-02.sql [new file with mode: 0644]
projects/stargazer/main.cpp
projects/stargazer/plugins/Makefile.in
projects/stargazer/plugins/authorization/ao/Makefile
projects/stargazer/plugins/authorization/inetaccess/inetaccess.cpp
projects/stargazer/plugins/authorization/inetaccess/inetaccess.h
projects/stargazer/plugins/capture/ether_freebsd/ether_cap.cpp
projects/stargazer/plugins/configuration/rpcconfig/rpcconfig.cpp
projects/stargazer/plugins/configuration/rpcconfig/tariff_helper.cpp
projects/stargazer/plugins/configuration/rpcconfig/user_helper.cpp
projects/stargazer/plugins/configuration/rpcconfig/user_helper.h
projects/stargazer/plugins/configuration/rpcconfig/users_methods.cpp
projects/stargazer/plugins/configuration/rpcconfig/users_methods.h
projects/stargazer/plugins/configuration/sgconfig/Makefile
projects/stargazer/plugins/configuration/sgconfig/configproto.cpp
projects/stargazer/plugins/configuration/sgconfig/configproto.h
projects/stargazer/plugins/configuration/sgconfig/parser.cpp
projects/stargazer/plugins/configuration/sgconfig/parser.h
projects/stargazer/plugins/configuration/sgconfig/parser_admin.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.cpp [new file with mode: 0644]
projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.h [new file with mode: 0644]
projects/stargazer/plugins/configuration/sgconfig/parser_tariff.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_user_info.cpp [new file with mode: 0644]
projects/stargazer/plugins/configuration/sgconfig/parser_user_info.h [new file with mode: 0644]
projects/stargazer/plugins/configuration/sgconfig/rsconf.cpp
projects/stargazer/plugins/other/rscript/rscript.cpp
projects/stargazer/plugins/other/smux/smux.cpp
projects/stargazer/plugins/store/files/file_store.cpp
projects/stargazer/plugins/store/firebird/firebird_store.cpp
projects/stargazer/plugins/store/firebird/firebird_store.h
projects/stargazer/plugins/store/firebird/firebird_store_tariffs.cpp
projects/stargazer/plugins/store/firebird/firebird_store_users.cpp
projects/stargazer/plugins/store/mysql/mysql_store.cpp
projects/stargazer/plugins/store/mysql/mysql_store.h
projects/stargazer/plugins/store/postgresql/postgresql_store.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store_users.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store_utils.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store_utils.h [deleted file]
projects/stargazer/tariff_impl.h
projects/stargazer/traffcounter_impl.cpp
projects/stargazer/user_impl.cpp
projects/stargazer/user_impl.h
projects/stargazer/user_property.cpp
projects/stargazer/users_impl.cpp
projects/stargazer/users_impl.h
stglibs/common.lib/common.cpp
stglibs/common.lib/include/stg/common.h
stglibs/crypto.lib/include/stg/blowfish.h
stglibs/pinger.lib/include/stg/pinger.h
stglibs/scriptexecuter.lib/include/stg/scriptexecuter.h
stglibs/scriptexecuter.lib/scriptexecuter.c
stglibs/srvconf.lib/Makefile
stglibs/srvconf.lib/include/stg/netunit.h [deleted file]
stglibs/srvconf.lib/include/stg/servconf.h
stglibs/srvconf.lib/include/stg/servconf_types.h [new file with mode: 0644]
stglibs/srvconf.lib/netunit.cpp
stglibs/srvconf.lib/netunit.h [new file with mode: 0644]
stglibs/srvconf.lib/parser.cpp [deleted file]
stglibs/srvconf.lib/parsers/auth_by.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/auth_by.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/base.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_admin.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_admin.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_corp.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_corp.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_service.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_service.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_tariff.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_tariff.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_user.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/chg_user.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_admin.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_admin.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_container.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_corp.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_corp.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_service.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_service.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_tariff.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_tariff.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_user.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/get_user.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/property.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/property.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/resetable_utils.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/server_info.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/server_info.h [new file with mode: 0644]
stglibs/srvconf.lib/parsers/simple.cpp [new file with mode: 0644]
stglibs/srvconf.lib/parsers/simple.h [new file with mode: 0644]
stglibs/srvconf.lib/servconf.cpp
stglibs/srvconf.lib/servconf.vpj [deleted file]
stglibs/srvconf.lib/servconf.vpw [deleted file]

index d36b01dda869a561907cdf65b3b2779bf464d071..9b84889aee87560161d650904d0485c9ad5e9e5c 100644 (file)
                                 </para>
                             </listitem>
                         </varlistentry>
+                        <varlistentry>
+                            <term>string <parameter>period</parameter></term>
+                            <listitem>
+                                <para>Периодичность снятия абонплаты:
+                                    <simplelist type="vert">
+                                        <member>month &#151; ежемесячное снятие</member>
+                                        <member>day &#151; ежедневное снятие</member>
+                                    </simplelist>
+                                </para>
+                            </listitem>
+                        </varlistentry>
                         <varlistentry>
                             <term>array of struct <parameter>dirprices</parameter></term>
                             <listitem>
                                 </para>
                             </listitem>
                         </varlistentry>
+                        <varlistentry>
+                            <term>string <parameter>period</parameter></term>
+                            <listitem>
+                                <para>Периодичность снятия абонплаты:
+                                    <simplelist type="vert">
+                                        <member>month &#151; ежемесячное снятие</member>
+                                        <member>day &#151; ежедневное снятие</member>
+                                    </simplelist>
+                                </para>
+                            </listitem>
+                        </varlistentry>
                         <varlistentry>
                             <term>array of struct <parameter>dirprices</parameter></term>
                             <listitem>
                                         </para>
                                     </listitem>
                                 </varlistentry>
+                                <varlistentry>
+                                    <term>string <parameter>period</parameter></term>
+                                    <listitem>
+                                        <para>Периодичность снятия абонплаты:
+                                            <simplelist type="vert">
+                                                <member>month &#151; ежемесячное снятие</member>
+                                                <member>day &#151; ежедневное снятие</member>
+                                            </simplelist>
+                                        </para>
+                                    </listitem>
+                                </varlistentry>
                                 <varlistentry>
                                     <term>array of struct <parameter>dirprices</parameter></term>
                                     <listitem>
index fac4f2be8b597e2d3a7354b99842cd7d23a0e021..82f8e7eeb1950d5a19ed9d74402b1ecf1fe50358 100644 (file)
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.add_user_cash"><function>stargazer.add_user_cash</function></link>,
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.add_user_cash"><function>stargazer.add_user_cash</function></link>,
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>
                 <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
             </para>
         </refsect1>
     </refentry>
                 <link linkend="stargazer.add_user_cash"><function>stargazer.add_user_cash</function></link>,
                 <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>
                 <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
+                <link linkend="stargazer.get_user_auth_by"><function>stargazer.get_user_auth_by</function></link>
+            </para>
+        </refsect1>
+    </refentry>
+    <refentry id="stargazer.get_user_auth_by">
+        <refmeta>
+            <refentrytitle>stargazer.get_user_auth_by</refentrytitle>
+        </refmeta>
+        <refnamediv>
+            <refname>stargazer.get_user_auth_by</refname>
+            <refpurpose>Получение списка авторизаторов которыми авторизован пользователь</refpurpose>
+        </refnamediv>
+        <refsynopsisdiv>
+            <funcsynopsis>
+                <funcprototype>
+                    <funcdef><function>stargazer.get_user_auth_by</function></funcdef>
+                    <paramdef>string <parameter>cookie</parameter></paramdef>
+                    <paramdef>string <parameter>login</parameter></paramdef>
+                </funcprototype>
+            </funcsynopsis>
+        </refsynopsisdiv>
+        <refsect1>
+            <title>Description</title>
+            <para>Метод <function>stargazer.get_user_auth_by</function> позволяет получить список авторизаторов которыми в данный момент авторизован пользователь.</para>
+            <variablelist>
+                <varlistentry>
+                    <term>string <parameter>cookie</parameter></term>
+                    <listitem>
+                        <para>Авторизационный cookie. Для авторизации в системе используется метод <function><link linkend="stargazer.login">stargazer.login</link></function></para>
+                    </listitem>
+                </varlistentry>
+                <varlistentry>
+                    <term>string <parameter>login</parameter></term>
+                    <listitem>
+                        <para>Логин пользователя</para>
+                    </listitem>
+                </varlistentry>
+            </variablelist>
+            <refsect2>
+                <title>Return Value</title>
+                <para>Возвращает структуру:</para>
+                <variablelist>
+                    <varlistentry>
+                        <term>bool <structfield>result</structfield></term>
+                        <listitem>
+                            <para>Результат операции. true - успешно, false - неудача (неправильный или устаревший cookie).</para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term>array of strings <structfield>auths</structfield></term>
+                        <listitem>
+                            <para>Список авторизаторов которыми авторизован пользователь.</para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </refsect2>
+        </refsect1>
+        <refsect1>
+            <title>See also</title>
+            <para>
+                <link linkend="stargazer.get_users"><function>stargazer.get_users</function></link>,
+                <link linkend="stargazer.get_user"><function>stargazer.get_user</function></link>,
+                <link linkend="stargazer.add_user"><function>stargazer.add_user</function></link>,
+                <link linkend="stargazer.chg_user"><function>stargazer.chg_user</function></link>,
+                <link linkend="stargazer.del_user"><function>stargazer.del_user</function></link>,
+                <link linkend="stargazer.add_user_cash"><function>stargazer.add_user_cash</function></link>,
+                <link linkend="stargazer.set_user_cash"><function>stargazer.set_user_cash</function></link>
+                <link linkend="stargazer.chg_user_tariff"><function>stargazer.chg_user_tariff</function></link>
+                <link linkend="stargazer.get_online_ips"><function>stargazer.get_online_ips</function></link>
             </para>
         </refsect1>
     </refentry>
index df6d9e22456f0f633a804c1311cf25fa7d7dff90..8b1a988e1877ff79c77e73bfd404b67e22710583 100644 (file)
@@ -7,9 +7,10 @@
 #ifndef ADMIN_CONF_H
 #define ADMIN_CONF_H
 
-#include <string>
-
 #include "os_int.h"
+#include "resetable.h"
+
+#include <string>
 
 #define ADM_LOGIN_LEN   (32)
 #define ADM_PASSWD_LEN  (32)
@@ -75,6 +76,29 @@ struct ADMIN_CONF
     std::string   password;
 };
 //-----------------------------------------------------------------------------
+struct ADMIN_CONF_RES
+{
+    ADMIN_CONF_RES(const ADMIN_CONF & conf)
+        : priv(conf.priv),
+          login(conf.login),
+          password(conf.password)
+    {}
+    ADMIN_CONF_RES(const ADMIN_CONF_RES & rhs)
+        : priv(rhs.priv),
+          login(rhs.login),
+          password(rhs.password)
+    {}
+    ADMIN_CONF_RES & operator=(const ADMIN_CONF_RES & rhs)
+    {
+        priv = rhs.priv;
+        login = rhs.login;
+        password = rhs.password;
+        return *this;
+    }
+    RESETABLE<PRIV> priv;
+    RESETABLE<std::string> login;
+    RESETABLE<std::string> password;
+};
 
 #include "admin_conf.inc.h"
 
index e882200df1c1783d2280088c4a79d21349c7987b..55f5b54bc9e6102f9cc1cb7f82e2aa5981964585 100644 (file)
@@ -80,8 +80,6 @@
 #define NO_TARIFF_NAME  "*_NO_TARIFF_*"
 #define NO_CORP_NAME    "*_NO_CORP_*"
 
-#define mega (1024 * 1024)
-
 #define MONITOR_TIME_DELAY_SEC  (60)
 
 #endif
index d6cc2ebbe626f5422de591c3f9e47f26d4e97a83..9bbc03d326941e2edce782663cbec4e3cbd15163 100644 (file)
@@ -1,6 +1,28 @@
+/*
+ *    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 CORP_CONF_H
 #define CORP_CONF_H
 
+#include "resetable.h"
+
 #include <string>
 
 struct CORP_CONF
@@ -13,6 +35,31 @@ std::string name;
 double      cash;
 };
 
+struct CORP_CONF_RES
+{
+CORP_CONF_RES()
+    : name(), cash()
+{}
+
+CORP_CONF_RES & operator=(const CORP_CONF & conf)
+{
+name = conf.name;
+cash = conf.cash;
+return *this;
+}
+
+CORP_CONF GetData() const
+{
+CORP_CONF cc;
+cc.name = name.data();
+cc.cash = cash.data();
+return cc;
+}
+
+RESETABLE<std::string> name;
+RESETABLE<double>      cash;
+};
+
 inline
 bool operator==(const CORP_CONF & a, const CORP_CONF & b)
 {
index 2d07c6c659c704a28c532bec285247608e93ac2d..e167301b5d72fa1cf2fdc480ab13ebbf92728759 100644 (file)
 #ifndef CORPORATIONS_H
 #define CORPORATIONS_H
 
-#include <string>
-
 #include "corp_conf.h"
 
+#include <string>
+
 class ADMIN;
 
 class CORPORATIONS {
index cc017b84b8b5624bd1f3389f3b203ea01c8ff4a7..00ab3fad579fd3169be8a3c0aed8b7f28bb6bbd2 100644 (file)
@@ -31,7 +31,7 @@
 #include <stdint.h>
 #endif
 
-#ifdef FREE_BSD5
+#if defined(FREE_BSD5) || defined(DARWIN)
 #include <inttypes.h>
 #endif
 
index f3cecac843b65ba94f85ffc023f945e7c8981c64..c78d02476e5cbea97d9b80acd764a80aad8d1c61 100644 (file)
@@ -1,9 +1,3 @@
- /*
- $Revision: 1.9 $
- $Date: 2010/03/11 14:42:04 $
- $Author: faust $
- */
-
 /*
  * Copyright (c) 2001 by Peter Simons <simons@cryp.to>.
  * All rights reserved.
@@ -15,8 +9,6 @@
 // This is a wrapper class about variables where you want to keep
 // track of whether it has been assigened yet or not.
 
-#include <iostream>
-
 template <typename T>
 class RESETABLE
 {
@@ -24,32 +16,31 @@ public:
     typedef T value_type;
 
     RESETABLE() : value(), is_set(false) {}
+    RESETABLE(const T & v) : value(v), is_set(true) {}
 
-    RESETABLE(const RESETABLE<value_type> & rvalue)
+    RESETABLE(const RESETABLE<T> & rvalue)
         : value(rvalue.value),
           is_set(rvalue.is_set)
     {}
 
-    RESETABLE(const value_type& val) : value(val), is_set(true) {}
-
-    RESETABLE<value_type> & operator=(const RESETABLE<value_type> & rvalue)
+    RESETABLE<T> & operator=(const RESETABLE<T> & rhs)
     {
-        value = rvalue.value;
-        is_set = rvalue.is_set;
+        value = rhs.value;
+        is_set = rhs.is_set;
         return *this;
     }
 
-    RESETABLE<value_type> & operator=(const value_type& rhs)
+    RESETABLE<T> & operator=(const T & rhs)
     {
         value = rhs;
         is_set = true;
         return *this;
     }
 
-    const value_type & const_data() const throw() { return value; }
-    value_type & data() throw() { return value; }
-    operator const value_type&() const throw() { return value; }
-    bool res_empty() const throw() { return !is_set; }
+    const T & const_data() const throw() { return value; }
+    T & data() throw() { return value; }
+    const T & data() const throw() { return value; }
+    bool empty() const throw() { return !is_set; }
     void reset() throw() { is_set = false; }
 
 private:
@@ -57,14 +48,4 @@ private:
     bool       is_set;
 };
 
-template <typename T>
-std::ostream & operator<<(std::ostream & o, const RESETABLE<T> & v);
-
-template <typename T>
-inline
-std::ostream & operator<<(std::ostream & o, const RESETABLE<T> & v)
-{
-    return o << v.const_data();
-}
-
 #endif // RESETABLE_VARIABLE_H
index ca58154b2a08d53612b64f6419f4f6e4cdbcfa6b..473830e44393636b301efdb16cc97a1a926acf99 100644 (file)
@@ -1,10 +1,31 @@
+/*
+ *    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 SERVICE_CONF_H
 #define SERVICE_CONF_H
 
-#include <string>
-
+#include "resetable.h"
 #include "os_int.h"
 
+#include <string>
+
 struct SERVICE_CONF
 {
 SERVICE_CONF()
@@ -30,6 +51,38 @@ double      cost;
 uint8_t     payDay;
 };
 
+struct SERVICE_CONF_RES
+{
+SERVICE_CONF_RES()
+    : name(), comment(),
+      cost(), payDay()
+{}
+
+SERVICE_CONF_RES & operator=(const SERVICE_CONF & conf)
+{
+name = conf.name;
+comment = conf.comment;
+cost = conf.cost;
+payDay = conf.payDay;
+return *this;
+}
+
+SERVICE_CONF GetData() const
+{
+SERVICE_CONF sc;
+sc.name = name.data();
+sc.comment = comment.data();
+sc.cost = cost.data();
+sc.payDay = payDay.data();
+return sc;
+}
+
+RESETABLE<std::string> name;
+RESETABLE<std::string> comment;
+RESETABLE<double>      cost;
+RESETABLE<uint8_t>     payDay;
+};
+
 inline
 bool operator==(const SERVICE_CONF & a, const SERVICE_CONF & b)
 {
index ddec31beb9af61a602a27bb8b8f05ee2956bc34c..8c49f7813b913cfe855526fadefc5e767f851596 100644 (file)
 #ifndef SERVICES_H
 #define SERVICES_H
 
-#include <string>
-
 #include "service_conf.h"
 
+#include <string>
+
 class ADMIN;
 
 class SERVICES {
index a5b1d2e9253ad3a441e283e3409e19c4dd0ae6a4..d0bf20b6dd268ddf0f7b2fa772cedad1e89ebdb1 100644 (file)
 #ifndef TARIFF_H
 #define TARIFF_H
 
-#include <ctime>
+#include "os_int.h"
 
 #include <string>
+#include <cstring>
+#include <ctime>
 
-#include "os_int.h"
-#include "tariff_conf.h"
+struct TARIFF_DATA;
 
 class TARIFF {
 public:
+    enum PERIOD { DAY = 0, MONTH };
+
+    static std::string PeriodToString(PERIOD period);
+    static PERIOD StringToPeriod(const std::string& value);
+
     virtual ~TARIFF() {}
     virtual double  GetPriceWithTraffType(uint64_t up,
                                           uint64_t down,
@@ -39,6 +45,7 @@ public:
     virtual double  GetPassiveCost() const = 0;
     virtual double  GetFee() const = 0;
     virtual double  GetFree() const = 0;
+    virtual PERIOD  GetPeriod() const = 0;
 
     virtual const   std::string & GetName() const = 0;
     virtual void    SetName(const std::string & name) = 0;
@@ -49,4 +56,23 @@ public:
     virtual const TARIFF_DATA & GetTariffData() const = 0;
 };
 
+inline
+std::string TARIFF::PeriodToString(TARIFF::PERIOD period)
+{
+switch (period)
+    {
+    case DAY: return "day";
+    case MONTH: return "month";
+    }
+return "month"; // Classic behaviour.
+}
+
+inline
+TARIFF::PERIOD TARIFF::StringToPeriod(const std::string& value)
+{
+if (strcasecmp(value.c_str(), "day") == 0)
+    return DAY;
+return MONTH; // Classic behaviour.
+}
+
 #endif
index 5b2eebb981b57258ba92863ca4df1718af0ae2b5..6a296230d8413e3b148d3969ffc69992fb115ae2 100644 (file)
 #ifndef TARIFF_CONF_H
 #define TARIFF_CONF_H
 
-#include <string>
-#include <vector>
-
+#include "tariff.h"
 #include "resetable.h"
 #include "const.h"
 
+#include <string>
+#include <vector>
+
 //-----------------------------------------------------------------------------
 enum
 {
@@ -102,21 +103,21 @@ struct DIRPRICE_DATA_RES
         return *this;
         }
 
-    DIRPRICE_DATA GetData()
+    DIRPRICE_DATA GetData() const
         {
         DIRPRICE_DATA dd;
-        dd.hDay        = hDay;
-        dd.hNight      = hNight;
-        dd.mDay        = mDay;
-        dd.mNight      = mNight;
-        dd.noDiscount  = noDiscount;
-        dd.priceDayA   = priceDayA;
-        dd.priceDayB   = priceDayB;
-
-        dd.priceNightA = priceNightA;
-        dd.priceNightB = priceNightB;
-        dd.singlePrice = singlePrice;
-        dd.threshold   = threshold;
+        dd.hDay        = hDay.data();
+        dd.hNight      = hNight.data();
+        dd.mDay        = mDay.data();
+        dd.mNight      = mNight.data();
+        dd.noDiscount  = noDiscount.data();
+        dd.priceDayA   = priceDayA.data();
+        dd.priceDayB   = priceDayB.data();
+
+        dd.priceNightA = priceNightA.data();
+        dd.priceNightB = priceNightB.data();
+        dd.singlePrice = singlePrice.data();
+        dd.threshold   = threshold.data();
         return dd;
         }
 
@@ -135,18 +136,20 @@ struct DIRPRICE_DATA_RES
 //-----------------------------------------------------------------------------
 struct TARIFF_CONF
 {
-    double      fee;
-    double      free;
-    int         traffType;
-    double      passiveCost;
-    std::string name;
+    double         fee;
+    double         free;
+    int            traffType;
+    double         passiveCost;
+    std::string    name;
+    TARIFF::PERIOD period;
 
     TARIFF_CONF()
         : fee(0),
           free(0),
           traffType(TRAFF_UP_DOWN),
           passiveCost(0),
-          name()
+          name(),
+          period(TARIFF::MONTH)
         {}
 
     TARIFF_CONF(const std::string & n)
@@ -154,7 +157,8 @@ struct TARIFF_CONF
           free(0),
           traffType(TRAFF_UP_DOWN),
           passiveCost(0),
-          name(n)
+          name(n),
+          period(TARIFF::MONTH)
         {}
 };
 //-----------------------------------------------------------------------------
@@ -165,7 +169,8 @@ struct TARIFF_CONF_RES
           free(),
           traffType(),
           passiveCost(),
-          name()
+          name(),
+          period()
         {}
 
     TARIFF_CONF_RES & operator=(const TARIFF_CONF & tc)
@@ -175,25 +180,28 @@ struct TARIFF_CONF_RES
         traffType   = tc.traffType;
         passiveCost = tc.passiveCost;
         name        = tc.name;
+        period      = tc.period;
         return *this;
         }
 
-    TARIFF_CONF GetData()
+    TARIFF_CONF GetData() const
         {
         TARIFF_CONF tc;
-        tc.fee         = fee;
-        tc.free        = free;
-        tc.name        = name;
-        tc.passiveCost = passiveCost;
-        tc.traffType   = traffType;
+        tc.fee         = fee.data();
+        tc.free        = free.data();
+        tc.name        = name.data();
+        tc.passiveCost = passiveCost.data();
+        tc.traffType   = traffType.data();
+        tc.period      = period.data();
         return tc;
         }
 
-    RESETABLE<double>      fee;
-    RESETABLE<double>      free;
-    RESETABLE<int>         traffType;
-    RESETABLE<double>      passiveCost;
-    RESETABLE<std::string> name;
+    RESETABLE<double>         fee;
+    RESETABLE<double>         free;
+    RESETABLE<int>            traffType;
+    RESETABLE<double>         passiveCost;
+    RESETABLE<std::string>    name;
+    RESETABLE<TARIFF::PERIOD> period;
 };
 //-----------------------------------------------------------------------------
 struct TARIFF_DATA
@@ -234,7 +242,7 @@ struct TARIFF_DATA_RES
           dirPrice(DIR_NUM)
         {}
 
-    TARIFF_DATA GetData()
+    TARIFF_DATA GetData() const
         {
         TARIFF_DATA td;
         td.tariffConf = tariffConf.GetData();
index b7024859fe5bda31ec3c1e86448cc11a24d393ca..8dc761e35acfb21932c97676faf1cd4dde379915 100644 (file)
 #ifndef USER_H
 #define USER_H
 
-#include <ctime>
-#include <string>
-
-#include "os_int.h"
 #include "notifer.h"
 #include "message.h"
 #include "tariff.h"
 #include "user_traff.h"
+#include "os_int.h"
+
+#include <vector>
+#include <string>
+
+#include <ctime>
 
 class USER_PROPERTIES;
 class AUTH;
@@ -71,12 +73,12 @@ public:
 
     virtual bool                GetConnected() const = 0;
     virtual time_t              GetConnectedModificationTime() const = 0;
+    virtual const std::string & GetLastDisconnectReason() const = 0;
     virtual int                 GetAuthorized() const = 0;
-    /*virtual int                 Authorize(uint32_t ip,
-                                          uint32_t enabledDirs,
-                                          const AUTH * auth) = 0;
-    virtual void                Unauthorize(const AUTH * auth) = 0;*/
+    virtual time_t              GetAuthorizedModificationTime() const = 0;
+
     virtual bool                IsAuthorizedBy(const AUTH * auth) const = 0;
+    virtual std::vector<std::string> GetAuthorizers() const = 0;
 
     virtual int                 AddMessage(STG_MSG * msg) = 0;
 
index 599336583a4ebc159e400e76279b15e12292b9bb..5d65fcee9f606dc053b66a3f66b53bd173b14a43 100644 (file)
@@ -77,7 +77,7 @@ struct USER_CONF_RES
           group(),
           credit(),
           nextTariff(),
-          userdata(USERDATA_NUM, RESETABLE<std::string>()),
+          userdata(USERDATA_NUM),
           creditExpire(),
           ips()
     {
@@ -100,37 +100,34 @@ struct USER_CONF_RES
         group        = uc.group;
         credit       = uc.credit;
         nextTariff   = uc.nextTariff;
-        for (int i = 0; i < USERDATA_NUM; i++)
-            {
-            userdata[i]  = uc.userdata[i];
-            }
+        for (size_t i = 0; i < USERDATA_NUM; i++) userdata[i]  = uc.userdata[i];
         creditExpire = uc.creditExpire;
         ips          = uc.ips;
         return *this;
     }
-    operator USER_CONF() const
+    USER_CONF GetData() const
     {
         USER_CONF uc;
-        uc.password     = password;
-        uc.passive      = passive;
-        uc.disabled     = disabled;
-        uc.disabledDetailStat = disabledDetailStat;
-        uc.alwaysOnline = alwaysOnline;
-        uc.tariffName   = tariffName;
-        uc.address      = address;
-        uc.phone        = phone;
-        uc.email        = email;
-        uc.note         = note;
-        uc.realName     = realName;
-        uc.group        = group;
-        uc.credit       = credit;
-        uc.nextTariff   = nextTariff;
+        uc.password     = password.data();
+        uc.passive      = passive.data();
+        uc.disabled     = disabled.data();
+        uc.disabledDetailStat = disabledDetailStat.data();
+        uc.alwaysOnline = alwaysOnline.data();
+        uc.tariffName   = tariffName.data();
+        uc.address      = address.data();
+        uc.phone        = phone.data();
+        uc.email        = email.data();
+        uc.note         = note.data();
+        uc.realName     = realName.data();
+        uc.group        = group.data();
+        uc.credit       = credit.data();
+        uc.nextTariff   = nextTariff.data();
         for (int i = 0; i < USERDATA_NUM; i++)
             {
-            uc.userdata[i]  = userdata[i];
+            uc.userdata[i]  = userdata[i].data();
             }
-        uc.creditExpire = creditExpire;
-        uc.ips          = ips;
+        uc.creditExpire = creditExpire.data();
+        uc.ips          = ips.data();
         return uc;
     }
     //-------------------------------------------------------------------------
@@ -155,4 +152,3 @@ struct USER_CONF_RES
 };
 //-----------------------------------------------------------------------------
 #endif
-
index e68190c543e5531227ad13c444be1c4b9c728327..e55f99fa7fc114460681fcebe87c8639ef2ee259 100644 (file)
@@ -70,7 +70,8 @@ public:
     std::string GetIpStr() const;
     bool IsIPInIPS(uint32_t ip) const;
     bool OnlyOneIP() const;
-    int  Count() const;
+    bool IsAnyIP() const;
+    size_t  Count() const;
     void Add(const IP_MASK &im);
     void Erase();
 
@@ -129,9 +130,9 @@ return s.str();
 }
 //-----------------------------------------------------------------------------
 inline
-int USER_IPS::Count() const
+size_t USER_IPS::Count() const
 {
-return static_cast<int>(ips.size());
+return ips.size();
 }
 //-----------------------------------------------------------------------------
 inline
@@ -172,6 +173,12 @@ return false;
 }
 //-----------------------------------------------------------------------------
 inline
+bool USER_IPS::IsAnyIP() const
+{
+    return !ips.empty() && ips.front().ip == 0;
+}
+//-----------------------------------------------------------------------------
+inline
 void USER_IPS::Add(const IP_MASK &im)
 {
 ips.push_back(im);
index 7c0f4da15dd4554e325f1f03d2f221f4823189ab..398c457914894ea083d8f31e3cde6756985f569d 100644 (file)
@@ -19,6 +19,7 @@ $Author: faust $
 #include "stg/logger.h"
 #include "stg/locker.h"
 #include "stg/scriptexecuter.h"
+#include "stg/common.h"
 
 #include "store.h"
 #include "admin.h"
@@ -288,7 +289,7 @@ USER_PROPERTY_LOGGED<varT>::USER_PROPERTY_LOGGED(varT & val,
       name(n),
       scriptsDir(sd)
 {
-properties.insert(std::make_pair(name, this));
+properties.insert(std::make_pair(ToLower(name), this));
 }
 //-------------------------------------------------------------------------
 template <typename varT>
index 54f11dec3a80ff748adfc819093a8f62cd4c2942..ff020dc7021195e8d3a921e3b52a72408f0fe6c8 100644 (file)
@@ -29,6 +29,8 @@
 
 #include <ctime>
 #include <map>
+#include <utility>
+#include <string>
 
 #include "os_int.h"
 #include "resetable.h"
@@ -113,10 +115,11 @@ struct STAT_NODE
 //-----------------------------------------------------------------------------
 struct USER_STAT
 {
-    //USER_STAT & operator= (const USER_STAT_RES & usr);
     USER_STAT()
-        : up(),
-          down(),
+        : sessionUp(),
+          sessionDown(),
+          monthUp(),
+          monthDown(),
           cash(0),
           freeMb(0),
           lastCashAdd(0),
@@ -125,8 +128,10 @@ struct USER_STAT
           lastActivityTime(0)
     {}
 
-    DIR_TRAFF   up;
-    DIR_TRAFF   down;
+    DIR_TRAFF   sessionUp;
+    DIR_TRAFF   sessionDown;
+    DIR_TRAFF   monthUp;
+    DIR_TRAFF   monthDown;
     double      cash;
     double      freeMb;
     double      lastCashAdd;
@@ -137,6 +142,8 @@ struct USER_STAT
 //-----------------------------------------------------------------------------
 typedef std::map<IP_DIR_PAIR, STAT_NODE> TRAFF_STAT;
 //-----------------------------------------------------------------------------
+typedef std::pair<double, std::string> CASH_INFO;
+//-----------------------------------------------------------------------------
 struct USER_STAT_RES
 {
     USER_STAT_RES()
@@ -146,8 +153,10 @@ struct USER_STAT_RES
           lastCashAddTime(),
           passiveTime(),
           lastActivityTime(),
-          up(),
-          down()
+          sessionUp(),
+          sessionDown(),
+          monthUp(),
+          monthDown()
     {}
 
     USER_STAT_RES & operator= (const USER_STAT & us)
@@ -158,32 +167,40 @@ struct USER_STAT_RES
         lastCashAddTime  = us.lastCashAddTime;
         passiveTime      = us.passiveTime;
         lastActivityTime = us.lastActivityTime;
-        up = us.up;
-        down = us.down;
-        return * this;
+        sessionUp        = us.sessionUp;
+        sessionDown      = us.sessionDown;
+        monthUp          = us.monthUp;
+        monthDown        = us.monthDown;
+        return *this;
     }
-    operator USER_STAT() const
+    USER_STAT GetData() const
     {
         USER_STAT us;
-        us.cash             = cash;
-        us.freeMb           = freeMb;
-        us.lastCashAdd      = lastCashAdd;
-        us.lastCashAddTime  = lastCashAddTime;
-        us.passiveTime      = passiveTime;
-        us.lastActivityTime = lastActivityTime;
-        us.up               = up;
-        us.down             = down;
+        us.cash             = cash.data();
+        us.freeMb           = freeMb.data();
+        us.lastCashAdd      = lastCashAdd.data();
+        us.lastCashAddTime  = lastCashAddTime.data();
+        us.passiveTime      = passiveTime.data();
+        us.lastActivityTime = lastActivityTime.data();
+        us.sessionUp        = sessionUp.GetData();
+        us.sessionDown      = sessionDown.GetData();
+        us.monthUp          = monthUp.GetData();
+        us.monthDown        = monthDown.GetData();
         return us;
     }
 
     RESETABLE<double>      cash;
+    RESETABLE<CASH_INFO>   cashAdd;
+    RESETABLE<CASH_INFO>   cashSet;
     RESETABLE<double>      freeMb;
     RESETABLE<double>      lastCashAdd;
     RESETABLE<time_t>      lastCashAddTime;
     RESETABLE<time_t>      passiveTime;
     RESETABLE<time_t>      lastActivityTime;
-    RESETABLE<DIR_TRAFF>   up;
-    RESETABLE<DIR_TRAFF>   down;
+    DIR_TRAFF_RES          sessionUp;
+    DIR_TRAFF_RES          sessionDown;
+    DIR_TRAFF_RES          monthUp;
+    DIR_TRAFF_RES          monthDown;
 };
 //-----------------------------------------------------------------------------
 #endif
index aee1171c9b387d876bd321fd6b0d6a5985205d43..e1176b90fdcc3c4ed00169bbf6bd413c0dc8bff9 100644 (file)
 #ifndef USER_TRAFF_H
 #define USER_TRAFF_H
 
-#include <iostream>
-#include <vector>
-
+#include "resetable.h"
 #include "const.h"
 #include "os_int.h"
 
+#include <iostream>
+#include <vector>
+
 enum TRAFF_DIRECTION {TRAFF_UPLOAD, TRAFF_DOWNLOAD};
 
 class DIR_TRAFF
@@ -43,64 +44,23 @@ public:
     typedef std::vector<uint64_t> ContainerType;
     typedef ContainerType::size_type IndexType;
 
-    //-------------------------------------------------------------------------
-    DIR_TRAFF();
-    DIR_TRAFF(const DIR_TRAFF & ts);
-    DIR_TRAFF & operator=(const DIR_TRAFF & ts);
-    ~DIR_TRAFF();
-    uint64_t operator[](IndexType idx) const;
-    uint64_t & operator[](IndexType idx);
-    DIR_TRAFF operator+(const DIR_TRAFF & ts);
+    DIR_TRAFF() : traff(DIR_NUM) {}
+    DIR_TRAFF(const DIR_TRAFF & ts) : traff(ts.traff) {}
+    DIR_TRAFF & operator=(const DIR_TRAFF & ts) { traff = ts.traff; return *this; }
+    const uint64_t & operator[](IndexType idx) const { return traff[idx]; }
+    uint64_t & operator[](IndexType idx) { return traff[idx]; }
+    IndexType size() const { return traff.size(); }
 
 private:
     ContainerType traff;
 };
-//-----------------------------------------------------------------------------
 
 //-----------------------------------------------------------------------------
-inline DIR_TRAFF::DIR_TRAFF()
-    : traff(DIR_NUM, 0)
-{
-}
-//-----------------------------------------------------------------------------
-inline DIR_TRAFF::DIR_TRAFF(const DIR_TRAFF & ts)
-    : traff(ts.traff)
-{
-}
-//-----------------------------------------------------------------------------
-inline DIR_TRAFF::~DIR_TRAFF()
-{
-}
-//-----------------------------------------------------------------------------
-inline DIR_TRAFF & DIR_TRAFF::operator=(const DIR_TRAFF & ts)
-{
-traff = ts.traff;
-return *this;
-}
-//-----------------------------------------------------------------------------
-inline uint64_t & DIR_TRAFF::operator[](IndexType idx)
-{
-return traff[idx];
-}
-//-----------------------------------------------------------------------------
-inline uint64_t DIR_TRAFF::operator[](IndexType idx) const
-{
-return traff[idx];
-}
-//-----------------------------------------------------------------------------
-inline DIR_TRAFF DIR_TRAFF::operator+(const DIR_TRAFF & ts)
-{
-for (IndexType i = 0; i < DIR_NUM; i++)
-    {
-    traff[i] = traff[i] + ts.traff[i];
-    }
-return *this;
-}
-//-----------------------------------------------------------------------------
-inline std::ostream & operator<<(std::ostream & o, const DIR_TRAFF & traff)
+inline
+std::ostream & operator<<(std::ostream & o, const DIR_TRAFF & traff)
 {
 bool first = true;
-for (DIR_TRAFF::IndexType i = 0; i < DIR_NUM; ++i)
+for (DIR_TRAFF::IndexType i = 0; i < traff.size(); ++i)
     {
     if (first)
         first = false;
@@ -110,5 +70,36 @@ for (DIR_TRAFF::IndexType i = 0; i < DIR_NUM; ++i)
     }
 return o;
 }
-//-----------------------------------------------------------------------------
+
+class DIR_TRAFF_RES
+{
+public:
+    typedef RESETABLE<uint64_t> value_type;
+    typedef RESETABLE<uint64_t> ValueType;
+    typedef std::vector<ValueType> ContainerType;
+    typedef ContainerType::size_type IndexType;
+
+    DIR_TRAFF_RES() : traff(DIR_NUM) {}
+    DIR_TRAFF_RES(const DIR_TRAFF & ts)
+        : traff(ts.size())
+    {
+    for (IndexType i = 0; i < ts.size(); ++i)
+        traff[i] = ts[i];
+    }
+    const ValueType & operator[](IndexType idx) const { return traff[idx]; }
+    ValueType & operator[](IndexType idx) { return traff[idx]; }
+    IndexType size() const { return traff.size(); }
+    DIR_TRAFF GetData() const
+    {
+    DIR_TRAFF res;
+    for (IndexType i = 0; i < traff.size(); ++i)
+        if (!traff[i].empty())
+            res[i] = traff[i].data();
+    return res;
+    }
+
+private:
+    ContainerType traff;
+};
+
 #endif
index 2ba238332297b5b70d0267dc4e967d5aacec9428..9f516aef877358c1d3d3537423c1d7b2d615f2c3 100644 (file)
@@ -32,6 +32,7 @@ class USERS {
 public:
     virtual ~USERS() {}
     virtual int  FindByName(const std::string & login, USER_PTR * user) = 0;
+    virtual int  FindByName(const std::string & login, CONST_USER_PTR * user) const = 0;
 
     virtual bool TariffInUse(const std::string & tariffName) const = 0;
 
@@ -46,13 +47,16 @@ public:
 
     virtual bool Authorize(const std::string & login, uint32_t ip,
                            uint32_t enabledDirs, const AUTH * auth) = 0;
-    virtual bool Unauthorize(const std::string & login, const AUTH * auth) = 0;
+    virtual bool Unauthorize(const std::string & login,
+                             const AUTH * auth,
+                             const std::string & reason = std::string()) = 0;
 
     virtual int  ReadUsers() = 0;
     virtual size_t Count() const = 0;
 
     virtual int  FindByIPIdx(uint32_t ip, USER_PTR * user) const = 0;
     virtual bool IsIPInIndex(uint32_t ip) const = 0;
+    virtual bool IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const = 0;
 
     virtual int  OpenSearch() = 0;
     virtual int  SearchNext(int handle, USER_PTR * u) = 0;
index 20da4e432a7081b73c7cf131ed5e1c0642957f24..fe6b3f69d9601d2f737404f78e0bfc31e24196a3 100644 (file)
@@ -164,6 +164,11 @@ struct UTIME: public timeval
     {
     return tv_usec;
     }
+
+    double AsDouble() const
+    {
+    return tv_sec + tv_usec * 1e-6;
+    }
 };
 
 
index 91fe7d9d4eed0512bd65431aeddca32e24b54940..6459cdb9e4f5e3fc049fada62d5bfba6e8f13b0a 100755 (executable)
@@ -53,15 +53,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but rlm_stg currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but rlm_stg currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building rlm_stg for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building rlm_stg for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="crypto.lib common.lib"
 
@@ -95,32 +95,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -129,39 +129,39 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "ARCH=$ARCH" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $CONFFILE
-echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $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
+printf "\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 $MAKE $MAKEOPTS
 
index ea3914c7d5d50b3134acc9b4dcbe67e37aae6c98..c7aa090dc9d2bf79a1cd7591ff44813690f2e131 100755 (executable)
@@ -53,15 +53,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but rscriptd currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but rscriptd currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building rscriptd for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building rscriptd for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="logger.lib 
           locker.lib
@@ -100,32 +100,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -134,41 +134,41 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 rm -f build_check.c
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "ARCH=$ARCH" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $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
+printf "\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 
 $MAKE $MAKEOPTS
 
index 8b79bc52307a9fb44d1e106d0e88e46021aa4791..5ea022a2fc0ed8aa2dc3b083481b84e2c5674590 100755 (executable)
@@ -53,15 +53,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but sgauth currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but sgauth currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building sgauth for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building sgauth for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="crypto.lib 
          common.lib 
@@ -98,32 +98,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -132,40 +132,40 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 rm -f build_check.c
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "ARCH=$ARCH" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $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
+printf "\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 $MAKE $MAKEOPTS
 
index 6f26a17e78e09066bceb50178f17b22a8778ab42..2b1456593dc88da9a43e861ce87358c9f8831e94 100755 (executable)
@@ -59,15 +59,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "################################################################################"
-    echo "# Sorry, but sgauthstress currently supported by Linux, FreeBSD 4.x-8.x        #"
-    echo "################################################################################"
+    printf "################################################################################\n"
+    printf "# Sorry, but sgauthstress currently supported by Linux, FreeBSD 4.x-8.x        #\n"
+    printf "################################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building sgauthstress for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building sgauthstress for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="logger.lib
           locker.lib
@@ -108,32 +108,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -142,103 +142,103 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 rm -f build_check.c
 
-echo -n "Checking for -lfbclient... "
+printf "Checking for -lfbclient... "
 $CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_FBCLIENT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_FBCLIENT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 
-echo -n "Checking for mysql_config... "
+printf "Checking for mysql_config... "
 MYSQL_VERSION=`mysql_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lmysqlclient... "
+    printf "no\n";
+    printf "Checking for -lmysqlclient... "
     $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_MYSQLCLIENT=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes"
-    echo -n "Checking for mysql_config --cflags... "
+    printf "yes\n"
+    printf "Checking for mysql_config --cflags... "
     MYSQL_CFLAGS=`mysql_config --cflags 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$MYSQL_CFLAGS]"
-        echo -n "Checking for mysql_config --libs_r... "
+        printf "[$MYSQL_CFLAGS]\n"
+        printf "Checking for mysql_config --libs_r... "
         MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_MYSQLCLIENT=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_MYSQLCLIENT=yes
-            echo "[$MYSQL_LDFLAGS]"
+            printf "[$MYSQL_LDFLAGS]\n"
         fi
     fi
 fi
 
-echo -n "Checking for pg_config... "
+printf "Checking for pg_config... "
 PG_VERSION=`pg_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lpq... "
+    printf "no\n";
+    printf "Checking for -lpq... "
     $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_PQ=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes";
-    echo -n "Checking for pg_config --includedir... "
+    printf "yes\n";
+    printf "Checking for pg_config --includedir... "
     PG_CFLAGS=`pg_config --includedir 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$PG_CFLAGS]"
-        echo -n "Checking for pg_config --libdir... "
+        printf "[$PG_CFLAGS]\n"
+        printf "Checking for pg_config --libdir... "
         PG_LDFLAGS=`pg_config --libdir 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_PQ=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_PQ=yes
-            echo "[$PG_LDFLAGS]"
+            printf "[$PG_LDFLAGS]\n"
         fi
     fi
 fi
@@ -265,36 +265,36 @@ then
          store/mysql"
 fi
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "DIR_MOD=\$(DIR_BUILD)/../stargazer/modules\n" >> $CONFFILE
+printf "DIR_PLUGINS=\$(DIR_BUILD)/../stargazer/plugins\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo -n "PLUGINS=" >> $CONFFILE
+printf "\n" >> $CONFFILE
+printf "PLUGINS=" >> $CONFFILE
 for plugin in $PLUGINS
 do
-    echo -n "$plugin " >> $CONFFILE
+    printf "$plugin " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $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
+printf "\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 $MAKE $MAKEOPTS
index 297d3e206983bb40c96ce9e9d5ab51e5b4051732..0098ff5ef0b7adab9d1edd0e564ab22cdf69c20e 100644 (file)
@@ -7,7 +7,9 @@ include ../../Makefile.conf
 PROG = sgconf
 
 SRCS = ./main.cpp \
-       ./common_sg.cpp
+       ./common_sg.cpp \
+       ./options.cpp \
+       ./actions.cpp
 
 STGLIBS = conffiles \
           srvconf \
@@ -41,7 +43,11 @@ OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
 
 CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
 CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
-LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
+LDFLAGS += $(STGLIBS_LIBS)
+
+ifneq ($(OS),darwin)
+LDFLAGS += -Wl,-E
+endif
 
 .PHONY: all clean distclean libs install uninstall install-bin install-data uninstall-bin uninstall-data
 all: libs $(PROG) ../../Makefile.conf
diff --git a/projects/sgconf/action.h b/projects/sgconf/action.h
new file mode 100644 (file)
index 0000000..0c1b4f9
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *    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 __STG_SGCONF_ACTION_H__
+#define __STG_SGCONF_ACTION_H__
+
+#include <string>
+#include <stdexcept>
+
+namespace SGCONF
+{
+
+class OPTION_BLOCK;
+struct PARSER_STATE;
+
+class ACTION
+{
+    public:
+        virtual ~ACTION() {}
+
+        virtual ACTION * Clone() const = 0;
+        virtual std::string ParamDescription() const = 0;
+        virtual std::string DefaultDescription() const = 0;
+        virtual OPTION_BLOCK & Suboptions() = 0;
+        virtual PARSER_STATE Parse(int argc, char ** argv) = 0;
+        virtual void ParseValue(const std::string &) {}
+
+        class ERROR : public std::runtime_error
+        {
+            public:
+                ERROR(const std::string & message)
+                    : std::runtime_error(message.c_str()) {}
+        };
+};
+
+} // namespace SGCONF
+
+#endif
diff --git a/projects/sgconf/actions.cpp b/projects/sgconf/actions.cpp
new file mode 100644 (file)
index 0000000..afa5162
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *    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>
+ */
diff --git a/projects/sgconf/actions.h b/projects/sgconf/actions.h
new file mode 100644 (file)
index 0000000..33a1134
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ *    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 __STG_SGCONF_ACTIONS_H__
+#define __STG_SGCONF_ACTIONS_H__
+
+#include "action.h"
+#include "options.h"
+#include "parser_state.h"
+
+#include "stg/common.h"
+#include "stg/resetable.h"
+
+#include <string>
+
+namespace SGCONF
+{
+
+typedef void (* FUNC0)();
+
+template <typename F>
+class FUNC0_ACTION : public ACTION
+{
+    public:
+        FUNC0_ACTION(const F & func) : m_func(func) {}
+
+        virtual ACTION * Clone() const { return new FUNC0_ACTION<F>(*this); }
+
+        virtual std::string ParamDescription() const { return ""; }
+        virtual std::string DefaultDescription() const { return ""; }
+        virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+        virtual PARSER_STATE Parse(int argc, char ** argv)
+        {
+        m_func();
+        return PARSER_STATE(true, argc, argv);
+        }
+
+    private:
+        F m_func;
+        OPTION_BLOCK m_suboptions;
+};
+
+template <typename F>
+inline
+FUNC0_ACTION<F> * MakeFunc0Action(F func)
+{
+return new FUNC0_ACTION<F>(func);
+}
+
+template <typename T>
+class PARAM_ACTION : public ACTION
+{
+    public:
+        PARAM_ACTION(RESETABLE<T> & param,
+                     const T & defaultValue,
+                     const std::string & paramDescription)
+            : m_param(param),
+              m_defaltValue(defaultValue),
+              m_description(paramDescription),
+              m_hasDefault(true)
+        {}
+        PARAM_ACTION(RESETABLE<T> & param,
+                     const std::string & paramDescription)
+            : m_param(param),
+              m_description(paramDescription),
+              m_hasDefault(false)
+        {}
+
+        virtual ACTION * Clone() const { return new PARAM_ACTION<T>(*this); }
+
+        virtual std::string ParamDescription() const { return m_description; }
+        virtual std::string DefaultDescription() const;
+        virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+        virtual PARSER_STATE Parse(int argc, char ** argv);
+        virtual void ParseValue(const std::string & value);
+
+    private:
+        RESETABLE<T> & m_param;
+        T m_defaltValue;
+        std::string m_description;
+        bool m_hasDefault;
+        OPTION_BLOCK m_suboptions;
+};
+
+template <typename T>
+inline
+std::string PARAM_ACTION<T>::DefaultDescription() const
+{
+return m_hasDefault ? " (default: '" + x2str(m_defaltValue) + "')"
+                    : "";
+}
+
+template <>
+inline
+std::string PARAM_ACTION<std::string>::DefaultDescription() const
+{
+return m_hasDefault ? " (default: '" + m_defaltValue + "')"
+                    : "";
+}
+
+template <typename T>
+inline
+PARSER_STATE PARAM_ACTION<T>::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+    argv == NULL ||
+    *argv == NULL)
+    throw ERROR("Missing argument.");
+T value;
+if (str2x(*argv, value))
+    throw ERROR(std::string("Bad argument: '") + *argv + "'");
+m_param = value;
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+template <typename T>
+inline
+void PARAM_ACTION<T>::ParseValue(const std::string & stringValue)
+{
+if (stringValue.empty())
+    throw ERROR("Missing value.");
+T value;
+if (str2x(stringValue, value))
+    throw ERROR(std::string("Bad value: '") + stringValue + "'");
+m_param = value;
+}
+
+template <>
+inline
+void PARAM_ACTION<std::string>::ParseValue(const std::string & stringValue)
+{
+m_param = stringValue;
+}
+
+template <>
+inline
+PARSER_STATE PARAM_ACTION<std::string>::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+    argv == NULL ||
+    *argv == NULL)
+    throw ERROR("Missing argument.");
+m_param = *argv;
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+template <typename T>
+inline
+PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
+                                  const T & defaultValue,
+                                  const std::string & paramDescription)
+{
+return new PARAM_ACTION<T>(param, defaultValue, paramDescription);
+}
+
+template <typename T>
+inline
+PARAM_ACTION<T> * MakeParamAction(RESETABLE<T> & param,
+                                  const std::string & paramDescription)
+{
+return new PARAM_ACTION<T>(param, paramDescription);
+}
+
+} // namespace SGCONF
+
+#endif
index a8a675bebf5cdb1d7418f9e21b05ddf56a4e4ca5..d7b72363cdc6dc8f23f931c637195989d292b6dd 100755 (executable)
@@ -51,17 +51,24 @@ then
     MAKE="gmake"
 fi
 
+if [ "$sys" = "Darwin" ]
+then
+    OS=darwin
+    ETC_DIR="./inst/freebsd/etc/stargazer"
+    MAKE="gmake"
+fi
+
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but sgconf currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but sgconf currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building sgconf for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building sgconf for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="conffiles.lib
          crypto.lib 
@@ -77,12 +84,18 @@ else
     then
         DEFS="$DEFS -DFREE_BSD"
     else
-        DEFS="$DEFS -DFREE_BSD5"
         if [ "$OS" = "bsd7" ]
         then
+            DEFS="$DEFS -DFREE_BSD5"
             LIB_THREAD=-lpthread
         else
-            LIB_THREAD=-lc_r
+            if [ "$OS" == "darwin" ]
+            then
+                DEFS="$DEFS -DDARWIN"
+                LIB_THREAD=-lpthread
+            else
+                LIB_THREAD=-lc_r
+            fi
         fi
     fi
 fi
@@ -97,32 +110,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -131,61 +144,61 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 
-echo -n "Checking for -lexpat... "
-echo "int main() { return 0; }" > build_check.c
+printf "Checking for -lexpat... "
+printf "int main() { return 0; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_EXPAT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_EXPAT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 rm -f build_check.c
 
 if [ "$CHECK_EXPAT" != "yes" ]
 then
-    echo "-lexpat not found!"
+    printf "-lexpat not found!\n"
     exit 1
 fi
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "ARCH=$ARCH" >> $CONFFILE
-echo "CHECK_EXPAT=$CHECK_EXPAT" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "CHECK_EXPAT=$CHECK_EXPAT\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $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
+printf "\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 
 $MAKE $MAKEOPTS
 
index 3d0151602d18c948c45c95177dd701cdc696320d..e407a7165c6e560c1a85fb528b28e285d5de8930 100644 (file)
  */
 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <iostream>
-#include <iconv.h>
-
-#include "stg/common.h"
 #include "sg_error_codes.h"
 #include "common_sg.h"
 #include "version_sg.h"
 
-using namespace std;
+#include "stg/common.h"
+
+#include <iostream>
+#include <vector>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cerrno>
+#include <clocale>
+
+#include <langinfo.h>
+#include <iconv.h>
+
+using namespace STG;
 
 const int usageConf = 0;
 const int usageInfo = 1;
@@ -47,18 +51,26 @@ const int usageInfo = 1;
 const int TO_KOI8 = 0;
 const int FROM_KOI8 = 1;
 //-----------------------------------------------------------------------------
-struct GetUserCbData
+struct ResultData
+{
+    bool result;
+    std::string reason;
+};
+//-----------------------------------------------------------------------------
+struct GetUserData
 {
-    void * data;
-    bool * result;
+    GetUserData(REQUEST & req, bool res) : request(req), result(res) {}
+    REQUEST & request;
+    bool result;
+    std::string reason;
 };
 //---------------------------------------------------------------------------
 struct HelpParams
 {
-    string setActionName;
-    string getActionName;
-    string valueName;
-    string valueParam;
+    std::string setActionName;
+    std::string getActionName;
+    std::string valueName;
+    std::string valueParam;
 };
 //---------------------------------------------------------------------------
 void Usage(int usageType)
@@ -84,7 +96,7 @@ HelpParams hp[] =
     {"set credit expire",       "get credit expire",    "-E",   "<credit_expire_date>"},
     {"set password",            "get password",         "-o",   "<new_password>"},
     {"set prepaid traffic",     "get prepaid traffic",  "-e",   "<prepaid>"},
-    {"set IP-addresses",       "get IP-addresses",     "-I",   "<*|ip_addr[,ip_addr...]>"},
+    {"set IP-addresses",        "get IP-addresses",     "-I",   "<*|ip_addr[,ip_addr...]>"},
     {"set name",                "get name",             "-A",   "<name>"},
     {"set note",                "get note",             "-N",   "<note>"},
     {"set street address",      "get street address",   "-D",   "<address>"},
@@ -122,6 +134,9 @@ printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --
 printf("To get userdata<0...9> use:\n");
 printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --ud0 [--ud1 ...]\n\n");
 
+printf("To get user's authorizers list use:\n");
+printf("sgconf get -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> --authorized-by\n\n");
+
 printf("To send message use:\n");
 printf("sgconf set -s <server> -p <port> -a <admin> -w <admin_pass> -u <user> -m <message>\n\n");
 
@@ -164,7 +179,7 @@ short int ParseServerPort(const char * p)
 int port;
 if (str2x(p, port) != 0)
     {
-    printf("Incorresct server port %s\n", p);
+    printf("Incorrect server port %s\n", p);
     exit(NETWORK_ERR_CODE);
     }
 return (short)port;
@@ -174,7 +189,7 @@ char * ParseAdminLogin(char * adm)
 {
 if (CheckLogin(adm))
     {
-    printf("Incorresct admin login %s\n", adm);
+    printf("Incorrect admin login %s\n", adm);
     exit(PARAMETER_PARSING_ERR_CODE);
     }
 return adm;
@@ -195,13 +210,13 @@ char * ParseUser(char * usr)
 {
 if (CheckLogin(usr))
     {
-    printf("Incorresct user login %s\n", usr);
+    printf("Incorrect user login %s\n", usr);
     exit(PARAMETER_PARSING_ERR_CODE);
     }
 return usr;
 }
 //-----------------------------------------------------------------------------
-void ConvertKOI8(const string & src, string * dst, int encType)
+void ConvertKOI8(const std::string & src, std::string * dst, int encType)
 {
 iconv_t cd;
 char * ob = new char[src.size() * 2 + 1];
@@ -276,67 +291,68 @@ delete[] ob;
 delete[] ib;
 }
 //-----------------------------------------------------------------------------
-void ConvertFromKOI8(const string & src, string * dst)
+void ConvertFromKOI8(const std::string & src, std::string * dst)
 {
 ConvertKOI8(src, dst, FROM_KOI8);
 }
 //-----------------------------------------------------------------------------
-void ConvertToKOI8(const string & src, string * dst)
+void ResultCallback(bool result, const std::string & reason, void * d)
 {
-ConvertKOI8(src, dst, TO_KOI8);
+ResultData * data = static_cast<ResultData *>(d);
+data->result = result;
+data->reason = reason;
 }
 //-----------------------------------------------------------------------------
-int RecvSetUserAnswer(const char * ans, void * d)
+void RecvAuthByData(bool result, const std::string & reason,
+                    const AUTH_BY::INFO & list, void * d)
 {
-GetUserCbData * gucbd;
-gucbd = (GetUserCbData *)d;
-
-bool * result = gucbd->result;
+ResultData * data = static_cast<ResultData *>(d);
+data->result = result;
+data->reason = reason;
 
-//REQUEST * req = (REQUEST *)gucbd->data;
+if (!result)
+    return;
 
-//printf("ans=%s\n", ans);
-if (strcasecmp("Ok", ans) == 0)
-    *result = true;
-else
-    *result = false;
+for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
+    std::cout << *it << "\n";
 
-return 0;
+std::cout << std::endl;
 }
 //-----------------------------------------------------------------------------
 struct StringReqParams
 {
-    string name;
-    RESETABLE<string> reqParam;
-    string * value;
+    std::string name;
+    RESETABLE<std::string> reqParam;
+    const std::string * value;
 };
 //-----------------------------------------------------------------------------
-void RecvUserData(USERDATA * ud, void * d)
+void GetUserCallback(bool result, const std::string& reason, const GET_USER::INFO & info, void * d)
 {
-GetUserCbData * gucbd;
-gucbd = (GetUserCbData *)d;
-
-bool * result = gucbd->result;
+GetUserData * data = static_cast<GetUserData *>(d);
+data->result = false;
+data->reason = reason;
 
-REQUEST * req = (REQUEST *)gucbd->data;
+if (!result)
+    return;
 
-if (ud->login == "")
+if (info.login == "")
     {
-    *result = false;
+    data->result = false;
+    data->reason = "Invalid login.";
     return;
     }
 
-if (!req->cash.res_empty())
-    cout << "cash=" << ud->cash << endl;
+if (!data->request.cash.empty())
+    cout << "cash = " << info.cash << endl;
 
-if (!req->credit.res_empty())
-    cout << "credit=" << ud->credit << endl;
+if (!data->request.credit.empty())
+    cout << "credit = " << info.credit << endl;
 
-if (!req->creditExpire.res_empty())
+if (!data->request.creditExpire.empty())
     {
     char buf[32];
     struct tm brokenTime;
-    time_t tt = ud->creditExpire;
+    time_t tt = info.creditExpire;
 
     brokenTime.tm_wday = 0;
     brokenTime.tm_yday = 0;
@@ -349,151 +365,172 @@ if (!req->creditExpire.res_empty())
 
     strftime(buf, 32, "%Y-%m-%d", &brokenTime);
 
-    cout << "creditExpire=" << buf << endl;
+    cout << "creditExpire = " << buf << endl;
     }
 
-if (!req->down.res_empty())
-    cout << "down=" << ud->down << endl;
+if (!data->request.down.empty())
+    cout << "down = " << info.down << endl;
 
-if (!req->passive.res_empty())
-    cout << "passive=" << ud->passive << endl;
+if (!data->request.passive.empty())
+    cout << "passive = " << info.passive << endl;
 
-if (!req->disableDetailStat.res_empty())
-    cout << "disableDetailStat=" << ud->disableDetailStat << endl;
+if (!data->request.disableDetailStat.empty())
+    cout << "disableDetailStat = " << info.disableDetailStat << endl;
 
-if (!req->alwaysOnline.res_empty())
-    cout << "alwaysOnline=" << ud->alwaysOnline << endl;
+if (!data->request.alwaysOnline.empty())
+    cout << "alwaysOnline = " << info.alwaysOnline << endl;
 
-if (!req->prepaidTraff.res_empty())
-    cout << "prepaidTraff=" << ud->prepaidTraff << endl;
+if (!data->request.prepaidTraff.empty())
+    cout << "prepaidTraff = " << info.prepaidTraff << endl;
 
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (!req->u[i].res_empty())
-        cout << "u" << i << "=" << ud->stat.mu[i] << endl;
-    if (!req->d[i].res_empty())
-        cout << "d" << i << "=" << ud->stat.md[i] << endl;
+    if (!data->request.sessionUpload[i].empty())
+        cout << "session upload for dir " << i << " = " << info.stat.su[i] << endl;
+    if (!data->request.sessionDownload[i].empty())
+        cout << "session download for dir " << i << "=" << info.stat.sd[i] << endl;
+    }
+
+for (int i = 0; i < DIR_NUM; i++)
+    {
+    if (!data->request.monthUpload[i].empty())
+        cout << "month upload for dir " << i << " = " << info.stat.mu[i] << endl;
+    if (!data->request.monthDownload[i].empty())
+        cout << "month download for dir " << i << " = " << info.stat.md[i] << endl;
     }
 
 for (int i = 0; i < USERDATA_NUM; i++)
     {
-    if (!req->ud[i].res_empty())
+    if (!data->request.userData[i].empty())
         {
-        string str;
-        ConvertFromKOI8(ud->userData[i], &str);
-        cout << "userdata" << i << "=" << str << endl;
+        std::string str;
+        ConvertFromKOI8(info.userData[i], &str);
+        cout << "user data " << i << " = " << str << endl;
         }
     }
 
 StringReqParams strReqParams[] =
 {
-    {"note",     req->note,        &ud->note},
-    {"name",     req->name,        &ud->name},
-    {"address",  req->address,     &ud->address},
-    {"email",    req->email,       &ud->email},
-    {"phone",    req->phone,       &ud->phone},
-    {"group",    req->group,       &ud->group},
-    {"tariff",   req->tariff,      &ud->tariff},
-    {"password", req->usrPasswd,   &ud->password},
-    {"ip",      req->ips,         &ud->ips}    // IP-address of user
+    {"note",     data->request.note,        &info.note},
+    {"name",     data->request.name,        &info.name},
+    {"address",  data->request.address,     &info.address},
+    {"email",    data->request.email,       &info.email},
+    {"phone",    data->request.phone,       &info.phone},
+    {"group",    data->request.group,       &info.group},
+    {"tariff",   data->request.tariff,      &info.tariff},
+    {"password", data->request.usrPasswd,   &info.password},
+    {"ip",       data->request.ips,         &info.ips} // IP-address of user
 };
 for (unsigned i = 0; i < sizeof(strReqParams) / sizeof(StringReqParams); i++)
     {
-    if (!strReqParams[i].reqParam.res_empty())
+    if (!strReqParams[i].reqParam.empty())
         {
         string str;
         ConvertFromKOI8(*strReqParams[i].value, &str);
-        cout << strReqParams[i].name << "=" << str << endl;
+        cout << strReqParams[i].name << " = " << str << endl;
         }
     }
-*result = true;
+data->result = true;
 }
 //-----------------------------------------------------------------------------
-int ProcessSetUser(const std::string &server,
-                   int port,
-                   const std::string &admLogin,
-                   const std::string &admPasswd,
-                   const std::string &str,
-                   void * data,
-                   bool isMessage)
+bool ProcessSetUser(const std::string & server,
+                    int port,
+                    const std::string & login,
+                    const std::string & password,
+                    const std::string & user,
+                    const USER_CONF_RES & conf,
+                    const USER_STAT_RES & stat)
 {
-SERVCONF sc;
+SERVCONF sc(server, port, login, password);
 
-bool result = false;
+ResultData data;
+int res = sc.ChgUser(user, conf, stat, ResultCallback, &data);
 
-
-sc.SetServer(server.c_str());  // õÓÔÁÎÁ×ÌÉ×ÁÅÍ ÉÍÑ ÓÅÒ×ÅÒÁ Ó ËÏÔÏÒÇÏ ÚÁÂÉÒÁÔØ ÉÎÆÕ
-sc.SetPort(port);           // ÁÄÍÉÎÓËÉÊ ÐÏÒÔ ÓÅÒ×ÅÒÁÐÏÒÔ
-sc.SetAdmLogin(admLogin.c_str());    // ÷ÙÓÔÁ×ÌÑÅÍ ÌÏÇÉΠɠÐÁÒÏÌØ ÁÄÍÉÎÁ
-sc.SetAdmPassword(admPasswd.c_str());
-
-// TODO Good variable name :)
-GetUserCbData gucbd;
-
-gucbd.data = data;
-gucbd.result = &result;
-
-if (isMessage)
+if (res == st_ok && data.result)
     {
-    sc.SetSendMessageCb(RecvSetUserAnswer, &gucbd);
-    sc.MsgUser(str.c_str());
+    printf("Ok\n");
+    return false;
     }
+
+printf("Error\n");
+if (res != st_ok)
+    printf("%s\n", sc.GetStrError().c_str());
 else
-    {
-    sc.SetChgUserCb(RecvSetUserAnswer, &gucbd);
-    sc.ChgUser(str.c_str());
-    }
+    printf("%s\n", data.reason.c_str());
+return true;
+}
+//-----------------------------------------------------------------------------
+bool ProcessSendMessage(const std::string & server, uint16_t port,
+                        const std::string & login, const std::string & password,
+                        const std::string & user, const std::string & text)
+{
+SERVCONF sc(server, port, login, password);
+
+ResultData data;
+int res = sc.SendMessage(user, text, ResultCallback, &data);
 
-if (result)
+if (res == st_ok && data.result)
     {
     printf("Ok\n");
-    return 0;
+    return true;
     }
+
+printf("Error\n");
+if (res != st_ok)
+    printf("%s\n", sc.GetStrError().c_str());
 else
+    printf("%s\n", data.reason.c_str());
+return false;
+}
+//-----------------------------------------------------------------------------
+bool ProcessGetUser(const std::string &server,
+                    int port,
+                    const std::string &admLogin,
+                    const std::string &admPasswd,
+                    const std::string &login,
+                    REQUEST & request)
+{
+SERVCONF sc(server, port, admLogin, admPasswd);
+
+GetUserData data(request, false);
+bool res = (sc.GetUser(login.c_str(), GetUserCallback, &data) == st_ok);
+
+if (res && data.result)
     {
-    printf("Error\n");
-    return -1;
+    printf("Ok\n");
+    return true;
     }
 
-return 0;
+printf("Error\n");
+if (!res)
+    printf("%s\n", sc.GetStrError().c_str());
+else
+    printf("%s\n", data.reason.c_str());
+return false;
 }
 //-----------------------------------------------------------------------------
-int ProcessGetUser(const std::string &server,
+bool ProcessAuthBy(const std::string &server,
                    int port,
                    const std::string &admLogin,
                    const std::string &admPasswd,
-                   const std::string &login,
-                   void * data)
+                   const std::string &login)
 {
-SERVCONF sc;
-
-bool result = false;
-
-sc.SetServer(server.c_str());  // õÓÔÁÎÁ×ÌÉ×ÁÅÍ ÉÍÑ ÓÅÒ×ÅÒÁ Ó ËÏÔÏÒÇÏ ÚÁÂÉÒÁÔØ ÉÎÆÕ
-sc.SetPort(port);           // ÁÄÍÉÎÓËÉÊ ÐÏÒÔ ÓÅÒ×ÅÒÁÐÏÒÔ
-sc.SetAdmLogin(admLogin.c_str());    // ÷ÙÓÔÁ×ÌÑÅÍ ÌÏÇÉΠɠÐÁÒÏÌØ ÁÄÍÉÎÁ
-sc.SetAdmPassword(admPasswd.c_str());
+SERVCONF sc(server, port, admLogin, admPasswd);
 
-// TODO Good variable name :)
-GetUserCbData gucbd;
+ResultData data;
+bool res = (sc.AuthBy(login.c_str(), RecvAuthByData, &data) == st_ok);
 
-gucbd.data = data;
-gucbd.result = &result;
-
-sc.SetGetUserDataRecvCb(RecvUserData, &gucbd);
-sc.GetUser(login.c_str());
-
-if (result)
+if (res && data.result)
     {
     printf("Ok\n");
-    return 0;
-    }
-else
-    {
-    printf("Error\n");
-    return -1;
+    return true;
     }
 
-return 0;
+printf("Error\n");
+if (!res)
+    printf("%s\n", sc.GetStrError().c_str());
+else
+    printf("%s\n", data.reason.c_str());
+return false;
 }
 //-----------------------------------------------------------------------------
index a654748a68f744ea558ef309d5d2702d21447c4e..323a8cf8f1dead9d437ef6c2c554af29f4455509 100644 (file)
 #ifndef COMMON_SG_H
 #define COMMON_SG_H
 
-#include <string>
-
 #include "stg/servconf.h"
+#include "stg/servconf_types.h"
 #include "request.h"
 
+#include <string>
+
+struct USER_CONF_RES;
+struct USER_STAT_RES;
+
 void UsageConf();
 void UsageInfo();
 
@@ -45,20 +49,29 @@ int CheckLogin(const char * login);
 void ConvertFromKOI8(const std::string & src, std::string * dst);
 void ConvertToKOI8(const std::string & src, std::string * dst);
 
-int ProcessGetUser(const std::string &server,
-                   int port,
-                   const std::string &admLogin,
-                   const std::string &admPasswd,
-                   const std::string &login,
-                   void * data);
+bool ProcessGetUser(const std::string & server,
+                    int port,
+                    const std::string & admLogin,
+                    const std::string & admPasswd,
+                    const std::string & login,
+                    REQUEST & request);
 
-int ProcessSetUser(const std::string &server,
+bool ProcessAuthBy(const std::string & server,
                    int port,
-                   const std::string &admLogin,
-                   const std::string &admPasswd,
-                   const std::string &str,
-                   void * data,
-                   bool isMessage = false);
+                   const std::string & admLogin,
+                   const std::string & admPasswd,
+                   const std::string & login);
 
-#endif
+bool ProcessSetUser(const std::string & server,
+                    int port,
+                    const std::string & admLogin,
+                    const std::string & admPasswd,
+                    const std::string & user,
+                    const USER_CONF_RES & conf,
+                    const USER_STAT_RES & stat);
 
+bool ProcessSendMessage(const std::string & server, uint16_t port,
+                        const std::string & login, const std::string & password,
+                        const std::string & user, const std::string & text);
+
+#endif
diff --git a/projects/sgconf/config.h b/projects/sgconf/config.h
new file mode 100644 (file)
index 0000000..9ec9616
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *    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 __STG_SGCONF_CONFIG_H__
+#define __STG_SGCONF_CONFIG_H__
+
+#include "stg/common.h"
+#include "stg/resetable.h"
+#include "stg/os_int.h"
+
+#include <string>
+
+namespace SGCONF
+{
+
+struct CONFIG
+{
+    RESETABLE<std::string> configFile;
+    RESETABLE<std::string> server;
+    RESETABLE<uint16_t> port;
+    RESETABLE<std::string> userName;
+    RESETABLE<std::string> userPass;
+
+    CONFIG & operator=(const CONFIG & rhs)
+    {
+    if (!rhs.configFile.empty())
+        configFile = rhs.configFile;
+    if (!rhs.server.empty())
+        server = rhs.server;
+    if (!rhs.port.empty())
+        port = rhs.port;
+    if (!rhs.userName.empty())
+        userName = rhs.userName;
+    if (!rhs.userPass.empty())
+        userPass = rhs.userPass;
+    return *this;
+    }
+
+    std::string Serialize() const
+    {
+    std::string res("{ ");
+    if (!configFile.empty())
+        res += "configFile: '" + configFile.data() + "'";
+    if (!server.empty())
+        res += ", server: '" + server.data() + "'";
+    if (!port.empty())
+        res += ", port: " + x2str(port.data());
+    if (!userName.empty())
+        res += ", userName: '" + userName.data() + "'";
+    if (!userPass.empty())
+        res += ", userPass: '" + userPass.data() + "'";
+    return res + " }";
+    }
+};
+
+}
+
+#endif
index 2aaacbc01d2e5e4d723f32d1d42f37de7a376008..a0ef89a1e632171c3ba977a32bc3dc4d96ce22bf 100644 (file)
 
 /*
  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
  */
 
- /*
- $Author: faust $
- $Revision: 1.25 $
- $Date: 2010/03/25 14:37:43 $
- */
+#include "request.h"
+#include "common_sg.h"
+#include "sg_error_codes.h"
 
-#include <unistd.h>
-#include <getopt.h>
-#include <iconv.h>
-#include <langinfo.h>
+#include "options.h"
+#include "actions.h"
+#include "config.h"
+
+#include "stg/user_conf.h"
+#include "stg/user_stat.h"
+#include "stg/common.h"
 
 #include <cerrno>
 #include <clocale>
 #include <cstdio>
+#include <cstdlib>
 #include <cstring>
 #include <string>
-#include <list>
 #include <sstream>
 
-#include "stg/common.h"
-#include "stg/netunit.h"
-#include "request.h"
-#include "common_sg.h"
-#include "sg_error_codes.h"
+#include <unistd.h>
+#include <getopt.h>
+#include <iconv.h>
+#include <langinfo.h>
+
+namespace
+{
 
-using namespace std;
+template <typename T>
+struct ARRAY_TYPE
+{
+typedef typename T::value_type type;
+};
 
-time_t stgTime;
+template <typename T>
+struct ARRAY_TYPE<T[]>
+{
+typedef T type;
+};
 
-int ParseReplyGet(void * data, list<string> * ans);
-//int ParseReplySet(void * data, list<string> * ans);
+template <typename T, size_t N>
+struct ARRAY_TYPE<T[N]>
+{
+typedef T type;
+};
+
+template <typename T>
+struct nullary_function
+{
+typedef T result_type;
+};
+
+template <typename F>
+class binder0 : public nullary_function<typename F::result_type>
+{
+    public:
+        binder0(const F & func, const typename F::argument_type & arg)
+            : m_func(func), m_arg(arg) {}
+        typename F::result_type operator()() const { return m_func(m_arg); }
+    private:
+        F m_func;
+        typename F::argument_type m_arg;
+};
+
+template <typename F>
+inline
+binder0<F> bind0(const F & func, const typename F::argument_type & arg)
+{
+return binder0<F>(func, arg);
+}
+
+template <typename C, typename A, typename R>
+class METHOD1_ADAPTER : public std::unary_function<A, R>
+{
+    public:
+        METHOD1_ADAPTER(R (C::* func)(A), C & obj) : m_func(func), m_obj(obj) {}
+        R operator()(A arg) { return (m_obj.*m_func)(arg); }
+    private:
+        R (C::* m_func)(A);
+        C & m_obj;
+};
+
+template <typename C, typename A, typename R>
+class CONST_METHOD1_ADAPTER : public std::unary_function<A, R>
+{
+    public:
+        CONST_METHOD1_ADAPTER(R (C::* func)(A) const, C & obj) : m_func(func), m_obj(obj) {}
+        R operator()(A arg) const { return (m_obj.*m_func)(arg); }
+    private:
+        R (C::* m_func)(A) const;
+        C & m_obj;
+};
+
+template <typename C, typename A, typename R>
+METHOD1_ADAPTER<C, A, R> Method1Adapt(R (C::* func)(A), C & obj)
+{
+return METHOD1_ADAPTER<C, A, R>(func, obj);
+}
+
+template <typename C, typename A, typename R>
+CONST_METHOD1_ADAPTER<C, A, R> Method1Adapt(R (C::* func)(A) const, C & obj)
+{
+return CONST_METHOD1_ADAPTER<C, A, R>(func, obj);
+}
+
+template <typename T>
+bool SetArrayItem(T & array, const char * index, const typename ARRAY_TYPE<T>::type & value)
+{
+size_t pos = 0;
+if (str2x(index, pos))
+    return false;
+array[pos] = value;
+return true;
+}
+
+void Usage();
+void UsageAll();
+void UsageImpl(bool full);
+void UsageConnection();
+void UsageAdmins(bool full);
+void UsageTariffs(bool full);
+void UsageUsers(bool full);
+void UsageServices(bool full);
+void UsageCorporations(bool full);
+
+void Version();
+
+void ReadUserConfigFile(SGCONF::OPTION_BLOCK & block)
+{
+std::vector<std::string> paths;
+const char * configHome = getenv("XDG_CONFIG_HOME");
+if (configHome == NULL)
+    {
+    const char * home = getenv("HOME");
+    if (home == NULL)
+        return;
+    paths.push_back(std::string(home) + "/.config/sgconf/sgconf.conf");
+    paths.push_back(std::string(home) + "/.sgconf/sgconf.conf");
+    }
+else
+    paths.push_back(std::string(configHome) + "/sgconf/sgconf.conf");
+for (std::vector<std::string>::const_iterator it = paths.begin(); it != paths.end(); ++it)
+    if (access(it->c_str(), R_OK) == 0)
+        {
+        block.ParseFile(*it);
+        return;
+        }
+}
+
+} // namespace anonymous
+
+namespace SGCONF
+{
+
+class CONFIG_ACTION : public ACTION
+{
+    public:
+        CONFIG_ACTION(CONFIG & config,
+                      const std::string & paramDescription)
+            : m_config(config),
+              m_description(paramDescription)
+        {}
+
+        virtual ACTION * Clone() const { return new CONFIG_ACTION(*this); }
+
+        virtual std::string ParamDescription() const { return m_description; }
+        virtual std::string DefaultDescription() const { return ""; }
+        virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
+        virtual PARSER_STATE Parse(int argc, char ** argv);
+
+    private:
+        CONFIG & m_config;
+        std::string m_description;
+        OPTION_BLOCK m_suboptions;
+
+        void ParseCredentials(const std::string & credentials);
+        void ParseHostAndPort(const std::string & hostAndPort);
+};
+
+PARSER_STATE CONFIG_ACTION::Parse(int argc, char ** argv)
+{
+if (argc == 0 ||
+    argv == NULL ||
+    *argv == NULL)
+    throw ERROR("Missing argument.");
+char * pos = strchr(*argv, '@');
+if (pos != NULL)
+    {
+    ParseCredentials(std::string(*argv, pos));
+    ParseHostAndPort(std::string(pos + 1));
+    }
+else
+    {
+    ParseHostAndPort(std::string(*argv));
+    }
+return PARSER_STATE(false, --argc, ++argv);
+}
+
+void CONFIG_ACTION::ParseCredentials(const std::string & credentials)
+{
+std::string::size_type pos = credentials.find_first_of(':');
+if (pos != std::string::npos)
+    {
+    m_config.userName = credentials.substr(0, pos);
+    m_config.userPass = credentials.substr(pos + 1);
+    }
+else
+    {
+    m_config.userName = credentials;
+    }
+}
+
+void CONFIG_ACTION::ParseHostAndPort(const std::string & hostAndPort)
+{
+std::string::size_type pos = hostAndPort.find_first_of(':');
+if (pos != std::string::npos)
+    {
+    m_config.server = hostAndPort.substr(0, pos);
+    uint16_t port = 0;
+    if (str2x(hostAndPort.substr(pos + 1), port))
+        throw ERROR("Invalid port value: '" + hostAndPort.substr(pos + 1) + "'");
+    m_config.port = port;
+    }
+else
+    {
+    m_config.server = hostAndPort;
+    }
+}
+
+inline
+CONFIG_ACTION * MakeParamAction(CONFIG & config,
+                                const std::string & paramDescription)
+{
+return new CONFIG_ACTION(config, paramDescription);
+}
+
+} // namespace SGCONF
+
+time_t stgTime;
 
 struct option long_options_get[] = {
 {"server",      1, 0, 's'},  //Server
@@ -66,37 +275,12 @@ struct option long_options_get[] = {
 {"passive",     0, 0, 'i'},  //passive
 {"disable-stat",0, 0, 'S'},  //disable detail stat
 {"always-online",0, 0, 'O'}, //always online
-{"u0",          0, 0, 500},  //U0
-{"u1",          0, 0, 501},  //U1
-{"u2",          0, 0, 502},  //U2
-{"u3",          0, 0, 503},  //U3
-{"u4",          0, 0, 504},  //U4
-{"u5",          0, 0, 505},  //U5
-{"u6",          0, 0, 506},  //U6
-{"u7",          0, 0, 507},  //U7
-{"u8",          0, 0, 508},  //U8
-{"u9",          0, 0, 509},  //U9
-{"d0",          0, 0, 600},  //D0
-{"d1",          0, 0, 601},  //D1
-{"d2",          0, 0, 602},  //D2
-{"d3",          0, 0, 603},  //D3
-{"d4",          0, 0, 604},  //D4
-{"d5",          0, 0, 605},  //D5
-{"d6",          0, 0, 606},  //D6
-{"d7",          0, 0, 607},  //D7
-{"d8",          0, 0, 608},  //D8
-{"d9",          0, 0, 609},  //D9
-
-{"ud0",         0, 0, 700},  //UserData0
-{"ud1",         0, 0, 701},  //UserData1
-{"ud2",         0, 0, 702},  //UserData2
-{"ud3",         0, 0, 703},  //UserData3
-{"ud4",         0, 0, 704},  //UserData4
-{"ud5",         0, 0, 705},  //UserData5
-{"ud6",         0, 0, 706},  //UserData6
-{"ud7",         0, 0, 707},  //UserData7
-{"ud8",         0, 0, 708},  //UserData8
-{"ud9",         0, 0, 709},  //UserData9
+{"session-upload",   1, 0, 500},  //SU0
+{"session-download", 1, 0, 501},  //SD0
+{"month-upload",     1, 0, 502},  //MU0
+{"month-download",   1, 0, 503},  //MD0
+
+{"user-data",   1, 0, 700},  //UserData0
 
 {"prepaid",     0, 0, 'e'},  //prepaid traff
 {"create",      0, 0, 'n'},  //create
@@ -108,7 +292,8 @@ struct option long_options_get[] = {
 {"email",       0, 0, 'L'},  //emaiL
 {"phone",       0, 0, 'P'},  //phone
 {"group",       0, 0, 'G'},  //Group
-{"ip",         0, 0, 'I'},  //IP-address of user
+{"ip",          0, 0, 'I'},  //IP-address of user
+{"authorized-by",0, 0, 800}, //always online
 
 {0, 0, 0, 0}};
 
@@ -128,37 +313,12 @@ struct option long_options_set[] = {
 {"passive",     1, 0, 'i'},  //passive
 {"disable-stat",1, 0, 'S'},  //disable detail stat
 {"always-online",1, 0, 'O'},  //always online
-{"u0",          1, 0, 500},  //U0
-{"u1",          1, 0, 501},  //U1
-{"u2",          1, 0, 502},  //U2
-{"u3",          1, 0, 503},  //U3
-{"u4",          1, 0, 504},  //U4
-{"u5",          1, 0, 505},  //U5
-{"u6",          1, 0, 506},  //U6
-{"u7",          1, 0, 507},  //U7
-{"u8",          1, 0, 508},  //U8
-{"u9",          1, 0, 509},  //U9
-{"d0",          1, 0, 600},  //D0
-{"d1",          1, 0, 601},  //D1
-{"d2",          1, 0, 602},  //D2
-{"d3",          1, 0, 603},  //D3
-{"d4",          1, 0, 604},  //D4
-{"d5",          1, 0, 605},  //D5
-{"d6",          1, 0, 606},  //D6
-{"d7",          1, 0, 607},  //D7
-{"d8",          1, 0, 608},  //D8
-{"d9",          1, 0, 609},  //D9
-
-{"ud0",         1, 0, 700},  //UserData
-{"ud1",         1, 0, 701},  //UserData1
-{"ud2",         1, 0, 702},  //UserData2
-{"ud3",         1, 0, 703},  //UserData3
-{"ud4",         1, 0, 704},  //UserData4
-{"ud5",         1, 0, 705},  //UserData5
-{"ud6",         1, 0, 706},  //UserData6
-{"ud7",         1, 0, 707},  //UserData7
-{"ud8",         1, 0, 708},  //UserData8
-{"ud9",         1, 0, 709},  //UserData9
+{"session-upload",   1, 0, 500},  //U0
+{"session-download", 1, 0, 501},  //U1
+{"month-upload",     1, 0, 502},  //U2
+{"month-download",   1, 0, 503},  //U3
+
+{"user-data",        1, 0, 700},  //UserData
 
 {"prepaid",     1, 0, 'e'},  //prepaid traff
 {"create",      1, 0, 'n'},  //create
@@ -170,40 +330,33 @@ struct option long_options_set[] = {
 {"email",       1, 0, 'L'},  //emaiL
 {"phone",       1, 0, 'P'},  //phone
 {"group",       1, 0, 'G'},  //Group
-{"ip",         0, 0, 'I'},  //IP-address of user
+{"ip",          0, 0, 'I'},  //IP-address of user
 
 {0, 0, 0, 0}};
 
 //-----------------------------------------------------------------------------
-double ParseCash(const char * c, string * message)
+CASH_INFO ParseCash(const char * str)
 {
 //-c 123.45:log message
-double cash;
-char * msg;
-char * str;
-str = new char[strlen(c) + 1];
-
-strncpy(str, c, strlen(c));
-str[strlen(c)] = 0;
-
-msg = strchr(str, ':');
-
-if (msg)
+std::string cashString;
+std::string message;
+const char * pos = strchr(str, ':');
+if (pos != NULL)
     {
-    *message =  msg + 1;
-    str[msg - str] = 0;
+    cashString.append(str, pos);
+    message.append(pos + 1);
     }
 else
-    *message = "";
+    cashString = str;
 
-if (strtodouble2(str, cash) != 0)
+double cash = 0;
+if (strtodouble2(cashString, cash) != 0)
     {
-    printf("Incorrect cash value %s\n", c);
+    printf("Incorrect cash value %s\n", str);
     exit(PARAMETER_PARSING_ERR_CODE);
     }
 
-delete[] str;
-return cash;
+return CASH_INFO(cash, message);
 }
 //-----------------------------------------------------------------------------
 double ParseCredit(const char * c)
@@ -253,63 +406,24 @@ if (!(dp[1] == 0 && (dp[0] == '1' || dp[0] == '0')))
 return dp[0] - '0';
 }
 //-----------------------------------------------------------------------------
-string ParseTariff(const char * t, int &chgType)
+void ParseTariff(const char * str, RESETABLE<std::string> & tariffName, RESETABLE<std::string> & nextTariff)
 {
-int l = strlen(t);
-char * s;
-s = new char[l];
-char * s1, * s2;
-string ss;
-
-strcpy(s, t);
-
-s1 = strtok(s, ":");
-
-if (strlen(s1) >= TARIFF_NAME_LEN)
+const char * pos = strchr(str, ':');
+if (pos != NULL)
     {
-    printf("Tariff name too big %s\n", s1);
-    exit(PARAMETER_PARSING_ERR_CODE);
-    }
-
-//*tariff = s;
-
-if (CheckLogin(s1))
-    {
-    printf("Incorrect tariff value %s\n", t);
-    exit(PARAMETER_PARSING_ERR_CODE);
-    }
-
-s2 = strtok(NULL, ":");
-
-chgType = -1;
-
-if (s2 == NULL)
-    {
-    chgType = TARIFF_NOW;
-    ss = s;
-    delete[] s;
-    return ss;
-    }
-
-
-if (strcmp(s2, "now") == 0)
-    chgType = TARIFF_NOW;
-
-if (strcmp(s2, "delayed") == 0)
-    chgType = TARIFF_DEL;
-
-if (strcmp(s2, "recalc") == 0)
-    chgType = TARIFF_REC;
-
-if (chgType < 0)
-    {
-    printf("Incorrect tariff value %s\n", t);
-    exit(PARAMETER_PARSING_ERR_CODE);
+    std::string tariff(str, pos);
+    if (strcmp(pos + 1, "now") == 0)
+        tariffName = tariff;
+    else if (strcmp(pos + 1, "delayed") == 0)
+        nextTariff = tariff;
+    else
+        {
+        printf("Incorrect tariff value '%s'. Should be '<tariff>', '<tariff>:now' or '<tariff>:delayed'.\n", str);
+        exit(PARAMETER_PARSING_ERR_CODE);
+        }
     }
-
-ss = s;
-delete[] s;
-return ss;
+else
+    tariffName = str;
 }
 //-----------------------------------------------------------------------------
 time_t ParseCreditExpire(const char * str)
@@ -400,10 +514,10 @@ memset(str, 0, strLen);
 
 r[0] = 0;
 
-if (!req->usrMsg.res_empty())
+if (!req->usrMsg.empty())
     {
     string msg;
-    Encode12str(msg, req->usrMsg);
+    Encode12str(msg, req->usrMsg.data());
     sprintf(str, "<Message login=\"%s\" msgver=\"1\" msgtype=\"1\" repeat=\"0\" repeatperiod=\"0\" showtime=\"0\" text=\"%s\"/>", req->login.const_data().c_str(), msg.c_str());
     //sprintf(str, "<message login=\"%s\" priority=\"0\" text=\"%s\"/>\n", req->login, msg);
     strcat(r, str);
@@ -429,25 +543,25 @@ if (req->createUser)
 strcat(r, "<SetUser>\n");
 sprintf(str, "<login value=\"%s\"/>\n", req->login.const_data().c_str());
 strcat(r, str);
-if (!req->credit.res_empty())
+if (!req->credit.empty())
     {
     sprintf(str, "<credit value=\"%f\"/>\n", req->credit.const_data());
     strcat(r, str);
     }
 
-if (!req->creditExpire.res_empty())
+if (!req->creditExpire.empty())
     {
     sprintf(str, "<creditExpire value=\"%ld\"/>\n", req->creditExpire.const_data());
     strcat(r, str);
     }
 
-if (!req->prepaidTraff.res_empty())
+if (!req->prepaidTraff.empty())
     {
     sprintf(str, "<FreeMb value=\"%f\"/>\n", req->prepaidTraff.const_data());
     strcat(r, str);
     }
 
-if (!req->cash.res_empty())
+if (!req->cash.empty())
     {
     string msg;
     Encode12str(msg, req->message);
@@ -455,7 +569,7 @@ if (!req->cash.res_empty())
     strcat(r, str);
     }
 
-if (!req->setCash.res_empty())
+if (!req->setCash.empty())
     {
     string msg;
     Encode12str(msg, req->message);
@@ -463,38 +577,38 @@ if (!req->setCash.res_empty())
     strcat(r, str);
     }
 
-if (!req->usrPasswd.res_empty())
+if (!req->usrPasswd.empty())
     {
     sprintf(str, "<password value=\"%s\" />\n", req->usrPasswd.const_data().c_str());
     strcat(r, str);
     }
 
-if (!req->down.res_empty())
+if (!req->down.empty())
     {
     sprintf(str, "<down value=\"%d\" />\n", req->down.const_data());
     strcat(r, str);
     }
 
-if (!req->passive.res_empty())
+if (!req->passive.empty())
     {
     sprintf(str, "<passive value=\"%d\" />\n", req->passive.const_data());
     strcat(r, str);
     }
 
-if (!req->disableDetailStat.res_empty())
+if (!req->disableDetailStat.empty())
     {
     sprintf(str, "<disableDetailStat value=\"%d\" />\n", req->disableDetailStat.const_data());
     strcat(r, str);
     }
 
-if (!req->alwaysOnline.res_empty())
+if (!req->alwaysOnline.empty())
     {
     sprintf(str, "<aonline value=\"%d\" />\n", req->alwaysOnline.const_data());
     strcat(r, str);
     }
 
 // IP-address of user
-if (!req->ips.res_empty())
+if (!req->ips.empty())
     {
     sprintf(str, "<ip value=\"%s\" />\n", req->ips.const_data().c_str());
     strcat(r, str);
@@ -504,7 +618,36 @@ int uPresent = false;
 int dPresent = false;
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (!req->u[i].res_empty())
+    if (!req->monthUpload[i].empty())
+        {
+        if (!uPresent && !dPresent)
+            {
+            sprintf(str, "<traff ");
+            strcat(r, str);
+            uPresent = true;
+            }
+
+        stringstream ss;
+        ss << req->monthUpload[i].const_data();
+        //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
+        sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
+        strcat(r, str);
+        }
+    if (!req->monthDownload[i].empty())
+        {
+        if (!uPresent && !dPresent)
+            {
+            sprintf(str, "<traff ");
+            strcat(r, str);
+            dPresent = true;
+            }
+
+        stringstream ss;
+        ss << req->monthDownload[i].const_data();
+        sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
+        strcat(r, str);
+        }
+    if (!req->sessionUpload[i].empty())
         {
         if (!uPresent && !dPresent)
             {
@@ -514,12 +657,12 @@ for (int i = 0; i < DIR_NUM; i++)
             }
 
         stringstream ss;
-        ss << req->u[i].const_data();
+        ss << req->sessionUpload[i].const_data();
         //sprintf(str, "MU%d=\"%lld\" ", i, req->u[i].const_data());
         sprintf(str, "MU%d=\"%s\" ", i, ss.str().c_str());
         strcat(r, str);
         }
-    if (!req->d[i].res_empty())
+    if (!req->sessionDownload[i].empty())
         {
         if (!uPresent && !dPresent)
             {
@@ -529,7 +672,7 @@ for (int i = 0; i < DIR_NUM; i++)
             }
 
         stringstream ss;
-        ss << req->d[i].const_data();
+        ss << req->sessionDownload[i].const_data();
         sprintf(str, "MD%d=\"%s\" ", i, ss.str().c_str());
         strcat(r, str);
         }
@@ -541,7 +684,7 @@ if (uPresent || dPresent)
 
 //printf("%s\n", r);
 
-if (!req->tariff.res_empty())
+if (!req->tariff.empty())
     {
     switch (req->chgTariff)
         {
@@ -561,60 +704,60 @@ if (!req->tariff.res_empty())
 
     }
 
-if (!req->note.res_empty())
+if (!req->note.empty())
     {
     string note;
-    Encode12str(note, req->note);
+    Encode12str(note, req->note.data());
     sprintf(str, "<note value=\"%s\"/>", note.c_str());
     strcat(r, str);
     }
 
-if (!req->name.res_empty())
+if (!req->name.empty())
     {
     string name;
-    Encode12str(name, req->name);
+    Encode12str(name, req->name.data());
     sprintf(str, "<name value=\"%s\"/>", name.c_str());
     strcat(r, str);
     }
 
-if (!req->address.res_empty())
+if (!req->address.empty())
     {
     string address;
-    Encode12str(address, req->address);
+    Encode12str(address, req->address.data());
     sprintf(str, "<address value=\"%s\"/>", address.c_str());
     strcat(r, str);
     }
 
-if (!req->email.res_empty())
+if (!req->email.empty())
     {
     string email;
-    Encode12str(email, req->email);
+    Encode12str(email, req->email.data());
     sprintf(str, "<email value=\"%s\"/>", email.c_str());
     strcat(r, str);
     }
 
-if (!req->phone.res_empty())
+if (!req->phone.empty())
     {
     string phone;
-    Encode12str(phone, req->phone);
+    Encode12str(phone, req->phone.data());
     sprintf(str, "<phone value=\"%s\"/>", phone.c_str());
     strcat(r, str);
     }
 
-if (!req->group.res_empty())
+if (!req->group.empty())
     {
     string group;
-    Encode12str(group, req->group);
+    Encode12str(group, req->group.data());
     sprintf(str, "<group value=\"%s\"/>", group.c_str());
     strcat(r, str);
     }
 
 for (int i = 0; i < USERDATA_NUM; i++)
     {
-    if (!req->ud[i].res_empty())
+    if (!req->userData[i].empty())
         {
         string ud;
-        Encode12str(ud, req->ud[i]);
+        Encode12str(ud, req->userData[i].data());
         sprintf(str, "<userdata%d value=\"%s\"/>", i, ud.c_str());
         strcat(r, str);
         }
@@ -625,30 +768,32 @@ strcat(r, "</SetUser>\n");
 //-----------------------------------------------------------------------------
 int CheckParameters(REQUEST * req)
 {
-int u = false;
-int d = false;
-int ud = false;
-int a = !req->admLogin.res_empty()
-    && !req->admPasswd.res_empty()
-    && !req->server.res_empty()
-    && !req->port.res_empty()
-    && !req->login.res_empty();
-
-int b = !req->cash.res_empty()
-    || !req->setCash.res_empty()
-    || !req->credit.res_empty()
-    || !req->prepaidTraff.res_empty()
-    || !req->tariff.res_empty()
-    || !req->usrMsg.res_empty()
-    || !req->usrPasswd.res_empty()
-
-    || !req->note.res_empty()
-    || !req->name.res_empty()
-    || !req->address.res_empty()
-    || !req->email.res_empty()
-    || !req->phone.res_empty()
-    || !req->group.res_empty()
-    || !req->ips.res_empty()   // IP-address of user
+bool su = false;
+bool sd = false;
+bool mu = false;
+bool md = false;
+bool ud = false;
+bool a = !req->admLogin.empty()
+    && !req->admPasswd.empty()
+    && !req->server.empty()
+    && !req->port.empty()
+    && !req->login.empty();
+
+bool b = !req->cash.empty()
+    || !req->setCash.empty()
+    || !req->credit.empty()
+    || !req->prepaidTraff.empty()
+    || !req->tariff.empty()
+    || !req->usrMsg.empty()
+    || !req->usrPasswd.empty()
+
+    || !req->note.empty()
+    || !req->name.empty()
+    || !req->address.empty()
+    || !req->email.empty()
+    || !req->phone.empty()
+    || !req->group.empty()
+    || !req->ips.empty() // IP-address of user
 
     || !req->createUser
     || !req->deleteUser;
@@ -656,25 +801,43 @@ int b = !req->cash.res_empty()
 
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (req->u[i].res_empty())
+    if (req->sessionUpload[i].empty())
         {
-        u = true;
+        su = true;
         break;
         }
     }
 
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (req->d[i].res_empty())
+    if (req->sessionDownload[i].empty())
         {
-        d = true;
+        sd = true;
         break;
         }
     }
 
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (req->ud[i].res_empty())
+    if (req->monthUpload[i].empty())
+        {
+        mu = true;
+        break;
+        }
+    }
+
+for (int i = 0; i < DIR_NUM; i++)
+    {
+    if (req->monthDownload[i].empty())
+        {
+        md = true;
+        break;
+        }
+    }
+
+for (int i = 0; i < DIR_NUM; i++)
+    {
+    if (req->userData[i].empty())
         {
         ud = true;
         break;
@@ -683,7 +846,7 @@ for (int i = 0; i < DIR_NUM; i++)
 
 
 //printf("a=%d, b=%d, u=%d, d=%d ud=%d\n", a, b, u, d, ud);
-return a && (b || u || d || ud);
+return a && (b || su || sd || mu || md || ud);
 }
 //-----------------------------------------------------------------------------
 int CheckParametersGet(REQUEST * req)
@@ -696,7 +859,7 @@ int CheckParametersSet(REQUEST * req)
 return CheckParameters(req);
 }
 //-----------------------------------------------------------------------------
-int mainGet(int argc, char **argv)
+bool mainGet(int argc, char **argv)
 {
 int c;
 REQUEST req;
@@ -791,10 +954,10 @@ while (1)
         case 'G': //Group
             req.group = " ";
             break;
-       
-       case 'I': //IP-address of user
-           req.ips = " ";
-           break;
+
+        case 'I': //IP-address of user
+            req.ips = " ";
+            break;
 
         case 'S': //Detail stat status
             req.disableDetailStat = " ";
@@ -805,50 +968,33 @@ while (1)
             break;
 
         case 500: //U
+            SetArrayItem(req.sessionUpload, optarg, 1);
+            //req.sessionUpload[optarg] = 1;
+            break;
         case 501:
+            SetArrayItem(req.sessionDownload, optarg, 1);
+            //req.sessionDownload[optarg] = 1;
+            break;
         case 502:
+            SetArrayItem(req.monthUpload, optarg, 1);
+            //req.monthUpload[optarg] = 1;
+            break;
         case 503:
-        case 504:
-        case 505:
-        case 506:
-        case 507:
-        case 508:
-        case 509:
-            //printf("U%d\n", c - 500);
-            req.u[c - 500] = 1;
-            break;
-
-        case 600: //D
-        case 601:
-        case 602:
-        case 603:
-        case 604:
-        case 605:
-        case 606:
-        case 607:
-        case 608:
-        case 609:
-            //printf("D%d\n", c - 600);
-            req.d[c - 600] = 1;
+            SetArrayItem(req.monthDownload, optarg, 1);
+            //req.monthDownload[optarg] = 1;
             break;
 
         case 700: //UserData
-        case 701:
-        case 702:
-        case 703:
-        case 704:
-        case 705:
-        case 706:
-        case 707:
-        case 708:
-        case 709:
-            //printf("UD%d\n", c - 700);
-            req.ud[c - 700] = " ";
+            SetArrayItem(req.userData, optarg, std::string(" "));
+            //req.userData[optarg] = " ";
+            break;
+
+        case 800:
+            req.authBy = true;
             break;
 
         case '?':
         case ':':
-            //printf ("Unknown option \n");
             missedOptionArg = true;
             break;
 
@@ -873,10 +1019,13 @@ if (missedOptionArg || !CheckParametersGet(&req))
     exit(PARAMETER_PARSING_ERR_CODE);
     }
 
-return ProcessGetUser(req.server, req.port, req.admLogin, req.admPasswd, req.login, &req);
+if (req.authBy)
+    return ProcessAuthBy(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data());
+else
+    return ProcessGetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), req);
 }
 //-----------------------------------------------------------------------------
-int mainSet(int argc, char **argv)
+bool mainSet(int argc, char **argv)
 {
 string str;
 
@@ -890,6 +1039,8 @@ const char * short_options_set = "s:p:a:w:u:c:r:t:m:o:d:i:e:v:nlN:A:D:L:P:G:I:S:
 
 int missedOptionArg = false;
 
+USER_CONF_RES conf;
+USER_STAT_RES stat;
 while (1)
     {
     int option_index = -1;
@@ -919,7 +1070,7 @@ while (1)
             break;
 
         case 'o': //change user password
-            req.usrPasswd = ParsePassword(optarg);
+            conf.password = ParsePassword(optarg);
             break;
 
         case 'u': //user
@@ -927,31 +1078,31 @@ while (1)
             break;
 
         case 'c': //add cash
-            req.cash = ParseCash(optarg, &req.message);
+            stat.cashAdd = ParseCash(optarg);
             break;
 
         case 'v': //set cash
-            req.setCash = ParseCash(optarg, &req.message);
+            stat.cashSet = ParseCash(optarg);
             break;
 
         case 'r': //credit
-            req.credit = ParseCredit(optarg);
+            conf.credit = ParseCredit(optarg);
             break;
 
         case 'E': //credit expire
-            req.creditExpire = ParseCreditExpire(optarg);
+            conf.creditExpire = ParseCreditExpire(optarg);
             break;
 
         case 'd': //down
-            req.down = ParseDownPassive(optarg);
+            conf.disabled = ParseDownPassive(optarg);
             break;
 
         case 'i': //passive
-            req.passive = ParseDownPassive(optarg);
+            conf.passive = ParseDownPassive(optarg);
             break;
 
         case 't': //tariff
-            req.tariff = ParseTariff(optarg, req.chgTariff);
+            ParseTariff(optarg, conf.tariffName, conf.nextTariff);
             break;
 
         case 'm': //message
@@ -961,7 +1112,7 @@ while (1)
             break;
 
         case 'e': //Prepaid Traffic
-            req.prepaidTraff = ParsePrepaidTraffic(optarg);
+            stat.freeMb = ParsePrepaidTraffic(optarg);
             break;
 
         case 'n': //Create User
@@ -974,98 +1125,70 @@ while (1)
 
         case 'N': //Note
             ParseAnyString(optarg, &str, "koi8-ru");
-            req.note = str;
+            conf.note = str;
             break;
 
         case 'A': //nAme
             ParseAnyString(optarg, &str, "koi8-ru");
-            req.name = str;
+            conf.realName = str;
             break;
 
         case 'D': //aDdress
             ParseAnyString(optarg, &str, "koi8-ru");
-            req.address = str;
+            conf.address = str;
             break;
 
         case 'L': //emaiL
             ParseAnyString(optarg, &str, "koi8-ru");
-            req.email = str;
-            //printf("EMAIL=%s\n", optarg);
+            conf.email = str;
             break;
 
         case 'P': //phone
             ParseAnyString(optarg, &str);
-            req.phone = str;
+            conf.phone = str;
             break;
 
         case 'G': //Group
             ParseAnyString(optarg, &str, "koi8-ru");
-            req.group = str;
+            conf.group = str;
             break;
 
         case 'I': //IP-address of user
             ParseAnyString(optarg, &str);
-            req.ips = str;
+            conf.ips = StrToIPS(str);
             break;
 
         case 'S':
-            req.disableDetailStat = ParseDownPassive(optarg);
+            conf.disabledDetailStat = ParseDownPassive(optarg);
             break;
 
         case 'O':
-            req.alwaysOnline = ParseDownPassive(optarg);
+            conf.alwaysOnline = ParseDownPassive(optarg);
             break;
 
         case 500: //U
+            SetArrayItem(stat.sessionUp, optarg, ParseTraff(argv[optind++]));
+            break;
         case 501:
+            SetArrayItem(stat.sessionDown, optarg, ParseTraff(argv[optind++]));
+            break;
         case 502:
+            SetArrayItem(stat.monthUp, optarg, ParseTraff(argv[optind++]));
+            break;
         case 503:
-        case 504:
-        case 505:
-        case 506:
-        case 507:
-        case 508:
-        case 509:
-            //printf("U%d\n", c - 500);
-            req.u[c - 500] = ParseTraff(optarg);
-            break;
-
-        case 600: //D
-        case 601:
-        case 602:
-        case 603:
-        case 604:
-        case 605:
-        case 606:
-        case 607:
-        case 608:
-        case 609:
-            //printf("D%d\n", c - 600);
-            req.d[c - 600] = ParseTraff(optarg);
+            SetArrayItem(stat.monthDown, optarg, ParseTraff(argv[optind++]));
             break;
 
         case 700: //UserData
-        case 701:
-        case 702:
-        case 703:
-        case 704:
-        case 705:
-        case 706:
-        case 707:
-        case 708:
-        case 709:
-            ParseAnyString(optarg, &str);
-            //printf("UD%d\n", c - 700);
-            req.ud[c - 700] = str;
+            ParseAnyString(argv[optind++], &str);
+            SetArrayItem(conf.userdata, optarg, str);
             break;
 
         case '?':
-            //printf("Missing option argument\n");
             missedOptionArg = true;
             break;
 
         case ':':
-            //printf("Missing option argument\n");
             missedOptionArg = true;
             break;
 
@@ -1094,12 +1217,85 @@ const int rLen = 20000;
 char rstr[rLen];
 memset(rstr, 0, rLen);
 
-CreateRequestSet(&req, rstr);
-return ProcessSetUser(req.server, req.port, req.admLogin, req.admPasswd, rstr, NULL, isMessage);
+if (isMessage)
+    return ProcessSendMessage(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), req.usrMsg.data());
+
+return ProcessSetUser(req.server.data(), req.port.data(), req.admLogin.data(), req.admPasswd.data(), req.login.data(), conf, stat);
 }
 //-----------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
+SGCONF::CONFIG config;
+
+SGCONF::OPTION_BLOCKS blocks;
+blocks.Add("General options")
+      .Add("c", "config", SGCONF::MakeParamAction(config.configFile, std::string("~/.config/stg/sgconf.conf"), "<config file>"), "override default config file")
+      .Add("h", "help", SGCONF::MakeFunc0Action(bind0(Method1Adapt(&SGCONF::OPTION_BLOCKS::Help, blocks), 0)), "\t\tshow this help and exit")
+      .Add("help-all", SGCONF::MakeFunc0Action(UsageAll), "\t\tshow full help and exit")
+      .Add("v", "version", SGCONF::MakeFunc0Action(Version), "\t\tshow version information and exit");
+SGCONF::OPTION_BLOCK & block = blocks.Add("Connection options")
+      .Add("s", "server", SGCONF::MakeParamAction(config.server, std::string("localhost"), "<address>"), "\t\thost to connect")
+      .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), "<port>"), "\t\tport to connect")
+      .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), "<username>"), "\tadministrative login")
+      .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, "<password>"), "\tpassword for the administrative login")
+      .Add("a", "address", SGCONF::MakeParamAction(config, "<connection string>"), "connection params as a single string in format: <login>:<password>@<host>:<port>");
+
+
+SGCONF::PARSER_STATE state(false, argc, argv);
+
+try
+{
+state = blocks.Parse(--argc, ++argv); // Skipping self name
+}
+catch (const SGCONF::OPTION::ERROR& ex)
+{
+std::cerr << ex.what() << "\n";
+return -1;
+}
+
+if (state.stop)
+    return 0;
+
+if (state.argc > 0)
+    {
+    std::cerr << "Unknown option: '" << *state.argv << "'\n";
+    return -1;
+    }
+
+try
+{
+SGCONF::CONFIG configOverride(config);
+
+if (config.configFile.empty())
+    {
+    const char * mainConfigFile = "/etc/sgconf/sgconf.conf";
+    if (access(mainConfigFile, R_OK) == 0)
+        block.ParseFile(mainConfigFile);
+    ReadUserConfigFile(block);
+    }
+else
+    {
+    block.ParseFile(config.configFile.data());
+    }
+
+config = configOverride;
+}
+catch (const std::exception& ex)
+{
+std::cerr << ex.what() << "\n";
+return -1;
+}
+
+std::cerr << "Config: " << config.Serialize() << std::endl;
+
+return 0;
+
+if (argc < 2)
+    {
+    Usage();
+    return 1;
+    }
+
 if (argc <= 2)
     {
     UsageConf();
@@ -1114,7 +1310,9 @@ if (strcmp(argv[1], "get") == 0)
 else if (strcmp(argv[1], "set") == 0)
     {
     //printf("set\n");
-    return mainSet(argc - 1, argv + 1);
+    if (mainSet(argc - 1, argv + 1) )
+        return 0;
+    return -1;
     }
 else
     {
@@ -1125,3 +1323,213 @@ return UNKNOWN_ERR_CODE;
 }
 //-----------------------------------------------------------------------------
 
+namespace
+{
+
+void Usage()
+{
+UsageImpl(false);
+}
+
+void UsageAll()
+{
+UsageImpl(true);
+}
+
+void UsageImpl(bool full)
+{
+std::cout << "sgconf is the Stargazer management utility.\n\n"
+          << "Usage:\n"
+          << "\tsgconf [options]\n\n"
+          << "General options:\n"
+          << "\t-c, --config <config file>\t\toverride default config file (default: \"~/.config/stg/sgconf.conf\")\n"
+          << "\t-h, --help\t\t\t\tshow this help and exit\n"
+          << "\t--help-all\t\t\t\tshow full help and exit\n"
+          << "\t-v, --version\t\t\t\tshow version information and exit\n\n";
+UsageConnection();
+UsageAdmins(full);
+UsageTariffs(full);
+UsageUsers(full);
+UsageServices(full);
+UsageCorporations(full);
+}
+//-----------------------------------------------------------------------------
+void UsageConnection()
+{
+std::cout << "Connection options:\n"
+          << "\t-s, --server <address>\t\t\thost to connect (ip or domain name, default: \"localhost\")\n"
+          << "\t-p, --port <port>\t\t\tport to connect (default: \"5555\")\n"
+          << "\t-u, --username <username>\t\tadministrative login (default: \"admin\")\n"
+          << "\t-w, --userpass <password>\t\tpassword for administrative login\n"
+          << "\t-a, --address <connection string>\tconnection params as a single string in format: <login>:<password>@<host>:<port>\n\n";
+}
+//-----------------------------------------------------------------------------
+void UsageAdmins(bool full)
+{
+std::cout << "Admins management options:\n"
+          << "\t--get-admins\t\t\t\tget a list of admins (subsequent options will define what to show)\n";
+if (full)
+    std::cout << "\t\t--login\t\t\t\tshow admin's login\n"
+              << "\t\t--priv\t\t\t\tshow admin's priviledges\n\n";
+std::cout << "\t--get-admin\t\t\t\tget the information about admin\n";
+if (full)
+    std::cout << "\t\t--login <login>\t\t\tlogin of the admin to show\n"
+              << "\t\t--priv\t\t\t\tshow admin's priviledges\n\n";
+std::cout << "\t--add-admin\t\t\t\tadd a new admin\n";
+if (full)
+    std::cout << "\t\t--login <login>\t\t\tlogin of the admin to add\n"
+              << "\t\t--password <password>\t\tpassword of the admin to add\n"
+              << "\t\t--priv <priv number>\t\tpriviledges of the admin to add\n\n";
+std::cout << "\t--del-admin\t\t\t\tdelete an existing admin\n";
+if (full)
+    std::cout << "\t\t--login <login>\t\t\tlogin of the admin to delete\n\n";
+std::cout << "\t--chg-admin\t\t\t\tchange an existing admin\n";
+if (full)
+    std::cout << "\t\t--login <login>\t\t\tlogin of the admin to change\n"
+              << "\t\t--priv <priv number>\t\tnew priviledges\n\n";
+}
+//-----------------------------------------------------------------------------
+void UsageTariffs(bool full)
+{
+std::cout << "Tariffs management options:\n"
+          << "\t--get-tariffs\t\t\t\tget a list of tariffs (subsequent options will define what to show)\n";
+if (full)
+    std::cout << "\t\t--name\t\t\t\tshow tariff's name\n"
+              << "\t\t--fee\t\t\t\tshow tariff's fee\n"
+              << "\t\t--free\t\t\t\tshow tariff's prepaid traffic in terms of cost\n"
+              << "\t\t--passive-cost\t\t\tshow tariff's cost of \"freeze\"\n"
+              << "\t\t--traff-type\t\t\tshow what type of traffix will be accounted by the tariff\n"
+              << "\t\t--dirs\t\t\t\tshow tarification rules for directions\n\n";
+std::cout << "\t--get-tariff\t\t\t\tget the information about tariff\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the tariff to show\n"
+              << "\t\t--fee\t\t\t\tshow tariff's fee\n"
+              << "\t\t--free\t\t\t\tshow tariff's prepaid traffic in terms of cost\n"
+              << "\t\t--passive-cost\t\t\tshow tariff's cost of \"freeze\"\n"
+              << "\t\t--traff-type\t\t\tshow what type of traffix will be accounted by the tariff\n"
+              << "\t\t--dirs\t\t\t\tshow tarification rules for directions\n\n";
+std::cout << "\t--add-tariff\t\t\t\tadd a new tariff\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the tariff to add\n"
+              << "\t\t--fee <fee>\t\t\tstariff's fee\n"
+              << "\t\t--free <free>\t\t\ttariff's prepaid traffic in terms of cost\n"
+              << "\t\t--passive-cost <cost>\t\ttariff's cost of \"freeze\"\n"
+              << "\t\t--traff-type <type>\t\twhat type of traffi will be accounted by the tariff\n"
+              << "\t\t--times <times>\t\t\tslash-separated list of \"day\" time-spans (in form \"hh:mm-hh:mm\") for each direction\n"
+              << "\t\t--prices-day-a <prices>\t\tslash-separated list of prices for \"day\" traffic before threshold for each direction\n"
+              << "\t\t--prices-night-a <prices>\tslash-separated list of prices for \"night\" traffic before threshold for each direction\n"
+              << "\t\t--prices-day-b <prices>\t\tslash-separated list of prices for \"day\" traffic after threshold for each direction\n"
+              << "\t\t--prices-night-b <prices>\tslash-separated list of prices for \"night\" traffic after threshold for each direction\n"
+              << "\t\t--single-prices <yes|no>\tslash-separated list of \"single price\" flags for each direction\n"
+              << "\t\t--no-discounts <yes|no>\t\tslash-separated list of \"no discount\" flags for each direction\n"
+              << "\t\t--thresholds <thresholds>\tslash-separated list of thresholds (in Mb) for each direction\n\n";
+std::cout << "\t--del-tariff\t\t\t\tdelete an existing tariff\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the tariff to delete\n\n";
+std::cout << "\t--chg-tariff\t\t\t\tchange an existing tariff\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the tariff to change\n"
+              << "\t\t--fee <fee>\t\t\tstariff's fee\n"
+              << "\t\t--free <free>\t\t\ttariff's prepaid traffic in terms of cost\n"
+              << "\t\t--passive-cost <cost>\t\ttariff's cost of \"freeze\"\n"
+              << "\t\t--traff-type <type>\t\twhat type of traffix will be accounted by the tariff\n"
+              << "\t\t--dir <N>\t\t\tnumber of direction data to change\n"
+              << "\t\t\t--time <time>\t\t\"day\" time-span (in form \"hh:mm-hh:mm\")\n"
+              << "\t\t\t--price-day-a <price>\tprice for \"day\" traffic before threshold\n"
+              << "\t\t\t--price-night-a <price>\tprice for \"night\" traffic before threshold\n"
+              << "\t\t\t--price-day-b <price>\tprice for \"day\" traffic after threshold\n"
+              << "\t\t\t--price-night-b <price>\tprice for \"night\" traffic after threshold\n"
+              << "\t\t\t--single-price <yes|no>\t\"single price\" flag\n"
+              << "\t\t\t--no-discount <yes|no>\t\"no discount\" flag\n"
+              << "\t\t\t--threshold <threshold>\tthreshold (in Mb)\n\n";
+}
+//-----------------------------------------------------------------------------
+void UsageUsers(bool full)
+{
+std::cout << "Users management options:\n"
+          << "\t--get-users\t\t\t\tget a list of users (subsequent options will define what to show)\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--get-user\t\t\t\tget the information about user\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--add-user\t\t\t\tadd a new user\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--del-user\t\t\t\tdelete an existing user\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--chg-user\t\t\t\tchange an existing user\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--check-user\t\t\t\tcheck credentials is valid\n";
+if (full)
+    std::cout << "\n\n";
+std::cout << "\t--send-message\t\t\t\tsend a message to a user\n";
+if (full)
+    std::cout << "\n\n";
+}
+//-----------------------------------------------------------------------------
+void UsageServices(bool full)
+{
+std::cout << "Services management options:\n"
+          << "\t--get-services\t\t\t\tget a list of services (subsequent options will define what to show)\n";
+if (full)
+    std::cout << "\t\t--name\t\t\t\tshow service's name\n"
+              << "\t\t--comment\t\t\tshow a comment to the service\n"
+              << "\t\t--cost\t\t\t\tshow service's cost\n"
+              << "\t\t--pay-day\t\t\tshow service's pay day\n\n";
+std::cout << "\t--get-service\t\t\t\tget the information about service\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the service to show\n"
+              << "\t\t--comment\t\t\tshow a comment to the service\n"
+              << "\t\t--cost\t\t\t\tshow service's cost\n"
+              << "\t\t--pay-day\t\t\tshow service's pay day\n\n";
+std::cout << "\t--add-service\t\t\t\tadd a new service\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the service to add\n"
+              << "\t\t--comment <comment>\t\ta comment to the service\n"
+              << "\t\t--cost <cost>\t\t\tservice's cost\n"
+              << "\t\t--pay-day <day>\t\t\tservice's pay day\n\n";
+std::cout << "\t--del-service\t\t\t\tdelete an existing service\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the service to delete\n\n";
+std::cout << "\t--chg-service\t\t\t\tchange an existing service\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the service to change\n"
+              << "\t\t--comment <comment>\t\ta comment to the service\n"
+              << "\t\t--cost <cost>\t\t\tservice's cost\n"
+              << "\t\t--pay-day <day>\t\t\tservice's pay day\n\n";
+}
+//-----------------------------------------------------------------------------
+void UsageCorporations(bool full)
+{
+std::cout << "Corporations management options:\n"
+          << "\t--get-corporations\t\t\tget a list of corporations (subsequent options will define what to show)\n";
+if (full)
+    std::cout << "\t\t--name\t\t\t\tshow corporation's name\n"
+              << "\t\t--cash\t\t\t\tshow corporation's cash\n\n";
+std::cout << "\t--get-corp\t\t\t\tget the information about corporation\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the corporation to show\n"
+              << "\t\t--cash\t\t\t\tshow corporation's cash\n\n";
+std::cout << "\t--add-corp\t\t\t\tadd a new corporation\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the corporation to add\n"
+              << "\t\t--cash <cash>\t\t\tinitial corporation's cash (default: \"0\")\n\n";
+std::cout << "\t--del-corp\t\t\t\tdelete an existing corporation\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the corporation to delete\n\n";
+std::cout << "\t--chg-corp\t\t\t\tchange an existing corporation\n";
+if (full)
+    std::cout << "\t\t--name <name>\t\t\tname of the corporation to change\n"
+              << "\t\t--add-cash <amount>[:<message>]\tadd cash to the corporation's account and optional comment message\n"
+              << "\t\t--set-cash <cash>[:<message>]\tnew corporation's cash and optional comment message\n\n";
+}
+
+void Version()
+{
+std::cout << "sgconf, version: 2.0.0-alpha.\n";
+}
+
+} // namespace anonymous
diff --git a/projects/sgconf/options.cpp b/projects/sgconf/options.cpp
new file mode 100644 (file)
index 0000000..6a4eef1
--- /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 "options.h"
+
+#include "action.h"
+#include "parser_state.h"
+
+#include "stg/common.h"
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include <functional>
+#include <algorithm>
+
+#include <unistd.h>
+
+namespace
+{
+
+template <class C>
+void ReadConfigFile(const std::string & filePath, void (C::* callback)(const std::string&, const std::string&), C * obj)
+{
+std::ifstream stream(filePath.c_str());
+std::string line;
+size_t num = 0;
+while (std::getline(stream, line))
+    {
+    ++num;
+    line = Trim(line);
+    std::string::size_type pos = line.find_first_of('#');
+    if (pos != std::string::npos)
+        line = line.substr(0, pos);
+    if (line.empty())
+        continue;
+    pos = line.find_first_of('=');
+    if (pos == std::string::npos)
+        {
+        std::ostringstream error;
+        error << "Bad file format, missing '=' in '" << filePath << ":" << num << "'.";
+        throw std::runtime_error(error.str().c_str());
+        }
+    (obj->*callback)(Trim(line.substr(0, pos)), Trim(line.substr(pos + 1, line.length() - pos - 1)));
+    }
+}
+
+} // namespace anonymous
+
+using SGCONF::OPTION;
+using SGCONF::OPTION_BLOCK;
+using SGCONF::OPTION_BLOCKS;
+using SGCONF::ACTION;
+using SGCONF::PARSER_STATE;
+
+OPTION::OPTION(const std::string & shortName,
+               const std::string & longName,
+               ACTION * action,
+               const std::string & description)
+    : m_shortName(shortName),
+      m_longName(longName),
+      m_action(action),
+      m_description(description)
+{
+}
+
+OPTION::OPTION(const std::string & longName,
+               ACTION * action,
+               const std::string & description)
+    : m_longName(longName),
+      m_action(action),
+      m_description(description)
+{
+}
+
+OPTION::OPTION(const OPTION & rhs)
+    : m_shortName(rhs.m_shortName),
+      m_longName(rhs.m_longName),
+      m_action(rhs.m_action->Clone()),
+      m_description(rhs.m_description)
+{
+}
+
+OPTION::~OPTION()
+{
+delete m_action;
+}
+
+OPTION & OPTION::operator=(const OPTION & rhs)
+{
+m_shortName = rhs.m_shortName;
+m_longName = rhs.m_longName;
+m_action = rhs.m_action->Clone();
+m_description = rhs.m_description;
+return *this;
+}
+
+void OPTION::Help(size_t level) const
+{
+if (!m_action)
+    throw ERROR("Option is not defined.");
+std::string indent(level, '\t');
+std::cout << indent << "\t";
+if (!m_shortName.empty())
+    std::cout << "-" << m_shortName << ", ";
+std::cout << "--" << m_longName << " " << m_action->ParamDescription()
+          << "\t" << m_description << m_action->DefaultDescription() << "\n";
+m_action->Suboptions().Help(level + 1);
+}
+
+bool OPTION::Check(const char * arg) const
+{
+if (arg == NULL)
+    return false;
+
+if (*arg++ != '-')
+    return false;
+
+if (*arg == '-')
+    return m_longName == arg + 1;
+
+return m_shortName == arg;
+}
+
+PARSER_STATE OPTION::Parse(int argc, char ** argv)
+{
+if (!m_action)
+    throw ERROR("Option is not defined.");
+try
+    {
+    return m_action->Parse(argc, argv);
+    }
+catch (const ACTION::ERROR & ex)
+    {
+    if (m_longName.empty())
+        throw ERROR("-" + m_shortName + ": " + ex.what());
+    else
+        throw ERROR("--" + m_longName + ", -" + m_shortName + ": " + ex.what());
+    }
+}
+
+void OPTION::ParseValue(const std::string & value)
+{
+if (!m_action)
+    throw ERROR("Option is not defined.");
+try
+    {
+    return m_action->ParseValue(value);
+    }
+catch (const ACTION::ERROR & ex)
+    {
+    throw ERROR(m_longName + ": " + ex.what());
+    }
+}
+
+OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & shortName,
+                                 const std::string & longName,
+                                 ACTION * action,
+                                 const std::string & description)
+{
+m_options.push_back(OPTION(shortName, longName, action, description));
+return *this;
+}
+
+OPTION_BLOCK & OPTION_BLOCK::Add(const std::string & longName,
+                                 ACTION * action,
+                                 const std::string & description)
+{
+m_options.push_back(OPTION(longName, action, description));
+return *this;
+}
+
+void OPTION_BLOCK::Help(size_t level) const
+{
+if (m_options.empty())
+    return;
+std::cout << m_description << ":\n";
+std::for_each(m_options.begin(),
+              m_options.end(),
+              std::bind2nd(std::mem_fun_ref(&OPTION::Help), level + 1));
+}
+
+PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv)
+{
+PARSER_STATE state(false, argc, argv);
+while (state.argc > 0 && !state.stop)
+    {
+    std::vector<OPTION>::iterator it = std::find_if(m_options.begin(), m_options.end(), std::bind2nd(std::mem_fun_ref(&OPTION::Check), *state.argv));
+    if (it != m_options.end())
+        state = it->Parse(--state.argc, ++state.argv);
+    else
+        break;
+    ++it;
+    }
+return state;
+}
+
+void OPTION_BLOCK::ParseFile(const std::string & filePath)
+{
+if (access(filePath.c_str(), R_OK))
+    throw ERROR("File '" + filePath + "' does not exists.");
+ReadConfigFile(filePath, &OPTION_BLOCK::OptionCallback, this);
+}
+
+void OPTION_BLOCK::OptionCallback(const std::string & key, const std::string & value)
+{
+for (std::vector<OPTION>::iterator it = m_options.begin(); it != m_options.end(); ++it)
+    if (it->Name() == key)
+        it->ParseValue(value);
+}
+
+void OPTION_BLOCKS::Help(size_t level) const
+{
+std::list<OPTION_BLOCK>::const_iterator it(m_blocks.begin());
+while (it != m_blocks.end())
+    {
+    it->Help(level);
+    std::cout << "\n";
+    ++it;
+    }
+}
+
+PARSER_STATE OPTION_BLOCKS::Parse(int argc, char ** argv)
+{
+PARSER_STATE state(false, argc, argv);
+std::list<OPTION_BLOCK>::iterator it(m_blocks.begin());
+while (!state.stop && it != m_blocks.end())
+    {
+    state = it->Parse(state.argc, state.argv);
+    ++it;
+    }
+return state;
+}
diff --git a/projects/sgconf/options.h b/projects/sgconf/options.h
new file mode 100644 (file)
index 0000000..6b33ee8
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *    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 __STG_SGCONF_OPTIONS_H__
+#define __STG_SGCONF_OPTIONS_H__
+
+#include <string>
+#include <vector>
+#include <list>
+#include <utility>
+#include <stdexcept>
+#include <cstddef> // size_t
+
+namespace SGCONF
+{
+
+class ACTION;
+struct PARSER_STATE;
+
+class OPTION
+{
+    public:
+        OPTION(const std::string & shortName,
+               const std::string & longName,
+               ACTION * action,
+               const std::string & description);
+        OPTION(const std::string & longName,
+               ACTION * action,
+               const std::string & description);
+        OPTION(const OPTION & rhs);
+        ~OPTION();
+
+        OPTION & operator=(const OPTION & rhs);
+
+        void Help(size_t level = 0) const;
+        PARSER_STATE Parse(int argc, char ** argv);
+        void ParseValue(const std::string & value);
+        bool Check(const char * arg) const;
+        const std::string & Name() const { return m_longName; }
+
+        class ERROR : public std::runtime_error
+        {
+            public:
+                ERROR(const std::string & message)
+                    : std::runtime_error(message.c_str()) {}
+        };
+
+    private:
+        std::string m_shortName;
+        std::string m_longName;
+        ACTION * m_action;
+        std::string m_description;
+};
+
+class OPTION_BLOCK
+{
+    public:
+        OPTION_BLOCK() {}
+        OPTION_BLOCK(const std::string & description)
+            : m_description(description) {}
+        OPTION_BLOCK & Add(const std::string & shortName,
+                           const std::string & longName,
+                           ACTION * action,
+                           const std::string & description);
+        OPTION_BLOCK & Add(const std::string & longName,
+                           ACTION * action,
+                           const std::string & description);
+
+        void Help(size_t level) const;
+
+        PARSER_STATE Parse(int argc, char ** argv);
+        void ParseFile(const std::string & filePath);
+
+        class ERROR : public std::runtime_error
+        {
+            public:
+                ERROR(const std::string & message)
+                    : std::runtime_error(message.c_str()) {}
+        };
+
+    private:
+        std::vector<OPTION> m_options;
+        std::string m_description;
+
+        void OptionCallback(const std::string & key, const std::string & value);
+};
+
+class OPTION_BLOCKS
+{
+    public:
+        OPTION_BLOCK & Add(const std::string & description)
+        { m_blocks.push_back(OPTION_BLOCK(description)); return m_blocks.back(); }
+        void Help(size_t level) const;
+        PARSER_STATE Parse(int argc, char ** argv);
+
+    private:
+        std::list<OPTION_BLOCK> m_blocks;
+};
+
+} // namespace SGCONF
+
+#endif
diff --git a/projects/sgconf/parser_state.h b/projects/sgconf/parser_state.h
new file mode 100644 (file)
index 0000000..22ad794
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *    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 __STG_SGCONF_PARSER_STATE_H__
+#define __STG_SGCONF_PARSER_STATE_H__
+
+namespace SGCONF
+{
+
+struct PARSER_STATE
+{
+    PARSER_STATE(bool s, int c, char ** v) : stop(s), argc(c), argv(v) {}
+    bool stop;
+    int argc;
+    char ** argv;
+};
+
+}
+
+#endif
index daddec1d3401f6d2eec33d1a2678a98823bd922a..bca3c148e1892f1e0306c2683a3aec8cbb6b81e7 100644 (file)
@@ -49,16 +49,19 @@ struct REQUEST
 REQUEST()
     : chgTariff(false),
       createUser(false),
-      deleteUser(false)
+      deleteUser(false),
+      authBy(false)
 {
     for (int i = 0; i < DIR_NUM; i++)
         {
-        u[i].reset();
-        d[i].reset();
+        sessionUpload[i].reset();
+        sessionDownload[i].reset();
+        monthUpload[i].reset();
+        monthDownload[i].reset();
         }
 
     for (int i = 0; i < USERDATA_NUM; i++)
-        ud[i].reset();
+        userData[i].reset();
 }
 
 RESETABLE<string>   server;
@@ -75,6 +78,7 @@ RESETABLE<double>   setCash;
 string              message;
 bool                createUser;
 bool                deleteUser;
+bool                authBy;
 
 RESETABLE<string>   usrMsg;
 RESETABLE<double>   credit;
@@ -86,10 +90,13 @@ RESETABLE<bool>     disableDetailStat;
 RESETABLE<bool>     alwaysOnline;
 RESETABLE<double>   prepaidTraff;
 
-RESETABLE<int64_t>  u[DIR_NUM];
-RESETABLE<int64_t>  d[DIR_NUM];
+RESETABLE<int64_t>  sessionUpload[DIR_NUM];
+RESETABLE<int64_t>  sessionDownload[DIR_NUM];
 
-RESETABLE<string>   ud[USERDATA_NUM];
+RESETABLE<int64_t>  monthUpload[DIR_NUM];
+RESETABLE<int64_t>  monthDownload[DIR_NUM];
+
+RESETABLE<string>   userData[USERDATA_NUM];
 
 RESETABLE<string>   note;
 RESETABLE<string>   name;
index 6816a4362647ab793ade6b7162adb016b28737fd..e9cfb40b478eaba32419daefc104d171a0187e9d 100755 (executable)
@@ -53,15 +53,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but sgconf currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but sgconf currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building sgconf for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building sgconf for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="conffiles.lib
          crypto.lib 
@@ -97,32 +97,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -131,61 +131,61 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 
-echo -n "Checking for -lexpat... "
-echo "int main() { return 0; }" > build_check.c
+printf "Checking for -lexpat... "
+printf "int main() { return 0; }\n" > build_check.c
 $CC $CXXFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_EXPAT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_EXPAT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 rm -f build_check.c
 
 if [ "$CHECK_EXPAT" != "yes" ]
 then
-    echo "-lexpat not found!"
+    printf "-lexpat not found!\n"
     exit 1
 fi
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "ARCH=$ARCH" >> $CONFFILE
-echo "CHECK_EXPAT=$CHECK_EXPAT" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "CHECK_EXPAT=$CHECK_EXPAT\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $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
+printf "\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
 
 $MAKE $MAKEOPTS
 
index 5084bd0dfb6f393efe5a81957dd0410c996f05c6..7e430be2fe4f8438b3ad727862d1b8d5f2649628 100755 (executable)
@@ -54,15 +54,15 @@ fi
 
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but sgconv currently supported by Linux, FreeBSD 4.x, 5.x, 6.x     #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but sgconv currently supported by Linux, FreeBSD 4.x, 5.x, 6.x     #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building sgconv for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building sgconv for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="logger.lib 
           locker.lib
@@ -103,32 +103,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS -L/usr/lib/mysql -L/usr/local/lib/mysql build_check.c -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -137,102 +137,102 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 
-echo -n "Checking for -lfbclient... "
+printf "Checking for -lfbclient... "
 $CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_FBCLIENT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_FBCLIENT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 
-echo -n "Checking for mysql_config... "
+printf "Checking for mysql_config... "
 MYSQL_VERSION=`mysql_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lmysqlclient... "
+    printf "no\n";
+    printf "Checking for -lmysqlclient... "
     $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_MYSQLCLIENT=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes"
-    echo -n "Checking for mysql_config --cflags... "
+    printf "yes\n"
+    printf "Checking for mysql_config --cflags... "
     MYSQL_CFLAGS=`mysql_config --cflags 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$MYSQL_CFLAGS]"
-        echo -n "Checking for mysql_config --libs_r... "
+        printf "[$MYSQL_CFLAGS]\n"
+        printf "Checking for mysql_config --libs_r... "
         MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_MYSQLCLIENT=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_MYSQLCLIENT=yes
-            echo "[$MYSQL_LDFLAGS]"
+            printf "[$MYSQL_LDFLAGS]\n"
         fi
     fi
 fi
 
-echo -n "Checking for pg_config... "
+printf "Checking for pg_config... "
 PG_VERSION=`pg_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lpq... "
+    printf "no\n";
+    printf "Checking for -lpq... "
     $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_PQ=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes";
-    echo -n "Checking for pg_config --includedir... "
+    printf "yes\n";
+    printf "Checking for pg_config --includedir... "
     PG_CFLAGS=`pg_config --includedir 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$PG_CFLAGS]"
-        echo -n "Checking for pg_config --libdir... "
+        printf "[$PG_CFLAGS]\n"
+        printf "Checking for pg_config --libdir... "
         PG_LDFLAGS=`pg_config --libdir 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_PQ=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_PQ=yes
-            echo "[$PG_LDFLAGS]"
+            printf "[$PG_LDFLAGS]\n"
         fi
     fi
 fi
@@ -259,40 +259,40 @@ then
          store/mysql"
 fi
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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 "CHECK_FBCLIENT=$CHECK_FBCLIENT" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "DIR_MOD=\$(DIR_BUILD)/../stargazer/modules\n" >> $CONFFILE
+printf "DIR_PLUGINS=\$(DIR_BUILD)/../stargazer/plugins\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "CHECK_FBCLIENT=$CHECK_FBCLIENT\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo -n "PLUGINS=" >> $CONFFILE
+printf "\n" >> $CONFFILE
+printf "PLUGINS=" >> $CONFFILE
 for plugin in $PLUGINS
 do
-    echo -n "$plugin " >> $CONFFILE
+    printf "$plugin " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $CONFFILE
-echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $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
-echo "VAR_DIR=$VAR_DIR" >> $CONFFILE
+printf "\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
+printf "VAR_DIR=$VAR_DIR\n" >> $CONFFILE
 
 mkdir -p ../stargazer/modules
 
index 9dfc0b51e0cec512172e6a71aef8ce1a46b3d463..aa2b6f90d65f74fa309c3140035a3f52c95c1a82 100644 (file)
@@ -47,7 +47,12 @@ OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
 
 CXXFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
 CFLAGS += $(DEFS) $(STGLIBS_INCS) $(SEARCH_DIRS)
+
+ifneq ($(OS),darwin)
 LDFLAGS += -Wl,-E $(STGLIBS_LIBS)
+endif
+
+LDFLAGS += $(STGLIBS_LIBS)
 
 .PHONY: all clean distclean libs plugins install uninstall install-bin install-data
 all: libs plugins $(PROG)
index a323148b9ed3c9787c58fd029a9d5a9e49060c68..2061d538b189e2f517b948fad8fda182025f680a 100755 (executable)
@@ -72,17 +72,24 @@ then
     MAKE="gmake"
 fi
 
+if [ "$sys" = "Darwin" ]
+then
+    OS=darwin
+    ETC_DIR="./inst/freebsd/etc/stargazer"
+    MAKE="gmake"
+fi
+
 if [ "$OS" = "unknown" ]
 then 
-    echo "#############################################################################"
-    echo "# Sorry, but stargazer currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #"
-    echo "#############################################################################"
+    printf "#############################################################################\n"
+    printf "# Sorry, but stargazer currently supported by Linux, FreeBSD 4.x, 5.x, 6.x  #\n"
+    printf "#############################################################################\n"
     exit 1
 fi
 
-echo "#############################################################################"
-echo "       Building STG 2.4 for $sys $release"
-echo "#############################################################################"
+printf "#############################################################################\n"
+printf "       Building STG 2.4 for $sys $release\n"
+printf "#############################################################################\n"
 
 STG_LIBS="logger.lib 
           locker.lib
@@ -116,12 +123,18 @@ else
         DEFS="$DEFS -DFREE_BSD"
         LIB_THREAD=-lc_r
     else
-        DEFS="$DEFS -DFREE_BSD5"
         if [ "$OS" = "bsd7" ]
         then
+            DEFS="$DEFS -DFREE_BSD5"
             LIB_THREAD=-lpthread
         else
-            LIB_THREAD=-lc_r
+            if [ "$OS" == "darwin" ]
+            then
+                DEFS="$DEFS -DDARWIN"
+                LIB_THREAD=-lpthread
+            else
+                LIB_THREAD=-lc_r
+            fi
         fi
     fi
     PLUGINS="$PLUGINS
@@ -139,32 +152,32 @@ then
     CXX=g++
 fi
 
-echo -n "Checking CC... "
+printf "Checking CC... "
 $CC --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CC not found"
+    printf "FAIL!\n"
+    printf "$CC not found\n"
     exit;
 fi
-echo "found"
-echo -n "Checking CXX... "
+printf "found\n"
+printf "Checking CXX... "
 $CXX --version > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "$CXX not found"
+    printf "FAIL!\n"
+    printf "$CXX not found\n"
     exit;
 fi
-echo "found"
+printf "found\n"
 
-echo -n "Checking endianess... "
-echo "int main() { int probe = 0x00000001; return *(char *)&probe; }" > build_check.c
+printf "Checking endianess... "
+printf "int main() { int probe = 0x00000001; return *(char *)&probe; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -o fake
 if [ $? != 0 ]
 then
-    echo "FAIL!"
-    echo "Endianess checking failed"
+    printf "FAIL!\n"
+    printf "Endianess checking failed\n"
     exit;
 else
     ./fake
@@ -173,179 +186,179 @@ else
         ARCH=le
         CXXFLAGS="$CXXFLAGS -DARCH_LE"
         CFLAGS="$CFLAGS -DARCH_LE"
-        echo "Little Endian"
+        printf "Little Endian\n"
     else
         ARCH=be
         CXXFLAGS="$CXXFLAGS -DARCH_BE"
         CFLAGS="$CFLAGS -DARCH_BE"
-        echo "Big Endian"
+        printf "Big Endian\n"
     fi
 fi
 rm -f fake
 
-echo -n "Checking for -lexpat... "
-echo "int main() { return 0; }" > build_check.c
+printf "Checking for -lexpat... "
+printf "int main() { return 0; }\n" > build_check.c
 $CC $CFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_EXPAT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_EXPAT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 
-echo -n "Checking for -lfbclient... "
+printf "Checking for -lfbclient... "
 $CC $CFLAGS $LDFLAGS build_check.c -lfbclient $LIB_THREAD -o fake > /dev/null 2> /dev/null
 if [ $? != 0 ]
 then
     CHECK_FBCLIENT=no
-    echo "no"
+    printf "no\n"
 else
     CHECK_FBCLIENT=yes
-    echo "yes"
+    printf "yes\n"
 fi
 rm -f fake
 
-echo -n "Checking for mysql_config... "
+printf "Checking for mysql_config... "
 MYSQL_VERSION=`mysql_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lmysqlclient... "
+    printf "no\n";
+    printf "Checking for -lmysqlclient... "
     $CC $CFLAGS $LDFLAGS build_check.c -lmysqlclient_r $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_MYSQLCLIENT=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes"
-    echo -n "Checking for mysql_config --cflags... "
+    printf "yes\n"
+    printf "Checking for mysql_config --cflags... "
     MYSQL_CFLAGS=`mysql_config --cflags 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_MYSQLCLIENT=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$MYSQL_CFLAGS]"
-        echo -n "Checking for mysql_config --libs_r... "
+        printf "[$MYSQL_CFLAGS]\n"
+        printf "Checking for mysql_config --libs_r... "
         MYSQL_LDFLAGS=`mysql_config --libs_r 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_MYSQLCLIENT=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_MYSQLCLIENT=yes
-            echo "[$MYSQL_LDFLAGS]"
+            printf "[$MYSQL_LDFLAGS]\n"
         fi
     fi
 fi
 
-echo -n "Checking for pg_config... "
+printf "Checking for pg_config... "
 PG_VERSION=`pg_config --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lpq... "
+    printf "no\n";
+    printf "Checking for -lpq... "
     $CC $CFLAGS $LDFLAGS build_check.c -lpq $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_PQ=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 else
-    echo "yes";
-    echo -n "Checking for pg_config --includedir... "
+    printf "yes\n";
+    printf "Checking for pg_config --includedir... "
     PG_CFLAGS=`pg_config --includedir 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_PQ=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$PG_CFLAGS]"
-        echo -n "Checking for pg_config --libdir... "
+        printf "[$PG_CFLAGS]\n"
+        printf "Checking for pg_config --libdir... "
         PG_LDFLAGS=`pg_config --libdir 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_PQ=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_PQ=yes
-            echo "[$PG_LDFLAGS]"
+            printf "[$PG_LDFLAGS]\n"
         fi
     fi
 fi
 
-echo -n "Checking for xmlrpc-c-config... "
+printf "Checking for xmlrpc-c-config... "
 XMLRPCC_VERSION=`xmlrpc-c-config $XMLRPC_FEATURES --version 2> /dev/null`
 if [ $? != 0 ]
 then
-    echo "no";
-    echo -n "Checking for -lxmlrpc... "
+    printf "no\n";
+    printf "Checking for -lxmlrpc... "
     $CC $CFLAGS $LDFLAGS build_check.c -lxmlrpc $LIB_THREAD -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_XMLRPC=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_XMLRPC=yes
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 elif [ "$XMLRPCC_VERSION" \< "$MIN_XMLRPCC_VERSION" ]
 then
-    echo "no (need at least $MIN_XMLRPCC_VERSION, actual $XMLRPCC_VERSION)";
+    printf "no (need at least $MIN_XMLRPCC_VERSION, actual $XMLRPCC_VERSION)\n";
     CHECK_XMLRPC=no
 else
-    echo "yes (version $XMLRPCC_VERSION)";
-    echo -n "Checking for xmlrpc-c-config --cflags... "
+    printf "yes (version $XMLRPCC_VERSION)\n";
+    printf "Checking for xmlrpc-c-config --cflags... "
     XMLRPC_CFLAGS=`xmlrpc-c-config $XMLRPC_FEATURES --cflags 2> /dev/null`
     if [ $? != 0 ]
     then
         CHECK_XMLRPC=no
-        echo "no"
+        printf "no\n"
     else
-        echo "[$XMLRPC_CFLAGS]"
-        echo -n "Checking for xmlrpc-c-config --libs... "
+        printf "[$XMLRPC_CFLAGS]\n"
+        printf "Checking for xmlrpc-c-config --libs... "
         XMLRPC_LDFLAGS=`xmlrpc-c-config $XMLRPC_FEATURES --libs 2> /dev/null`
         if [ $? != 0 ]
         then
             CHECK_XMLRPC=no
-            echo "no"
+            printf "no\n"
         else
             CHECK_XMLRPC=yes
-            echo "[$XMLRPC_LDFLAGS]"
+            printf "[$XMLRPC_LDFLAGS]\n"
         fi
     fi
 fi
 
 if [ "$OS" = "linux" ]
 then
-    echo -n "Checking for linux/netfilter_ipv4/ip_queue.h... "
-    echo "#include <linux/types.h>" > build_check.c
-    echo "#include <linux/netfilter_ipv4/ip_queue.h>" >> build_check.c
-    echo "int main() { return 0; }" >> build_check.c
+    printf "Checking for linux/netfilter_ipv4/ip_queue.h... "
+    printf "#include <linux/types.h>\n" > build_check.c
+    printf "#include <linux/netfilter_ipv4/ip_queue.h>\n" >> build_check.c
+    printf "int main() { return 0; }\n" >> build_check.c
     $CC $CFLAGS $LDFLAGS build_check.c -lexpat -o fake > /dev/null 2> /dev/null
     if [ $? != 0 ]
     then
         CHECK_IP_QUEUE_H=no
-        echo "no"
+        printf "no\n"
     else
         CHECK_IP_QUEUE_H=yes
         DEFS="$DEFS -DHAS_IP_QUEUE_H"
         PLUGINS="$PLUGINS
                  capture/ipq_linux"
-        echo "yes"
+        printf "yes\n"
     fi
     rm -f fake
 fi
@@ -354,7 +367,7 @@ rm -f build_check.c
 
 if [ "$CHECK_EXPAT" != "yes" ]
 then
-    echo "-lexpat not found!"
+    printf "-lexpat not found!\n"
     exit 1
 fi
 
@@ -384,45 +397,45 @@ then
              configuration/rpcconfig"
 fi
 
-echo "OS=$OS" > $CONFFILE
-echo "STG_TIME=yes" >> $CONFFILE
-echo "DEBUG=$DEBUG" >> $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)/modules" >> $CONFFILE
-echo "DIR_PLUGINS=\$(DIR_BUILD)/plugins" >> $CONFFILE
-echo "ARCH=$ARCH" >> $CONFFILE
-echo "CHECK_EXPAT=$CHECK_EXPAT" >> $CONFFILE
-echo "CHECK_FBCLIENT=$CHECK_FBCLIENT" >> $CONFFILE
-echo "CHECK_MYSQLCLIENT=$CHECK_MYSQLCLIENT" >> $CONFFILE
-echo "CHECK_PQ=$CHECK_PQ" >> $CONFFILE
-echo "CHECK_XMLRPC=$CHECK_XMLRPC" >> $CONFFILE
-echo "DEFS=$DEFS" >> $CONFFILE
-echo -n "STG_LIBS=" >> $CONFFILE
+printf "OS=$OS\n" > $CONFFILE
+printf "STG_TIME=yes\n" >> $CONFFILE
+printf "DEBUG=$DEBUG\n" >> $CONFFILE
+printf "DIR_BUILD=$BUILD_DIR\n" >> $CONFFILE
+printf "DIR_LIB=\$(DIR_BUILD)/../../lib\n" >> $CONFFILE
+printf "DIR_LIBSRC=\$(DIR_BUILD)/../../stglibs\n" >> $CONFFILE
+printf "DIR_INCLUDE=\$(DIR_BUILD)/../../include\n" >> $CONFFILE
+printf "DIR_MOD=\$(DIR_BUILD)/modules\n" >> $CONFFILE
+printf "DIR_PLUGINS=\$(DIR_BUILD)/plugins\n" >> $CONFFILE
+printf "ARCH=$ARCH\n" >> $CONFFILE
+printf "CHECK_EXPAT=$CHECK_EXPAT\n" >> $CONFFILE
+printf "CHECK_FBCLIENT=$CHECK_FBCLIENT\n" >> $CONFFILE
+printf "CHECK_MYSQLCLIENT=$CHECK_MYSQLCLIENT\n" >> $CONFFILE
+printf "CHECK_PQ=$CHECK_PQ\n" >> $CONFFILE
+printf "CHECK_XMLRPC=$CHECK_XMLRPC\n" >> $CONFFILE
+printf "DEFS=$DEFS\n" >> $CONFFILE
+printf "STG_LIBS=" >> $CONFFILE
 for lib in $STG_LIBS
 do
-    echo -n "$lib " >> $CONFFILE
+    printf "$lib " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo -n "PLUGINS=" >> $CONFFILE
+printf "\n" >> $CONFFILE
+printf "PLUGINS=" >> $CONFFILE
 for plugin in $PLUGINS
 do
-    echo -n "$plugin " >> $CONFFILE
+    printf "$plugin " >> $CONFFILE
 done
-echo "" >> $CONFFILE
-echo "CXXFLAGS=$CXXFLAGS" >> $CONFFILE
-echo "CFLAGS=$CFLAGS" >> $CONFFILE
-echo "LDFLAGS=$LDFLAGS" >> $CONFFILE
-echo "LIB_THREAD=$LIB_THREAD" >> $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
-echo "VAR_DIR=$VAR_DIR" >> $CONFFILE
-echo "ETC_DIR=$ETC_DIR" >> $CONFFILE
+printf "\n" >> $CONFFILE
+printf "CXXFLAGS=$CXXFLAGS\n" >> $CONFFILE
+printf "CFLAGS=$CFLAGS\n" >> $CONFFILE
+printf "LDFLAGS=$LDFLAGS\n" >> $CONFFILE
+printf "LIB_THREAD=$LIB_THREAD\n" >> $CONFFILE
+printf "PREFIX=$PREFIX\n" >> $CONFFILE
+printf "BIN_MODE=$BIN_MODE\n" >> $CONFFILE
+printf "DATA_MODE=$DATA_MODE\n" >> $CONFFILE
+printf "DIR_MODE=$DIR_MODE\n" >> $CONFFILE
+printf "OWNER=$OWNER\n" >> $CONFFILE
+printf "VAR_DIR=$VAR_DIR\n" >> $CONFFILE
+printf "ETC_DIR=$ETC_DIR\n" >> $CONFFILE
 
 mkdir -p modules
 
@@ -430,5 +443,5 @@ if [ "$1" != "debug" ]
 then
     $MAKE $MAKEOPTS
 else
-    echo -e "\n\n\nDebug build. Type $MAKE explicitly"
+    printf "\n\n\nDebug build. Type $MAKE explicitly\n"
 fi
index 69b5eae323f9ab5060489cfe15e590daeb67d4fd..df170dd089203f1e806d100cbe468b732c6c57da 100644 (file)
@@ -8,14 +8,14 @@
 
     # The time interval between sending an alive query to the user
     # and updating statistics
-    # Parameter: required 
+    # Parameter: required
     # Values: 5 ... 600 (seconds)
     # Default: 60
     UserDelay = 60
 
-    # User timeout. If authorizer does not respond during this time, 
+    # User timeout. If authorizer does not respond during this time,
     # the user will be disconnected
-    # Parameter: required 
+    # Parameter: required
     # Values: 5 ... 600
     # Default: 60
     UserTimeout = 65
     # FreeMb = cash - amount of money for which the user can download for free
     # FreeMb = none - no transfer
     # Default: cash
-    # Parameter: required 
+    # Parameter: required
     # Values: different, see above
     # Default: cash
     FreeMb = cash
+
+    # Enable protocol errors logging
+    # Parameter: optional
+    # Values: yes, no
+    # Default: no
+    # LogProtocolErrors = no
 </Module>
index 69b5eae323f9ab5060489cfe15e590daeb67d4fd..df170dd089203f1e806d100cbe468b732c6c57da 100644 (file)
@@ -8,14 +8,14 @@
 
     # The time interval between sending an alive query to the user
     # and updating statistics
-    # Parameter: required 
+    # Parameter: required
     # Values: 5 ... 600 (seconds)
     # Default: 60
     UserDelay = 60
 
-    # User timeout. If authorizer does not respond during this time, 
+    # User timeout. If authorizer does not respond during this time,
     # the user will be disconnected
-    # Parameter: required 
+    # Parameter: required
     # Values: 5 ... 600
     # Default: 60
     UserTimeout = 65
     # FreeMb = cash - amount of money for which the user can download for free
     # FreeMb = none - no transfer
     # Default: cash
-    # Parameter: required 
+    # Parameter: required
     # Values: different, see above
     # Default: cash
     FreeMb = cash
+
+    # Enable protocol errors logging
+    # Parameter: optional
+    # Values: yes, no
+    # Default: no
+    # LogProtocolErrors = no
 </Module>
diff --git a/projects/stargazer/inst/var/01-alter-02.mysql.sql b/projects/stargazer/inst/var/01-alter-02.mysql.sql
new file mode 100644 (file)
index 0000000..1f1b044
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ *  DB migration from v01 to v02 (mysql)
+ */
+
+ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month';
+
+CREATE TABLE info
+(
+    version INTEGER NOT NULL
+);
+
+INSERT INTO info VALUES (1);
diff --git a/projects/stargazer/inst/var/01-alter-02.postgresql.sql b/projects/stargazer/inst/var/01-alter-02.postgresql.sql
new file mode 100644 (file)
index 0000000..ef6a98c
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ *  DB migration from v01 to v02 (postgres)
+ */
+BEGIN;
+
+CREATE DOMAIN DM_TARIFF_PERIOD AS TEXT NOT NULL
+    CONSTRAINT valid_value CHECK (VALUE = 'month' OR VALUE = 'day');
+
+ALTER TABLE tb_tariffs ADD period DM_TARIFF_PERIOD DEFAULT 'month';
+
+UPDATE tb_info SET version = 7;
+
+COMMIT;
diff --git a/projects/stargazer/inst/var/01-alter-02.sql b/projects/stargazer/inst/var/01-alter-02.sql
new file mode 100644 (file)
index 0000000..628a016
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ *  DB migration from v01 to v02 (firebird)
+ */
+
+CREATE DOMAIN DM_TARIFF_PERIOD AS VARCHAR(32) NOT NULL
+    CHECK (VALUE = 'month' OR VALUE = 'day');
+
+ALTER TABLE tb_tariffs ADD period DM_TARIFF_PERIOD DEFAULT 'month';
+
+CREATE TABLE tb_info
+(
+    version INTEGER NOT NULL
+);
+
+INSERT INTO tb_info VALUES (1);
index eb61e2d5d5d31975f50db3d0670acd3765b3ab2f..200fd2a664e15f46e1d2228b20ba6f4db509bdd3 100644 (file)
@@ -106,7 +106,7 @@ else
     }
 }
 //-----------------------------------------------------------------------------
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
 int StartScriptExecuter(char * procName, int msgKey, int * msgID, SETTINGS_IMPL * settings)
 #else
 int StartScriptExecuter(char *, int msgKey, int * msgID, SETTINGS_IMPL * settings)
@@ -151,7 +151,7 @@ switch (executerPid)
 
     case 0:
         delete settings;
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
         Executer(*msgID, executerPid, procName);
 #else
         Executer(*msgID, executerPid);
@@ -160,7 +160,7 @@ switch (executerPid)
 
     default:
         if (executersPid.empty()) {
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
             Executer(*msgID, executerPid, NULL);
 #else
             Executer(*msgID, executerPid);
@@ -464,7 +464,7 @@ while (true)
                 }
             break;
         default:
-            WriteServLog("Ignore signel %d", sig);
+            WriteServLog("Ignore signal %d", sig);
             break;
         }
     if (stop)
index 70954a2a8aef74a5a38d89d021efce16f623632e..dd1e124a32a1e01407d872605a4d490476ed7785 100644 (file)
@@ -9,18 +9,23 @@ OBJS = $(notdir $(patsubst %.cpp, %.o, $(patsubst %.c, %.o, $(SRCS))))
 LN = ln
 
 STGLIBS_INCS = $(addprefix -I ../../../../../stglibs/,$(addsuffix .lib/include,$(STGLIBS)))
-STGLIBS_LIBS = $(addprefix -L ../../../../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
+STGLIBS_PATHS = $(addprefix -L ../../../../../stglibs/,$(addsuffix .lib,$(STGLIBS)))
 
-LIBS += $(addprefix -lstg,$(STGLIBS))
+STGLIBS_LIBS = $(addprefix -lstg,$(STGLIBS))
 
 CXXFLAGS += -fPIC $(STGLIBS_INCS)
 CFLAGS += -fPIC $(STGLIBS_INCS)
+
+ifneq ($(OS),darwin)
 LDFLAGS += -shared -Wl,-rpath,$(PREFIX)/usr/lib/stg
+else
+LDFLAGS += -dynamiclib -undefined suppress -flat_namespace -Wl,-rpath,$(PREFIX)/usr/lib/stg
+endif
 
 all: $(PROG)
 
 $(PROG): $(OBJS)
-       $(CXX) $^ $(STGLIBS_LIBS) $(LIBS) $(LDFLAGS) -o $(PROG)
+       $(CXX) $^ $(STGLIBS_PATHS) $(STGLIBS_LIBS) $(LIBS) $(LDFLAGS) -o $(PROG)
        $(LN) -fs "`pwd`/$(PROG)" $(DIR_MOD)/$(PROG)
 
 clean:
index 1a7697e36972a0f6b6169306d2b6c990b71c0cc5..0e356aa1831a4fc659a4ed471483a20cf16c2397 100644 (file)
@@ -8,10 +8,10 @@ PROG = mod_auth_ao.so
 
 SRCS = ./ao.cpp
 
-STGLIBS = common \
+STGLIBS = scriptexecuter \
          logger \
          locker \
-         scriptexecuter
+         common
 
 include ../../Makefile.in
 
index dd0102b2f0b5bb8ad6311dd46cd9f7da8b477b90..5a15a10aea91cfee72d1614d068c73bab3d61a4c 100644 (file)
@@ -134,6 +134,17 @@ if (ParseIntInRange(pvi->value[0], 15, 1200, &userTimeout))
     printfd(__FILE__, "Cannot parse parameter 'UserTimeout'\n");
     return -1;
     }
+///////////////////////////
+pv.param = "LogProtocolErrors";
+pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
+if (pvi == s.moduleParams.end())
+    logProtocolErrors = false;
+else if (ParseYesNo(pvi->value[0], &logProtocolErrors))
+    {
+    errorStr = "Cannot parse parameter \'LogProtocolErrors\': " + errorStr;
+    printfd(__FILE__, "Cannot parse parameter 'LogProtocolErrors'\n");
+    return -1;
+    }
 /////////////////////////////////////////////////////////////
 std::string freeMbType;
 int n = 0;
@@ -590,8 +601,11 @@ if (dataLen <= 0) // Error
 if (dataLen > 256)
     return -1;
 
+uint32_t sip = outerAddr.sin_addr.s_addr;
+uint16_t sport = htons(outerAddr.sin_port);
+
 int protoVer;
-if (CheckHeader(buffer, &protoVer))
+if (CheckHeader(buffer, sip, &protoVer))
     return -1;
 
 char login[PASSWD_LEN];  //TODO why PASSWD_LEN ?
@@ -599,9 +613,6 @@ memset(login, 0, PASSWD_LEN);
 
 Decrypt(&ctxS, login, buffer + 8, PASSWD_LEN / 8);
 
-uint32_t sip = outerAddr.sin_addr.s_addr;
-uint16_t sport = htons(outerAddr.sin_port);
-
 USER_PTR user;
 if (users->FindByName(login, &user))
     {
@@ -642,12 +653,14 @@ if (!user->GetProperty().ips.Get().IsIPInIPS(sip))
 return PacketProcessor(buffer, dataLen, sip, sport, protoVer, user);
 }
 //-----------------------------------------------------------------------------
-int AUTH_IA::CheckHeader(const char * buffer, int * protoVer)
+int AUTH_IA::CheckHeader(const char * buffer, uint32_t sip, int * protoVer)
 {
 if (strncmp(IA_ID, buffer, strlen(IA_ID)) != 0)
     {
     //SendError(userIP, updateMsg);
     printfd(__FILE__, "update needed - IA_ID\n");
+    if (iaSettings.LogProtocolErrors())
+        logger("IP: %s. Header: invalid packed signature.", inet_ntostring(sip).c_str());
     //SendError(userIP, "Incorrect header!");
     return -1;
     }
@@ -655,6 +668,8 @@ if (strncmp(IA_ID, buffer, strlen(IA_ID)) != 0)
 if (buffer[6] != 0) //proto[0] shoud be 0
     {
     printfd(__FILE__, "update needed - PROTO major: %d\n", buffer[6]);
+    if (iaSettings.LogProtocolErrors())
+        logger("IP: %s. Header: invalid protocol major version: %d.", inet_ntostring(sip).c_str(), buffer[6]);
     //SendError(userIP, updateMsg);
     return -1;
     }
@@ -664,6 +679,8 @@ if (buffer[7] < 6)
     // need update
     //SendError(userIP, updateMsg);
     printfd(__FILE__, "update needed - PROTO minor: %d\n", buffer[7]);
+    if (iaSettings.LogProtocolErrors())
+        logger("IP: %s. Header: invalid protocol minor version: %d.", inet_ntostring(sip).c_str(), buffer[7]);
     return -1;
     }
 else
@@ -691,6 +708,8 @@ while (it != ip2user.end())
     if ((it->second.phase.GetPhase() == 2)
         && (currTime - it->second.phase.GetTime()) > iaSettings.GetUserDelay())
         {
+        if (iaSettings.LogProtocolErrors())
+            logger("User '%s'. Protocol version: %d. Phase 2: connect request timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserDelay());
         it->second.phase.SetPhase1();
         printfd(__FILE__, "Phase changed from 2 to 1. Reason: timeout\n");
         ip2user.erase(it++);
@@ -733,6 +752,8 @@ while (it != ip2user.end())
 
         if ((currTime - it->second.phase.GetTime()) > iaSettings.GetUserTimeout())
             {
+            if (iaSettings.LogProtocolErrors())
+                logger("User '%s'. Protocol version: %d. Phase 3: alive timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserTimeout());
             users->Unauthorize(it->second.user->GetLogin(), this);
             ip2user.erase(it++);
             continue;
@@ -742,6 +763,8 @@ while (it != ip2user.end())
     if ((it->second.phase.GetPhase() == 4)
         && ((currTime - it->second.phase.GetTime()) > iaSettings.GetUserDelay()))
         {
+        if (iaSettings.LogProtocolErrors())
+            logger("User '%s'. Protocol version: %d. Phase 4: disconnect request timeout (%f > %d).", it->second.login.c_str(), it->second.protoVer, (currTime - it->second.phase.GetTime()).AsDouble(), iaSettings.GetUserDelay());
         it->second.phase.SetPhase3();
         printfd(__FILE__, "Phase changed from 4 to 3. Reason: timeout\n");
         }
@@ -1174,6 +1197,8 @@ if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
     else
         {
         errorStr = iaUser->user->GetStrError();
+        if (iaSettings.LogProtocolErrors())
+            logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: phase 2, authorization error ('%s').", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, errorStr.c_str());
         iaUser->phase.SetPhase1();
         ip2user.erase(sip);
         printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
@@ -1181,6 +1206,13 @@ if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
         }
     }
 printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), connAck->rnd);
+if (iaSettings.LogProtocolErrors())
+    {
+    if (iaUser->phase.GetPhase() != 2)
+        logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid phase, expected 2, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
+    if (connAck->rnd != iaUser->rnd + 1)
+        logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), connAck->rnd);
+    }
 return -1;
 }
 //-----------------------------------------------------------------------------
@@ -1210,6 +1242,8 @@ if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
     else
         {
         errorStr = iaUser->user->GetStrError();
+        if (iaSettings.LogProtocolErrors())
+            logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: phase 2, authorization error ('%s').", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, errorStr.c_str());
         iaUser->phase.SetPhase1();
         ip2user.erase(sip);
         printfd(__FILE__, "Phase changed from 2 to 1. Reason: failed to authorize user\n");
@@ -1217,6 +1251,13 @@ if ((iaUser->phase.GetPhase() == 2) && (connAck->rnd == iaUser->rnd + 1))
         }
     }
 printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), connAck->rnd);
+if (iaSettings.LogProtocolErrors())
+    {
+    if (iaUser->phase.GetPhase() != 2)
+        logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid phase, expected 2, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
+    if (connAck->rnd != iaUser->rnd + 1)
+        logger("IP: %s. User '%s'. Protocol version: %d. CONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), connAck->rnd);
+    }
 return -1;
 }
 //-----------------------------------------------------------------------------
@@ -1259,11 +1300,13 @@ if ((iaUser->phase.GetPhase() == 3) && (aliveAck->rnd == iaUser->rnd + 1))
 return 0;
 }
 //-----------------------------------------------------------------------------
-int AUTH_IA::Process_DISCONN_SYN_6(DISCONN_SYN_6 *, IA_USER * iaUser, uint32_t)
+int AUTH_IA::Process_DISCONN_SYN_6(DISCONN_SYN_6 *, IA_USER * iaUser, uint32_t sip)
 {
 printfd(__FILE__, "DISCONN_SYN_6\n");
 if (iaUser->phase.GetPhase() != 3)
     {
+    if (iaSettings.LogProtocolErrors())
+        logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_SYN: invalid phase, expected 3, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
     printfd(__FILE__, "Invalid phase. Expected 3, actual %d\n", iaUser->phase.GetPhase());
     errorStr = "Incorrect request DISCONN_SYN";
     return -1;
@@ -1280,10 +1323,12 @@ int AUTH_IA::Process_DISCONN_SYN_7(DISCONN_SYN_7 * disconnSyn, IA_USER * iaUser,
 return Process_DISCONN_SYN_6(disconnSyn, iaUser, sip);
 }
 //-----------------------------------------------------------------------------
-int AUTH_IA::Process_DISCONN_SYN_8(DISCONN_SYN_8 *, IA_USER * iaUser, uint32_t)
+int AUTH_IA::Process_DISCONN_SYN_8(DISCONN_SYN_8 *, IA_USER * iaUser, uint32_t sip)
 {
 if (iaUser->phase.GetPhase() != 3)
     {
+    if (iaSettings.LogProtocolErrors())
+        logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_SYN: invalid phase, expected 3, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
     errorStr = "Incorrect request DISCONN_SYN";
     printfd(__FILE__, "Invalid phase. Expected 3, actual %d\n", iaUser->phase.GetPhase());
     return -1;
@@ -1297,7 +1342,7 @@ return 0;
 //-----------------------------------------------------------------------------
 int AUTH_IA::Process_DISCONN_ACK_6(DISCONN_ACK_6 * disconnAck,
                                    IA_USER * iaUser,
-                                   uint32_t,
+                                   uint32_t sip,
                                    std::map<uint32_t, IA_USER>::iterator)
 {
 #ifdef ARCH_BE
@@ -1307,6 +1352,13 @@ SwapBytes(disconnAck->rnd);
 printfd(__FILE__, "DISCONN_ACK_6\n");
 if (!((iaUser->phase.GetPhase() == 4) && (disconnAck->rnd == iaUser->rnd + 1)))
     {
+    if (iaSettings.LogProtocolErrors())
+        {
+        if (iaUser->phase.GetPhase() != 4)
+            logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid phase, expected 4, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
+        if (disconnAck->rnd != iaUser->rnd + 1)
+            logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), disconnAck->rnd);
+        }
     printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), disconnAck->rnd);
     return -1;
     }
@@ -1319,7 +1371,7 @@ int AUTH_IA::Process_DISCONN_ACK_7(DISCONN_ACK_7 * disconnAck, IA_USER * iaUser,
 return Process_DISCONN_ACK_6(disconnAck, iaUser, sip, it);
 }
 //-----------------------------------------------------------------------------
-int AUTH_IA::Process_DISCONN_ACK_8(DISCONN_ACK_8 * disconnAck, IA_USER * iaUser, uint32_t, std::map<uint32_t, IA_USER>::iterator)
+int AUTH_IA::Process_DISCONN_ACK_8(DISCONN_ACK_8 * disconnAck, IA_USER * iaUser, uint32_t sip, std::map<uint32_t, IA_USER>::iterator)
 {
 #ifdef ARCH_BE
 SwapBytes(disconnAck->len);
@@ -1328,6 +1380,13 @@ SwapBytes(disconnAck->rnd);
 printfd(__FILE__, "DISCONN_ACK_8\n");
 if (!((iaUser->phase.GetPhase() == 4) && (disconnAck->rnd == iaUser->rnd + 1)))
     {
+    if (iaSettings.LogProtocolErrors())
+        {
+        if (iaUser->phase.GetPhase() != 4)
+            logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid phase, expected 4, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, iaUser->phase.GetPhase());
+        if (disconnAck->rnd != iaUser->rnd + 1)
+            logger("IP: %s. User '%s'. Protocol version: %d. DISCONN_ACK: invalid control number, expected %d, got %d.", inet_ntostring(sip).c_str(), iaUser->login.c_str(), iaUser->protoVer, (iaUser->rnd + 1), disconnAck->rnd);
+        }
     printfd(__FILE__, "Invalid phase or control number. Phase: %d. Control number: %d\n", iaUser->phase.GetPhase(), disconnAck->rnd);
     return -1;
     }
index a13a11db2a0374b05d5e80ca6211e2de73c529e8..873505566c8e699458d4eaf27324b956844774b6 100644 (file)
@@ -209,6 +209,7 @@ public:
     int             GetUserTimeout() const { return userTimeout; }
     uint16_t        GetUserPort() const { return port; }
     FREEMB          GetFreeMbShowType() const { return freeMbShowType; }
+    bool            LogProtocolErrors() const { return logProtocolErrors; }
 
 private:
     int             userDelay;
@@ -216,6 +217,7 @@ private:
     uint16_t        port;
     std::string     errorStr;
     FREEMB          freeMbShowType;
+    bool            logProtocolErrors;
 };
 //-----------------------------------------------------------------------------
 class AUTH_IA;
@@ -266,7 +268,7 @@ private:
     int                 FinalizeNet();
     void                DelUser(USER_PTR u);
     int                 RecvData(char * buffer, int bufferSize);
-    int                 CheckHeader(const char * buffer, int * protoVer);
+    int                 CheckHeader(const char * buffer, uint32_t sip, int * protoVer);
     int                 PacketProcessor(void * buff, size_t dataLen, uint32_t sip, uint16_t sport, int protoVer, USER_PTR user);
 
     int                 Process_CONN_SYN_6(CONN_SYN_6 * connSyn, IA_USER * iaUser, uint32_t sip);
index 5177330eaf5c8886696d0886605de6e566d0ae43..72e7f73bdcad694183f5cb94c03fe9dd33d1e241 100644 (file)
@@ -279,7 +279,7 @@ do
 if (bd->fd < 0)
     {
     errorStr = "Can't capture packets. Open bpf device for " + bd->iface + " error.";
-    logger("Cannot open device for interface '%s': %s", bd->iface, strerror(errno));
+    logger("Cannot open device for interface '%s': %s", bd->iface.c_str(), strerror(errno));
     printfd(__FILE__, "Cannot open BPF device\n");
     return -1;
     }
@@ -289,7 +289,7 @@ strncpy(ifr.ifr_name, bd->iface.c_str(), sizeof(ifr.ifr_name));
 if (ioctl(bd->fd, BIOCSBLEN, (caddr_t)&l) < 0)
     {
     errorStr = bd->iface + " BIOCSBLEN " + std::string(strerror(errno));
-    logger("ioctl (BIOCSBLEN) error for interface '%s': %s", db->iface, strerror(errno));
+    logger("ioctl (BIOCSBLEN) error for interface '%s': %s", bd->iface.c_str(), strerror(errno));
     printfd(__FILE__, "ioctl failed: '%s'\n", errorStr.c_str());
     return -1;
     }
@@ -297,7 +297,7 @@ if (ioctl(bd->fd, BIOCSBLEN, (caddr_t)&l) < 0)
 if (ioctl(bd->fd, BIOCSETIF, (caddr_t)&ifr) < 0)
     {
     errorStr = bd->iface + " BIOCSETIF " + std::string(strerror(errno));
-    logger("ioctl (BIOCSETIF) error for interface '%s': %s", db->iface, strerror(errno));
+    logger("ioctl (BIOCSETIF) error for interface '%s': %s", bd->iface.c_str(), strerror(errno));
     printfd(__FILE__, "ioctl failed: '%s'\n", errorStr.c_str());
     return -1;
     }
@@ -305,7 +305,7 @@ if (ioctl(bd->fd, BIOCSETIF, (caddr_t)&ifr) < 0)
 if (ioctl(bd->fd, BIOCIMMEDIATE, &im) < 0)
     {
     errorStr = bd->iface + " BIOCIMMEDIATE " + std::string(strerror(errno));
-    logger("ioctl (BIOCIMMEDIATE) error for interface '%s': %s", db->iface, strerror(errno));
+    logger("ioctl (BIOCIMMEDIATE) error for interface '%s': %s", bd->iface.c_str(), strerror(errno));
     printfd(__FILE__, "ioctl failed: '%s'\n", errorStr.c_str());
     return -1;
     }
index e84e9a0e1af96c8e9a23acbcef97716e977bbe27..dca87fbee34ce8a65eb0bc85997c6e57b54ec6cc 100644 (file)
@@ -473,5 +473,11 @@ xmlrpc_c::methodPtr const methodGetOnlinIPsPtr(new METHOD_GET_ONLINE_IPS(
             users
             ));
 rpcRegistry.addMethod("stargazer.get_online_ips", methodGetOnlinIPsPtr);
+
+xmlrpc_c::methodPtr const methodGetUserAuthByPtr(new METHOD_GET_USER_AUTH_BY(
+            this,
+            users
+            ));
+rpcRegistry.addMethod("stargazer.get_user_auth_by", methodGetUserAuthByPtr);
 }
 
index fad12886f651d870866a459225efbf5e591416b9..85abf8205a5e59822db40850c3b37d4de905be45 100644 (file)
@@ -12,6 +12,7 @@ structVal["fee"] = xmlrpc_c::value_double(data.tariffConf.fee);
 structVal["freemb"] = xmlrpc_c::value_double(data.tariffConf.free);
 structVal["passivecost"] = xmlrpc_c::value_double(data.tariffConf.passiveCost);
 structVal["traffType"] = xmlrpc_c::value_int(data.tariffConf.traffType);
+structVal["period"] = xmlrpc_c::value_string(TARIFF::PeriodToString(data.tariffConf.period));
 
 std::vector<xmlrpc_c::value> prices(DIR_NUM);
 
@@ -65,6 +66,11 @@ if ((it = structVal.find("traffType")) != structVal.end())
     data.tariffConf.traffType = xmlrpc_c::value_int(it->second);
     }
 
+if ((it = structVal.find("period")) != structVal.end())
+    {
+    data.tariffConf.period = TARIFF::StringToPeriod(xmlrpc_c::value_string(it->second));
+    }
+
 if ((it = structVal.find("dirprices")) != structVal.end())
     {
     std::vector<xmlrpc_c::value> prices(
index 665a04f4af96f9783424a859a005999c743a00f3..89c41587f8527862de5932bbc4cbe52e63ab0c37 100644 (file)
@@ -161,6 +161,18 @@ if ((it = structVal.find("ips")) != structVal.end())
     {
     USER_IPS ips;
     ips = StrToIPS(xmlrpc_c::value_string(it->second));
+
+    for (size_t i = 0; i < ips.Count(); ++i)
+        {
+        CONST_USER_PTR user;
+        uint32_t ip = ips[i].ip;
+        if (users.IsIPInUse(ip, login, &user))
+            {
+            printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+            return true;
+            }
+        }
+
     if (!ptr->GetProperty().ips.Set(ips,
                                 admin,
                                 login,
index 83f70b5c4df2428cfabb48a296688c1ff2618604..4e1dd7966f0a584be40ffc972779d2cdc9bfd525 100644 (file)
@@ -14,8 +14,9 @@ class TARIFFS;
 class USER_HELPER
 {
 public:
-    USER_HELPER(USER_PTR & p)
-        : ptr(p)
+    USER_HELPER(USER_PTR & p, USERS & us)
+        : ptr(p),
+          users(us)
     {
     }
 
@@ -28,6 +29,7 @@ public:
                      TARIFFS * tariffs);
 private:
     USER_PTR & ptr;
+    USERS & users;
 };
 
 #endif
index 5b39cf1e84aff4f00ec3ac9016b7629fce753638..5adbf44131905750cfa52fefbf1398b0842b2dd0 100644 (file)
@@ -39,7 +39,7 @@ if (users->FindByName(login, &u))
     return;
     }
 
-USER_HELPER uhelper(u);
+USER_HELPER uhelper(u, *users);
 
 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
     {
@@ -172,7 +172,7 @@ while (1)
 
     xmlrpc_c::value info;
 
-    USER_HELPER uhelper(u);
+    USER_HELPER uhelper(u, *users);
 
     uhelper.GetUserInfo(&info, hidePassword);
 
@@ -216,7 +216,7 @@ if (users->FindByName(login, &u))
     return;
     }
 
-USER_HELPER uhelper(u);
+USER_HELPER uhelper(u, *users);
 
 if (!adminInfo.priviledges.userConf || !adminInfo.priviledges.userPasswd)
     {
@@ -509,3 +509,36 @@ ipm.mask = htonl(0xffFFffFF << (32 - ipm.mask));
 
 return false;
 }
+
+void METHOD_GET_USER_AUTH_BY::execute(xmlrpc_c::paramList const & paramList,
+                                      xmlrpc_c::value *   const   retvalPtr)
+{
+std::string cookie = paramList.getString(0);
+std::string login = paramList.getString(1);
+paramList.verifyEnd(2);
+
+std::map<std::string, xmlrpc_c::value> structVal;
+ADMIN_INFO adminInfo;
+
+if (config->GetAdminInfo(cookie, &adminInfo))
+    {
+    structVal["result"] = xmlrpc_c::value_boolean(false);
+    *retvalPtr = xmlrpc_c::value_struct(structVal);
+    return;
+    }
+
+USER_PTR u;
+
+if (users->FindByName(login, &u))
+    {
+    structVal["result"] = xmlrpc_c::value_boolean(false);
+    *retvalPtr = xmlrpc_c::value_struct(structVal);
+    return;
+    }
+
+std::vector<std::string> list(u->GetAuthorizers());
+std::vector<xmlrpc_c::value> authList;
+for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
+    authList.push_back(xmlrpc_c::value_string(*it));
+*retvalPtr = xmlrpc_c::value_array(authList);
+}
index 413e9aaf8b418578f374a056383207489dcdc4a1..d1ec33a4ade340f07e1612e1b9641de38417db8d 100644 (file)
@@ -229,4 +229,24 @@ private:
     bool ParseNet(const std::string & net, IP_MASK & ipm) const;
 };
 
+class METHOD_GET_USER_AUTH_BY : public xmlrpc_c::method {
+public:
+    METHOD_GET_USER_AUTH_BY(RPC_CONFIG * c,
+                            USERS * u)
+        : config(c),
+          users(u)
+    {
+    }
+
+    void execute(xmlrpc_c::paramList const & paramList,
+                 xmlrpc_c::value *   const   retvalP);
+
+private:
+    METHOD_GET_USER_AUTH_BY(const METHOD_GET_ONLINE_IPS & rvalue);
+    METHOD_GET_USER_AUTH_BY & operator=(const METHOD_GET_ONLINE_IPS & rvalue);
+
+    RPC_CONFIG * config;
+    USERS * users;
+};
+
 #endif
index b6f4938a632095cfcdf505f4fb950e39d65845e6..1b59f5cfa844da7c643e85e7318c58771fb01338 100644 (file)
@@ -11,7 +11,9 @@ SRCS = ./stgconfig.cpp \
        ./configproto.cpp \
        ./parser.cpp \
        ./parser_tariff.cpp \
-       ./parser_admin.cpp
+       ./parser_admin.cpp \
+       ./parser_auth_by.cpp \
+       ./parser_user_info.cpp
 
 LIBS += -lexpat \
        $(LIB_THREAD)
index 22facc612adf4b55a9b02f22d3f3ac8d20a323c2..ec3e3ee3c86e765a5a048e3fe8fe920e596091b4 100644 (file)
  $Author: faust $
  */
 
+#include "configproto.h"
 
 #include <unistd.h>
 
-#include "configproto.h"
-
 //-----------------------------------------------------------------------------
 void ParseXMLStart(void *data, const char *el, const char **attr)
 {
@@ -87,39 +86,15 @@ else
 }
 //-----------------------------------------------------------------------------
 CONFIGPROTO::CONFIGPROTO(PLUGIN_LOGGER & l)
-    : answerList(),
-      requestList(),
-      adminIP(0),
-      adminLogin(),
-      adminPassword(),
+    : adminIP(0),
       port(0),
-      thrReciveSendConf(),
       nonstop(true),
       state(0),
       currAdmin(NULL),
       logger(l),
       listenSocket(-1),
-      parserGetServInfo(),
-      parserGetUsers(),
-      parserGetUser(),
-      parserChgUser(),
-      parserAddUser(),
-      parserDelUser(),
-      parserCheckUser(),
-      parserSendMessage(),
-      parserGetAdmins(),
-      parserAddAdmin(),
-      parserDelAdmin(),
-      parserChgAdmin(),
-      parserGetTariffs(),
-      parserAddTariff(),
-      parserDelTariff(),
-      parserChgTariff(),
       admins(NULL),
-      currParser(NULL),
-      dataParser(),
-      xmlParser(),
-      errorStr()
+      currParser(NULL)
 {
 dataParser.push_back(&parserGetServInfo);
 
@@ -130,6 +105,8 @@ dataParser.push_back(&parserAddUser);
 dataParser.push_back(&parserDelUser);
 dataParser.push_back(&parserCheckUser);
 dataParser.push_back(&parserSendMessage);
+dataParser.push_back(&parserAuthBy);
+dataParser.push_back(&parserUserInfo);
 
 dataParser.push_back(&parserGetTariffs);
 dataParser.push_back(&parserAddTariff);
@@ -210,51 +187,34 @@ while(nonstop)
 return 0;
 }
 //-----------------------------------------------------------------------------
-void CONFIGPROTO::SetPort(uint16_t p)
-{
-port = p;
-}
-//-----------------------------------------------------------------------------
 void CONFIGPROTO::SetAdmins(ADMINS * a)
 {
 admins = a;
 for (size_t i = 0; i < dataParser.size(); i++)
-    {
     dataParser[i]->SetAdmins(a);
-    }
-
 }
 //-----------------------------------------------------------------------------
 void CONFIGPROTO::SetUsers(USERS * u)
 {
 for (size_t i = 0; i < dataParser.size(); i++)
-    {
     dataParser[i]->SetUsers(u);
-    }
-
 }
 //-----------------------------------------------------------------------------
 void CONFIGPROTO::SetTariffs(TARIFFS * t)
 {
 for (size_t i = 0; i < dataParser.size(); i++)
-    {
     dataParser[i]->SetTariffs(t);
-    }
 }
 //-----------------------------------------------------------------------------
 void CONFIGPROTO::SetStore(STORE * s)
 {
 for (size_t i = 0; i < dataParser.size(); i++)
-    {
     dataParser[i]->SetStore(s);
-    }
 }
 //-----------------------------------------------------------------------------
 void CONFIGPROTO::SetStgSettings(const SETTINGS * s)
 {
 for (size_t i = 0; i < dataParser.size(); i++)
-    {
     dataParser[i]->SetStgSettings(s);
-    }
 }
 //-----------------------------------------------------------------------------
index b8b01f024da3f1f0d8daf32ce7ea50231678ec13..4adba09758afae9345de7104f1e4236160a55de9 100644 (file)
 #ifndef CONFIGPROTO_H
 #define CONFIGPROTO_H
 
-#include <expat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <string>
-#include <list>
+#include "parser_auth_by.h"
+#include "parser_user_info.h"
 
 #include "stg/users.h"
 #include "stg/admins.h"
 #include "stg/logger.h"
 #include "parser.h"
 
+#include <string>
+#include <list>
+
+#include <expat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
 #define  STG_HEADER     "SG04"
 #define  OK_HEADER      "OKHD"
 #define  ERR_HEADER     "ERHD"
@@ -55,7 +58,7 @@ public:
     CONFIGPROTO(PLUGIN_LOGGER & l);
     ~CONFIGPROTO();
 
-    void            SetPort(uint16_t port);
+    void            SetPort(uint16_t p) { port = p; }
     void            SetAdmins(ADMINS * a);
     void            SetUsers(USERS * u);
     void            SetTariffs(TARIFFS * t);
@@ -107,6 +110,8 @@ private:
     PARSER_DEL_USER             parserDelUser;
     PARSER_CHECK_USER           parserCheckUser;
     PARSER_SEND_MESSAGE         parserSendMessage;
+    PARSER_AUTH_BY              parserAuthBy;
+    PARSER_USER_INFO            parserUserInfo;
 
     PARSER_GET_ADMINS           parserGetAdmins;
     PARSER_ADD_ADMIN            parserAddAdmin;
index 1f7757d22a99e68e013cba489092061cb9b43e55..a7c79c00d5df90f09685a7a7f535882eff233db9 100644 (file)
@@ -133,8 +133,7 @@ answerList->erase(answerList->begin(), answerList->end());
 
 if (users->FindByName(login, &u))
     {
-    s = "<user result=\"error\"/>";
-    answerList->push_back(s);
+    answerList->push_back("<user result=\"error\" reason=\"User not found.\"/>");
     return;
     }
 
@@ -286,6 +285,13 @@ answerList->push_back(s);
 strprintf(&s, "<CreditExpire value=\"%ld\" />", u->GetProperty().creditExpire.Get());
 answerList->push_back(s);
 
+s = "<AuthorizedBy>";
+std::vector<std::string> list(u->GetAuthorizers());
+for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
+    s += "<Auth name=\"" + *it + "\"/>";
+s += "</AuthorizedBy>";
+answerList->push_back(s);
+
 strprintf(&s, "</user>");
 answerList->push_back(s);
 }
@@ -936,8 +942,6 @@ else
                 }
             j+=2;
             }
-        usr->down = dtd;
-        usr->up = dtu;
         return 0;
         }
 
@@ -1009,13 +1013,13 @@ if (users->FindByName(login, &u))
 
 bool check = false;
 bool alwaysOnline = u->GetProperty().alwaysOnline;
-if (!ucr->alwaysOnline.res_empty())
+if (!ucr->alwaysOnline.empty())
     {
     check = true;
     alwaysOnline = ucr->alwaysOnline.const_data();
     }
 bool onlyOneIP = u->GetProperty().ips.ConstData().OnlyOneIP();
-if (!ucr->ips.res_empty())
+if (!ucr->ips.empty())
     {
     check = true;
     onlyOneIP = ucr->ips.const_data().OnlyOneIP();
@@ -1025,52 +1029,66 @@ if (check && alwaysOnline && !onlyOneIP)
     {
     printfd(__FILE__, "Requested change leads to a forbidden state: AlwaysOnline with multiple IP's\n");
     GetStgLogger()("%s Requested change leads to a forbidden state: AlwaysOnline with multiple IP's", currAdmin->GetLogStr().c_str());
+    res = -1;
     return -1;
     }
 
-if (!ucr->ips.res_empty())
+for (size_t i = 0; i < ucr->ips.const_data().Count(); ++i)
+    {
+    CONST_USER_PTR user;
+    uint32_t ip = ucr->ips.const_data().operator[](i).ip;
+    if (users->IsIPInUse(ip, login, &user))
+        {
+        printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+        GetStgLogger()("%s trying to assign an IP %s to '%s' that is currently in use by '%s'", currAdmin->GetLogStr().c_str(), inet_ntostring(ip).c_str(), login.c_str(), user->GetLogin().c_str());
+        res = -1;
+        return -1;
+        }
+    }
+
+if (!ucr->ips.empty())
     if (!u->GetProperty().ips.Set(ucr->ips.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->alwaysOnline.res_empty())
+if (!ucr->alwaysOnline.empty())
     if (!u->GetProperty().alwaysOnline.Set(ucr->alwaysOnline.const_data(),
                                       currAdmin, login, store))
         res = -1;
 
-if (!ucr->address.res_empty())
+if (!ucr->address.empty())
     if (!u->GetProperty().address.Set(ucr->address.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->creditExpire.res_empty())
+if (!ucr->creditExpire.empty())
     if (!u->GetProperty().creditExpire.Set(ucr->creditExpire.const_data(),
                                       currAdmin, login, store))
         res = -1;
 
-if (!ucr->credit.res_empty())
+if (!ucr->credit.empty())
     if (!u->GetProperty().credit.Set(ucr->credit.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!usr->freeMb.res_empty())
+if (!usr->freeMb.empty())
     if (!u->GetProperty().freeMb.Set(usr->freeMb.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->disabled.res_empty())
+if (!ucr->disabled.empty())
     if (!u->GetProperty().disabled.Set(ucr->disabled.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->disabledDetailStat.res_empty())
+if (!ucr->disabledDetailStat.empty())
     if (!u->GetProperty().disabledDetailStat.Set(ucr->disabledDetailStat.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->email.res_empty())
+if (!ucr->email.empty())
     if (!u->GetProperty().email.Set(ucr->email.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->group.res_empty())
+if (!ucr->group.empty())
     if (!u->GetProperty().group.Set(ucr->group.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->note.res_empty())
+if (!ucr->note.empty())
     if (!u->GetProperty().note.Set(ucr->note.const_data(), currAdmin, login, store))
         res = -1;
 
@@ -1088,31 +1106,31 @@ userdata.push_back(u->GetProperty().userdata9.GetPointer());
 
 for (int i = 0; i < (int)userdata.size(); i++)
     {
-    if (!ucr->userdata[i].res_empty())
+    if (!ucr->userdata[i].empty())
         {
         if(!userdata[i]->Set(ucr->userdata[i].const_data(), currAdmin, login, store))
             res = -1;
         }
     }
 
-if (!ucr->passive.res_empty())
+if (!ucr->passive.empty())
     if (!u->GetProperty().passive.Set(ucr->passive.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->password.res_empty())
+if (!ucr->password.empty())
     if (!u->GetProperty().password.Set(ucr->password.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->phone.res_empty())
+if (!ucr->phone.empty())
     if (!u->GetProperty().phone.Set(ucr->phone.const_data(), currAdmin, login, store))
         res = -1;
 
-if (!ucr->realName.res_empty())
+if (!ucr->realName.empty())
     if (!u->GetProperty().realName.Set(ucr->realName.const_data(), currAdmin, login, store))
         res = -1;
 
 
-if (!usr->cash.res_empty())
+if (!usr->cash.empty())
     {
     //if (*currAdmin->GetPriv()->userCash)
         {
@@ -1134,7 +1152,7 @@ if (!usr->cash.res_empty())
     }
 
 
-if (!ucr->tariffName.res_empty())
+if (!ucr->tariffName.empty())
     {
     if (tariffs->FindByName(ucr->tariffName.const_data()))
         {
@@ -1149,7 +1167,7 @@ if (!ucr->tariffName.res_empty())
         }
     }
 
-if (!ucr->nextTariff.res_empty())
+if (!ucr->nextTariff.empty())
     {
     if (tariffs->FindByName(ucr->nextTariff.const_data()))
         {
@@ -1169,14 +1187,14 @@ int upCount = 0;
 int downCount = 0;
 for (int i = 0; i < DIR_NUM; i++)
     {
-    if (!upr[i].res_empty())
+    if (!upr[i].empty())
         {
-        up[i] = upr[i];
+        up[i] = upr[i].data();
         upCount++;
         }
-    if (!downr[i].res_empty())
+    if (!downr[i].empty())
         {
-        down[i] = downr[i];
+        down[i] = downr[i].data();
         downCount++;
         }
     }
@@ -1189,15 +1207,6 @@ if (downCount)
     if (!u->GetProperty().down.Set(down, currAdmin, login, store))
         res = -1;
 
-/*if (!usr->down.res_empty())
-    {
-    u->GetProperty().down.Set(usr->down.const_data(), currAdmin, login, store);
-    }
-if (!usr->up.res_empty())
-    {
-    u->GetProperty().up.Set(usr->up.const_data(), currAdmin, login, store);
-    }*/
-
 u->WriteConf();
 u->WriteStat();
 
@@ -1342,11 +1351,11 @@ switch (result)
         break;
     case res_params_error:
         printfd(__FILE__, "res_params_error\n");
-        answerList->push_back("<SendMessageResult value=\"Parameters error\"/>");
+        answerList->push_back("<SendMessageResult value=\"Parameters error.\"/>");
         break;
     case res_unknown:
         printfd(__FILE__, "res_unknown\n");
-        answerList->push_back("<SendMessageResult value=\"Unknown user\"/>");
+        answerList->push_back("<SendMessageResult value=\"Unknown user.\"/>");
         break;
     default:
         printfd(__FILE__, "res_default\n");
@@ -1400,30 +1409,17 @@ else
     answerList->push_back("<DelUser value=\"ok\"/>");
 }
 //-----------------------------------------------------------------------------
-/*void PARSERDELUSER::CreateAnswer(char * mes)
-{
-//answerList->clear();
-answerList->erase(answerList->begin(), answerList->end());
-
-char str[255];
-sprintf(str, "<DelUser value=\"%s\"/>", mes);
-answerList->push_back(str);
-}*/
-//-----------------------------------------------------------------------------
 //  CHECK USER
 // <checkuser login="vasya" password=\"123456\"/>
 //-----------------------------------------------------------------------------
 int PARSER_CHECK_USER::ParseStart(void *, const char *el, const char **attr)
 {
-result = false;
-
 if (strcasecmp(el, "CheckUser") == 0)
     {
     if (attr[0] == NULL || attr[1] == NULL
      || attr[2] == NULL || attr[3] == NULL)
         {
-        result = false;
-        CreateAnswer();
+        CreateAnswer("Invalid parameters.");
         printfd(__FILE__, "PARSER_CHECK_USER - attr err\n");
         return 0;
         }
@@ -1431,22 +1427,19 @@ if (strcasecmp(el, "CheckUser") == 0)
     USER_PTR user;
     if (users->FindByName(attr[1], &user))
         {
-        result = false;
-        CreateAnswer();
+        CreateAnswer("User not found.");
         printfd(__FILE__, "PARSER_CHECK_USER - login err\n");
         return 0;
         }
 
     if (strcmp(user->GetProperty().password.Get().c_str(), attr[3]))
         {
-        result = false;
-        CreateAnswer();
+        CreateAnswer("Wrong password.");
         printfd(__FILE__, "PARSER_CHECK_USER - passwd err\n");
         return 0;
         }
 
-    result = true;
-    CreateAnswer();
+    CreateAnswer(NULL);
     return 0;
     }
 return -1;
@@ -1461,12 +1454,12 @@ if (strcasecmp(el, "CheckUser") == 0)
 return -1;
 }
 //-----------------------------------------------------------------------------
-void PARSER_CHECK_USER::CreateAnswer()
+void PARSER_CHECK_USER::CreateAnswer(const char * error)
 {
-if (result)
-    answerList->push_back("<CheckUser value=\"Ok\"/>");
+if (error)
+    answerList->push_back(std::string("<CheckUser value=\"Err\" reason=\"") + error + "\"/>");
 else
-    answerList->push_back("<CheckUser value=\"Err\"/>");
+    answerList->push_back("<CheckUser value=\"Ok\"/>");
 }
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
index df3d7155872b56f3a08aaad57e6d750ce6b0853c..e76d8f4ca9b36ec5122bcd12a68f958f2c1ed431 100644 (file)
@@ -7,10 +7,6 @@
 #ifndef PARSER_H
 #define PARSER_H
 
-#include <list>
-#include <string>
-#include <vector>
-
 #include "stg/resetable.h"
 #include "stg/const.h"
 #include "stg/store.h"
 #include "stg/users.h"
 #include "stg/message.h"
 
+#include <list>
+#include <string>
+#include <vector>
+
 class TARIFFS;
 class SETTINGS;
 
@@ -39,18 +39,18 @@ public:
     virtual ~BASE_PARSER() {}
     virtual int ParseStart(void *data, const char *el, const char **attr) = 0;
     virtual int ParseEnd(void *data, const char *el) = 0;
-    virtual void CreateAnswer() = 0;
-    virtual void SetAnswerList(std::list<std::string> * ansList) { answerList = ansList; }
 
-    virtual void SetUsers(USERS * u) { users = u; }
-    virtual void SetAdmins(ADMINS * a) { admins = a; }
-    virtual void SetTariffs(TARIFFS * t) { tariffs = t; }
-    virtual void SetStore(STORE * s) { store = s; }
-    virtual void SetStgSettings(const SETTINGS * s) { settings = s; }
+    void SetAnswerList(std::list<std::string> * ansList) { answerList = ansList; }
+
+    void SetUsers(USERS * u) { users = u; }
+    void SetAdmins(ADMINS * a) { admins = a; }
+    void SetTariffs(TARIFFS * t) { tariffs = t; }
+    void SetStore(STORE * s) { store = s; }
+    void SetStgSettings(const SETTINGS * s) { settings = s; }
 
-    virtual void SetCurrAdmin(ADMIN & cua) { currAdmin = &cua; }
-    virtual std::string & GetStrError() { return strError; }
-    virtual void Reset() { answerList->clear(); depth = 0; }
+    void SetCurrAdmin(ADMIN & cua) { currAdmin = &cua; }
+    std::string & GetStrError() { return strError; }
+    void Reset() { answerList->clear(); depth = 0; }
 
 protected:
     BASE_PARSER(const BASE_PARSER & rvalue);
@@ -71,6 +71,8 @@ class PARSER_GET_ADMINS: public BASE_PARSER {
 public:
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
+
+private:
     void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
@@ -79,9 +81,11 @@ public:
         PARSER_ADD_ADMIN() : BASE_PARSER(), adminToAdd() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     std::string adminToAdd;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_DEL_ADMIN: public BASE_PARSER {
@@ -89,10 +93,12 @@ public:
         PARSER_DEL_ADMIN() : BASE_PARSER(), adminToDel() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
-    int CheckAttr(const char **attr);
     std::string adminToDel;
+
+    int CheckAttr(const char **attr);
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_CHG_ADMIN: public BASE_PARSER {
@@ -100,17 +106,21 @@ public:
         PARSER_CHG_ADMIN() : BASE_PARSER(), login(), password(), privAsString() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     RESETABLE<std::string> login;
     RESETABLE<std::string> password;
     RESETABLE<std::string> privAsString;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_GET_SERVER_INFO: public BASE_PARSER {
 public:
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
+
+private:
     void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
@@ -120,9 +130,11 @@ public:
         ~PARSER_GET_USER() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     std::string login;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_GET_USERS: public BASE_PARSER {
@@ -130,16 +142,20 @@ public:
         PARSER_GET_USERS() : BASE_PARSER(), lastUserUpdateTime(0), lastUpdateFound(false) {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     time_t lastUserUpdateTime;
     bool lastUpdateFound;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_GET_TARIFFS: public BASE_PARSER {
 public:
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
+
+private:
     void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
@@ -148,9 +164,11 @@ public:
         PARSER_ADD_TARIFF() : BASE_PARSER(), tariffToAdd() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     std::string tariffToAdd;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_DEL_TARIFF: public BASE_PARSER {
@@ -158,9 +176,11 @@ public:
         PARSER_DEL_TARIFF() : BASE_PARSER(), tariffToDel() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
     std::string tariffToDel;
+
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_CHG_TARIFF: public BASE_PARSER {
@@ -168,14 +188,15 @@ public:
         PARSER_CHG_TARIFF() : BASE_PARSER(), td() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
+    TARIFF_DATA_RES td;
+
     int ParseSlashedIntParams(int paramsNum, const std::string & s, int * params);
     int ParseSlashedDoubleParams(int paramsNum, const std::string & s, double * params);
     int CheckTariffData();
     int AplayChanges();
-
-    TARIFF_DATA_RES td;
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------/
 class PARSER_ADD_USER: public BASE_PARSER {
@@ -184,11 +205,13 @@ public:
         ~PARSER_ADD_USER() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
-    void Reset();
+
 private:
-    int CheckUserData();
     std::string login;
+
+    int CheckUserData();
+    void CreateAnswer();
+    void Reset();
 };
 //-----------------------------------------------------------------------------
 class PARSER_CHG_USER: public BASE_PARSER {
@@ -197,15 +220,8 @@ public:
         ~PARSER_CHG_USER();
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
-    void Reset();
-private:
-    PARSER_CHG_USER(const PARSER_CHG_USER & rvalue);
-    PARSER_CHG_USER & operator=(const PARSER_CHG_USER & rvalue);
-
-    std::string EncChar2String(const char *);
-    int AplayChanges();
 
+private:
     USER_STAT_RES * usr;
     USER_CONF_RES * ucr;
     RESETABLE<uint64_t> * upr;
@@ -214,6 +230,14 @@ private:
     std::string login;
     bool cashMustBeAdded;
     int res;
+
+    PARSER_CHG_USER(const PARSER_CHG_USER & rvalue);
+    PARSER_CHG_USER & operator=(const PARSER_CHG_USER & rvalue);
+
+    std::string EncChar2String(const char *);
+    int AplayChanges();
+    void CreateAnswer();
+    void Reset();
 };
 //-----------------------------------------------------------------------------
 class PARSER_DEL_USER: public BASE_PARSER {
@@ -221,24 +245,25 @@ public:
         PARSER_DEL_USER() : BASE_PARSER(), res(0), u(NULL) {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
 
 private:
+    int res;
+    USER * u;
+
     PARSER_DEL_USER(const PARSER_DEL_USER & rvalue);
     PARSER_DEL_USER & operator=(const PARSER_DEL_USER & rvalue);
 
-    int res;
-    USER * u;
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 class PARSER_CHECK_USER: public BASE_PARSER {
 public:
-        PARSER_CHECK_USER() : BASE_PARSER(), result(false) {}
+        PARSER_CHECK_USER() : BASE_PARSER() {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
+
 private:
-    bool result;
+    void CreateAnswer(const char * error);
 };
 //-----------------------------------------------------------------------------
 class PARSER_SEND_MESSAGE: public BASE_PARSER {
@@ -246,18 +271,19 @@ public:
         PARSER_SEND_MESSAGE() : BASE_PARSER(), logins(), result(0), msg(), u(NULL) {}
     int ParseStart(void *data, const char *el, const char **attr);
     int ParseEnd(void *data, const char *el);
-    void CreateAnswer();
-private:
-    PARSER_SEND_MESSAGE(const PARSER_SEND_MESSAGE & rvalue);
-    PARSER_SEND_MESSAGE & operator=(const PARSER_SEND_MESSAGE & rvalue);
-
-    int ParseLogins(const char * logins);
 
+private:
     enum {res_ok, res_params_error, res_unknown};
     std::vector<std::string> logins;
     int result;
     STG_MSG msg;
     USER * u;
+
+    PARSER_SEND_MESSAGE(const PARSER_SEND_MESSAGE & rvalue);
+    PARSER_SEND_MESSAGE & operator=(const PARSER_SEND_MESSAGE & rvalue);
+
+    int ParseLogins(const char * logins);
+    void CreateAnswer();
 };
 //-----------------------------------------------------------------------------
 #endif //PARSER_H
index 9d87f30047bc434e8d6688451cb713fd2ef990b4..b1285a772441d3facc49cd96937c05f11ba9c24d 100644 (file)
@@ -213,11 +213,11 @@ void PARSER_CHG_ADMIN::CreateAnswer()
 answerList->erase(answerList->begin(), answerList->end());
 
 
-if (!login.res_empty())
+if (!login.empty())
     {
     ADMIN * origAdmin = NULL;
 
-    if (admins->Find(login, &origAdmin))
+    if (admins->Find(login.data(), &origAdmin))
         {
         answerList->push_back(std::string("<ChgAdmin Result = \"Admin '") + login.data() + "' is not found.\"/>");
         return;
@@ -225,10 +225,10 @@ if (!login.res_empty())
 
     ADMIN_CONF conf(origAdmin->GetConf());
 
-    if (!password.res_empty())
+    if (!password.empty())
         conf.password = password.data();
 
-    if (!privAsString.res_empty())
+    if (!privAsString.empty())
         {
         int p = 0;
         if (str2x(privAsString.data().c_str(), p) < 0)
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.cpp b/projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.cpp
new file mode 100644 (file)
index 0000000..5492157
--- /dev/null
@@ -0,0 +1,46 @@
+#include "parser_auth_by.h"
+
+int PARSER_AUTH_BY::ParseStart(void * /*data*/, const char *el, const char **attr)
+{
+if (strcasecmp(el, "GetUserAuthBy") == 0)
+    {
+    if (attr[0] && attr[1])
+        login = attr[1];
+    else
+        {
+        login.erase(login.begin(), login.end());
+        return -1;
+        }
+    return 0;
+    }
+return -1;
+}
+
+int PARSER_AUTH_BY::ParseEnd(void * /*data*/, const char *el)
+{
+if (strcasecmp(el, "GetUserAuthBy") == 0)
+    {
+    CreateAnswer();
+    return 0;
+    }
+return -1;
+}
+
+void PARSER_AUTH_BY::CreateAnswer()
+{
+answerList->erase(answerList->begin(), answerList->end());
+
+USER_PTR u;
+if (users->FindByName(login, &u))
+    {
+    answerList->push_back("<AuthorizedBy result=\"error\" reason=\"User not found.\"/>");
+    return;
+    }
+
+std::string s = "<AuthorizedBy result=\"ok\">";
+std::vector<std::string> list(u->GetAuthorizers());
+for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
+    s += "<Auth name=\"" + *it + "\"/>";
+s += "</AuthorizedBy>";
+answerList->push_back(s);
+}
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.h b/projects/stargazer/plugins/configuration/sgconfig/parser_auth_by.h
new file mode 100644 (file)
index 0000000..c34586c
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __STG_PARSER_AUTH_BY_H__
+#define __STG_PARSER_AUTH_BY_H__
+
+#include <string>
+
+#include "parser.h"
+
+class PARSER_AUTH_BY : public BASE_PARSER {
+public:
+    int ParseStart(void *data, const char *el, const char **attr);
+    int ParseEnd(void *data, const char *el);
+    void CreateAnswer();
+
+private:
+    std::string login;
+};
+
+#endif
index 7be1af9645a0107ff39a0ec839e45780f1817b08..0e001b224a559fdfee6f94411275387e7ec62926 100644 (file)
@@ -145,6 +145,8 @@ for (; it != dataList.end(); ++it)
             break;
         }
 
+    answerList->push_back("<Period value=\"" + TARIFF::PeriodToString(it->tariffConf.period) + "\"/>");
+
     answerList->push_back("</tariff>");
     }
 answerList->push_back("</Tariffs>");
@@ -451,6 +453,12 @@ else
             }
         return 0;
         }
+
+    if (strcasecmp(el, "Period") == 0)
+        {
+        td.tariffConf.period = TARIFF::StringToPeriod(attr[1]);
+        return 0;
+        }
     }
 return -1;
 }
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser_user_info.cpp b/projects/stargazer/plugins/configuration/sgconfig/parser_user_info.cpp
new file mode 100644 (file)
index 0000000..72c3c6e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *    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 "parser_user_info.h"
+
+#include "stg/user.h"
+#include "stg/common.h"
+
+#include <strings.h> // strcasecmp
+
+int PARSER_USER_INFO::ParseStart(void * /*data*/, const char *el, const char **attr)
+{
+login.clear();
+if (strcasecmp(el, "GetUserInfo") != 0)
+    return -1;
+
+if (!attr[0] || !attr[1] || strcasecmp(attr[0], "login") != 0)
+    return -1;
+
+login = attr[1];
+return 0;
+}
+
+int PARSER_USER_INFO::ParseEnd(void * /*data*/, const char *el)
+{
+if (strcasecmp(el, "GetUserInfo") != 0)
+    return -1;
+
+CreateAnswer();
+return 0;
+}
+
+void PARSER_USER_INFO::CreateAnswer()
+{
+answerList->clear();
+
+CONST_USER_PTR u;
+if (users->FindByName(login, &u))
+    {
+    answerList->push_back("<UserInfo result=\"error\"/>");
+    return;
+    }
+
+std::string s = "<UserInfo lastAuthTime=\"" + x2str(u->GetAuthorizedModificationTime()) + "\"" +
+                " lastDisconnectTime=\"" + x2str(u->GetConnectedModificationTime()) + "\"" +
+                " connected=\"" + (u->GetConnected() ? "true" : "false") + "\"" +
+                " lastDisconnectReason=\"" + u->GetLastDisconnectReason() + "\">";
+std::vector<std::string> list(u->GetAuthorizers());
+for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); ++it)
+    s += "<Auth name=\"" + *it + "\"/>";
+s += "</UserInfo>";
+answerList->push_back(s);
+}
diff --git a/projects/stargazer/plugins/configuration/sgconfig/parser_user_info.h b/projects/stargazer/plugins/configuration/sgconfig/parser_user_info.h
new file mode 100644 (file)
index 0000000..ccd1d94
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *    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 __STG_PARSER_USER_INFO_H__
+#define __STG_PARSER_USER_INFO_H__
+
+#include "parser.h"
+
+#include <string>
+
+class PARSER_USER_INFO : public BASE_PARSER {
+public:
+    int ParseStart(void *data, const char *el, const char **attr);
+    int ParseEnd(void *data, const char *el);
+
+private:
+    std::string login;
+
+    void CreateAnswer();
+};
+
+#endif
index 9b448f6cede881e7c7df4fc6275a9f6b3fb0d798..6ca2b3da41de956ebe9442c726c2b9e17b2f6e53 100644 (file)
 *
 *******************************************************************/
 
-#include <unistd.h> // close
+#include "configproto.h"
+
+#include "stg/blowfish.h"
 
 #include <cerrno>
 #include <csignal>
 #include <cstdio> // snprintf
 
-#include "stg/blowfish.h"
-#include "configproto.h"
+#include <unistd.h> // close
 
 #ifndef ENODATA
 // FreeBSD 4.* - suxx
@@ -147,13 +148,11 @@ while (nonstop)
                              &outerAddrLen);
 
     if (!nonstop)
-        {
         break;
-        }
 
     if (outerSocket < 0)
         {
-       logger("accept error: %s", strerror(errno));
+        logger("accept error: %s", strerror(errno));
         printfd(__FILE__, "accept failed\n");
         continue;
         }
@@ -256,8 +255,8 @@ while (pos < stgHdrLen)
     ssize_t ret = recv(sock, &buf[pos], static_cast<int>(stgHdrLen) - static_cast<int>(pos), 0);
     if (ret <= 0)
         {
-       if (ret < 0)
-           logger("recv error: %s", strerror(errno));
+        if (ret < 0)
+            logger("recv error: %s", strerror(errno));
         state = confHdr;
         return -1;
         }
@@ -319,7 +318,7 @@ while (pos < ADM_LOGIN_LEN) {
     if (ret <= 0)
         {
         // Error in network
-       logger("recv error: %s", strerror(errno));
+        logger("recv error: %s", strerror(errno));
         state = confHdr;
         return ENODATA;
         }
@@ -370,7 +369,7 @@ while (pos < ADM_LOGIN_LEN)
         {
         // Network error
         printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
-       logger("recv error: %s", strerror(errno));
+        logger("recv error: %s", strerror(errno));
         state = confHdr;
         return ENODATA;
         }
@@ -389,9 +388,7 @@ EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
 
 char login[ADM_LOGIN_LEN + 1];
 for (size_t i = 0; i < ADM_LOGIN_LEN / 8; i++)
-    {
     DecodeString(login + i * 8, loginS + i * 8, &ctx);
-    }
 
 if (currAdmin == admins->GetNoAdmin())
     {
@@ -456,7 +453,7 @@ while (1)
         if (ret < 0)
             {
             // Network error
-           logger("recv error: %s", strerror(errno));
+            logger("recv error: %s", strerror(errno));
             printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
             return -1;
             }
@@ -514,11 +511,8 @@ while (li != answerList.end())
         if (n % 8 == 0)
             {
             EncodeString(buffS, buff, &ctx);
-            int ret = static_cast<int>(send(sock, buffS, 8, 0));
-            if (ret < 0)
-                {
+            if (send(sock, buffS, 8, 0) < 0)
                 return -1;
-                }
             }
         }
     k = 0;// new node
index 5c94606b41a6905aa284db3039fc796d58197db1..725bc3f1a6b0f11c8def0f3d07cfd5268825bb83 100644 (file)
@@ -324,6 +324,9 @@ std::for_each(authorizedUsers.begin(),
               authorizedUsers.end(),
               UpdateRouter(*this));
 
+logger("%s reloaded successfully.", rsSettings.GetMapFileName().c_str());
+printfd(__FILE__, "REMOTE_SCRIPT::Reload() %s reloaded successfully.\n");
+
 return 0;
 }
 //-----------------------------------------------------------------------------
@@ -546,14 +549,25 @@ authorizedUsers.insert(std::make_pair(user->GetCurrIP(), rsu));
 void REMOTE_SCRIPT::DelRSU(USER_PTR user)
 {
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-const std::map<uint32_t, RS::USER>::iterator it(
+std::map<uint32_t, RS::USER>::iterator it(authorizedUsers.begin());
+while (it != authorizedUsers.end())
+    {
+    if (it->second.user == user)
+        {
+        Send(it->second, true);
+        authorizedUsers.erase(it);
+        return;
+        }
+    ++it;
+    }
+/*const std::map<uint32_t, RS::USER>::iterator it(
         authorizedUsers.find(user->GetCurrIP())
         );
 if (it != authorizedUsers.end())
     {
     Send(it->second, true);
     authorizedUsers.erase(it);
-    }
+    }*/
 }
 //-----------------------------------------------------------------------------
 void RS::IP_NOTIFIER::Notify(const uint32_t & /*oldValue*/, const uint32_t & newValue)
index 31b91bb390ee431b7caf1e732832012586d5bb89..09cb4636795b1f72d567dc6274e2d74f788a2fad 100644 (file)
@@ -278,6 +278,11 @@ if (Stop())
     return -1;
 if (Start())
     return -1;
+if (!needReconnect)
+    {
+    printfd(__FILE__, "SMUX reconnected succesfully.\n");
+    logger("Reconnected successfully.");
+    }
 return 0;
 }
 
index 4e4489adcaa86614d32aaa0b390e24b5e513506b..0466b82490c97bfd576a2e477a7d0514257ab388 100644 (file)
@@ -728,7 +728,7 @@ for (int i = 0; i < DIR_NUM; i++)
         printfd(__FILE__, "FILES_STORE::RestoreUserStat - download stat read failed for user '%s'\n", login.c_str());
         return -1;
         }
-    stat->down[i] = traff;
+    stat->monthDown[i] = traff;
 
     snprintf(s, 22, "U%d", i);
     if (cf.ReadULongLongInt(s, &traff, 0) != 0)
@@ -738,7 +738,7 @@ for (int i = 0; i < DIR_NUM; i++)
         printfd(__FILE__, "FILES_STORE::RestoreUserStat - upload stat read failed for user '%s'\n", login.c_str());
         return -1;
         }
-    stat->up[i] = traff;
+    stat->monthUp[i] = traff;
     }
 
 if (cf.ReadDouble("Cash", &stat->cash, 0) != 0)
@@ -869,9 +869,9 @@ fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
     for (int i = 0; i < DIR_NUM; i++)
         {
         snprintf(s, 22, "D%d", i);
-        cfstat.WriteInt(s, stat.down[i]);
+        cfstat.WriteInt(s, stat.monthDown[i]);
         snprintf(s, 22, "U%d", i);
-        cfstat.WriteInt(s, stat.up[i]);
+        cfstat.WriteInt(s, stat.monthUp[i]);
         }
 
     cfstat.WriteDouble("Cash", stat.cash);
@@ -990,8 +990,8 @@ return WriteLog2String(logStr, login);
 }
 //-----------------------------------------------------------------------------
 int FILES_STORE::WriteUserDisconnect(const std::string & login,
-                                     const DIR_TRAFF & up,
-                                     const DIR_TRAFF & down,
+                                     const DIR_TRAFF & monthUp,
+                                     const DIR_TRAFF & monthDown,
                                      const DIR_TRAFF & sessionUp,
                                      const DIR_TRAFF & sessionDown,
                                      double cash,
@@ -1005,9 +1005,9 @@ logStr << "Disconnect, "
        << "\' session download: \'"
        << sessionDown
        << "\' month upload: \'"
-       << up
+       << monthUp
        << "\' month download: \'"
-       << down
+       << monthDown
        << "\' cash: \'"
        << cash
        << "\'";
@@ -1061,11 +1061,11 @@ for (size_t i = 0; i < DIR_NUM; i++)
     {
     char dirName[3];
     snprintf(dirName, 3, "U%llu", (unsigned long long)i);
-    s.WriteInt(dirName, stat.up[i]); // Classic
-    s2.WriteInt(dirName, stat.up[i]); // New
+    s.WriteInt(dirName, stat.monthUp[i]); // Classic
+    s2.WriteInt(dirName, stat.monthUp[i]); // New
     snprintf(dirName, 3, "D%llu", (unsigned long long)i);
-    s.WriteInt(dirName, stat.down[i]); // Classic
-    s2.WriteInt(dirName, stat.down[i]); // New
+    s.WriteInt(dirName, stat.monthDown[i]); // Classic
+    s2.WriteInt(dirName, stat.monthDown[i]); // New
     }
 
 // Classic
@@ -1483,6 +1483,11 @@ else
                 printfd(__FILE__, "FILES_STORE::RestoreTariff - invalid trafftype for tariff '%s'\n", tariffName.c_str());
                 return -1;
                 }
+
+if (conf.ReadString("Period", &str, "month") < 0)
+    td->tariffConf.period = TARIFF::MONTH;
+else
+    td->tariffConf.period = TARIFF::StringToPeriod(str);
 return 0;
 }
 //-----------------------------------------------------------------------------
@@ -1558,6 +1563,8 @@ std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
             cf.WriteString("TraffType", "max");
             break;
         }
+
+    cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period));
     }
 
 return 0;
@@ -1851,7 +1858,7 @@ if (rename((fileName + ".new").c_str(), fileName.c_str()) < 0)
     {
     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
     errorStr = "Error moving dir from " + fileName + ".new to " + fileName;
-    printfd(__FILE__, "FILES_STORE::SaveTariff - rename failed. Message: '%s'\n", strerror(errno));
+    printfd(__FILE__, "FILES_STORE::EditMessage - rename failed. Message: '%s'\n", strerror(errno));
     return -1;
     }
 
index 9cc7c3048b3462d088cd91ee21c94c6f307f4603..37b5184f8aabedfc6c2b8dee2b0a2bd4d2342644 100644 (file)
  *
  */
 
+#include "firebird_store.h"
+
+#include "stg/ibpp.h"
+#include "stg/plugin_creator.h"
+
 #include <string>
 #include <vector>
 #include <algorithm>
 
-#include "stg/ibpp.h"
-#include "stg/plugin_creator.h"
-#include "firebird_store.h"
+#include <cctype>
 
 namespace
 {
@@ -78,55 +81,41 @@ std::string s;
 for(i = settings.moduleParams.begin(); i != settings.moduleParams.end(); ++i)
     {
     s = i->param;
-    std::transform(s.begin(), s.end(), s.begin(), ToLower());
+
+    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
+
     if (s == "server")
-        {
         db_server = *(i->value.begin());
-        }
+
     if (s == "database")
-        {
         db_database = *(i->value.begin());
-        }
+
     if (s == "user")
-        {
         db_user = *(i->value.begin());
-        }
+
     if (s == "password")
-        {
         db_password = *(i->value.begin());
-        }
 
     // Advanced settings block
 
     if (s == "isolationLevel")
         {
         if (*(i->value.begin()) == "Concurrency")
-            {
             til = IBPP::ilConcurrency;
-            }
         else if (*(i->value.begin()) == "DirtyRead")
-            {
             til = IBPP::ilReadDirty;
-            }
         else if (*(i->value.begin()) == "ReadCommitted")
-            {
             til = IBPP::ilReadCommitted;
-            }
         else if (*(i->value.begin()) == "Consistency")
-            {
             til = IBPP::ilConsistency;
-            }
         }
+
     if (s == "lockResolution")
         {
         if (*(i->value.begin()) == "Wait")
-            {
             tlr = IBPP::lrWait;
-            }
         else if (*(i->value.begin()) == "NoWait")
-            {
             tlr = IBPP::lrNoWait;
-            }
         }
     }
 
@@ -134,6 +123,7 @@ try
     {
     db = IBPP::DatabaseFactory(db_server, db_database, db_user, db_password, "", "KOI8U", "");
     db->Connect();
+    return CheckVersion();
     }
 catch (IBPP::Exception & ex)
     {
@@ -145,3 +135,39 @@ catch (IBPP::Exception & ex)
 return 0;
 }
 //-----------------------------------------------------------------------------
+int FIREBIRD_STORE::CheckVersion()
+{
+IBPP::Transaction tr = IBPP::TransactionFactory(db, IBPP::amRead, til, tlr);
+IBPP::Statement st = IBPP::StatementFactory(db, tr);
+
+std::string name;
+
+try
+    {
+    tr->Start();
+    st->Execute("SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG=0 AND RDB$RELATION_NAME = 'TB_INFO'");
+    if (!st->Fetch())
+        {
+        schemaVersion = 0;
+        }
+    else
+        {
+        st->Execute("SELECT version FROM tb_info");
+        while (st->Fetch())
+            st->Get(1, schemaVersion);
+        }
+    tr->Commit();
+    logger("FIREBIRD_STORE: Current DB schema version: %d", schemaVersion);
+    }
+
+catch (IBPP::Exception & ex)
+    {
+    tr->Rollback();
+    strError = "IBPP exception";
+    printfd(__FILE__, ex.what());
+    return -1;
+    }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
index 638067f2011516f1228af789cb3769f0757d4278..688f0e88651da56258aad827b29d4ff92a21c6d7 100644 (file)
@@ -125,9 +125,11 @@ private:
     mutable pthread_mutex_t mutex;
     IBPP::TIL til;
     IBPP::TLR tlr;
+    int schemaVersion;
     PLUGIN_LOGGER logger;
 
     int SaveStat(const USER_STAT & stat, const std::string & login, int year = 0, int month = 0) const;
+    int CheckVersion();
 };
 
 time_t ts2time_t(const IBPP::Timestamp & ts);
index 1d74cf07e29d3f5978f0db3e3c2d415bfad66889..325e7d7f10b48c79978a04f52655f65a4f9d653c 100644 (file)
@@ -146,17 +146,36 @@ try
     }
     st->Get(1, id);
     st->Close();
-    st->Prepare("update tb_tariffs set \
-            fee = ?, \
-            free = ?, \
-            passive_cost = ?, \
-            traff_type = ? \
-            where pk_tariff = ?");
-    st->Set(1, td.tariffConf.fee);
-    st->Set(2, td.tariffConf.free);
-    st->Set(3, td.tariffConf.passiveCost);
-    st->Set(4, td.tariffConf.traffType);
-    st->Set(5, id);
+    if (schemaVersion > 0)
+        {
+        st->Prepare("update tb_tariffs set \
+                fee = ?, \
+                free = ?, \
+                passive_cost = ?, \
+                traff_type = ?, \
+                period = ? \
+                where pk_tariff = ?");
+        st->Set(1, td.tariffConf.fee);
+        st->Set(2, td.tariffConf.free);
+        st->Set(3, td.tariffConf.passiveCost);
+        st->Set(4, td.tariffConf.traffType);
+        st->Set(5, TARIFF::PeriodToString(td.tariffConf.period));
+        st->Set(6, id);
+        }
+    else
+        {
+        st->Prepare("update tb_tariffs set \
+                fee = ?, \
+                free = ?, \
+                passive_cost = ?, \
+                traff_type = ? \
+                where pk_tariff = ?");
+        st->Set(1, td.tariffConf.fee);
+        st->Set(2, td.tariffConf.free);
+        st->Set(3, td.tariffConf.passiveCost);
+        st->Set(4, td.tariffConf.traffType);
+        st->Set(5, id);
+        }
     st->Execute();
     st->Close();
 
@@ -200,7 +219,7 @@ try
             threshold = ?, \
             time_day_begins = ?, \
             time_day_ends = ? \
-             where fk_tariff = ? and dir_num = ?");
+            where fk_tariff = ? and dir_num = ?");
     st->Set(1, pda);
     st->Set(2, pdb);
     st->Set(3, pna);
@@ -246,7 +265,7 @@ td->tariffConf.name = tariffName;
 try
     {
     tr->Start();
-    st->Prepare("select * from tb_tariffs where name = ?");
+    st->Prepare("select * from tb_tariffs where name = ?"); // TODO: explicit field order!
     st->Set(1, tariffName);
     st->Execute();
     if (!st->Fetch())
@@ -261,6 +280,12 @@ try
     st->Get(4, td->tariffConf.free);
     st->Get(5, td->tariffConf.passiveCost);
     st->Get(6, td->tariffConf.traffType);
+    if (schemaVersion > 0)
+        {
+        std::string period;
+        st->Get(7, period);
+        td->tariffConf.period = TARIFF::StringToPeriod(period);
+        }
     st->Close();
     st->Prepare("select * from tb_tariffs_params where fk_tariff = ?");
     st->Set(1, id);
index 8b21907e76c1d58e52824b653b3877099530b3c4..3f00b16bbd8517b0b81a852bb9844f34f372eadf 100644 (file)
@@ -204,8 +204,8 @@ try
                         upload = ?, \
                         download = ? \
                      where fk_stat = ? and dir_num = ?");
-        st->Set(1, (int64_t)stat.up[i]);
-        st->Set(2, (int64_t)stat.down[i]);
+        st->Set(1, (int64_t)stat.monthUp[i]);
+        st->Set(2, (int64_t)stat.monthDown[i]);
         st->Set(3, sid);
         st->Set(4, i);
         st->Execute();
@@ -337,7 +337,7 @@ try
     st->Execute();
 
     st->Prepare("insert into tb_allowed_ip (fk_user, ip, mask) values (?, ?, ?)");
-    for(i = 0; i < conf.ips.Count(); i++)
+    for(size_t i = 0; i < conf.ips.Count(); i++)
         {
         st->Set(1, uid);
         st->Set(2, (int32_t)conf.ips[i].ip);
@@ -421,8 +421,8 @@ try
         if (st->Fetch())
             {
             st->Get(3, dir);
-            st->Get(5, (int64_t &)stat->up[dir]);
-            st->Get(4, (int64_t &)stat->down[dir]);
+            st->Get(5, (int64_t &)stat->monthUp[dir]);
+            st->Get(4, (int64_t &)stat->monthDown[dir]);
             }
         else
             {
index b4ac87155a762d5510d4700f624decf959956fd2..53de158aa660986ab6f09e83477f3277bfa0b4bd 100644 (file)
@@ -12,6 +12,7 @@
 #include "stg/user_stat.h"
 #include "stg/blowfish.h"
 #include "stg/plugin_creator.h"
+#include "stg/logger.h"
 #include "mysql_store.h"
 
 #define adm_enc_passwd "cjeifY8m3"
@@ -235,12 +236,18 @@ else
                  }
                  ret = CheckAllTables(sock);
             }
-         }
-         else
-             ret = CheckAllTables(sock);
-         mysql_close(sock);
+        }
+        else
+        {
+            ret = CheckAllTables(sock);
+        }
+        if (!ret)
+        {
+            logger("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
+            MakeUpdates(sock);
+        }
+        mysql_close(sock);
     }
-    
 }
 return ret;
 }
@@ -267,6 +274,43 @@ return num_rows == 1;
 //-----------------------------------------------------------------------------
 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
 {
+//info-------------------------------------------------------------------------
+if(!IsTablePresent("info",sock))
+{
+    sprintf(qbuf,"CREATE TABLE info (version INTEGER NOT NULL)");
+
+    if(MysqlQuery(qbuf,sock))
+        {
+        errorStr = "Couldn't create info table With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+
+    sprintf(qbuf,"INSERT INTO info SET version=0");
+
+    if(MysqlQuery(qbuf,sock))
+        {
+        errorStr = "Couldn't write default version. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+    schemaVersion = 0;
+}
+else
+{
+    std::vector<std::string> info;
+    if (GetAllParams(&info, "info", "version"))
+        schemaVersion = 0;
+    else
+    {
+        if (info.empty())
+            schemaVersion = 0;
+        else
+            GetInt(info.front(), &schemaVersion, 0);
+    }
+}
 //admins-----------------------------------------------------------------------
 if(!IsTablePresent("admins",sock))
 {
@@ -330,8 +374,9 @@ if(!IsTablePresent("tariffs",sock))
         res += param;
         }
     
-    res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"\
-        "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '')";
+    res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"
+        "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '',"
+        "period VARCHAR(32) NOT NULL DEFAULT 'month')";
     
     if(MysqlQuery(res.c_str(),sock))
     {
@@ -385,7 +430,7 @@ if(!IsTablePresent("tariffs",sock))
     
     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
-        "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down'";
+        "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down',period='month'";
     
     if(MysqlQuery(res.c_str(),sock))
     {
@@ -394,6 +439,17 @@ if(!IsTablePresent("tariffs",sock))
         mysql_close(sock);
         return -1;
     }
+
+    sprintf(qbuf,"UPDATE info SET version=1");
+
+    if(MysqlQuery(qbuf,sock))
+    {
+        errorStr = "Couldn't write default version. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+    }
+    schemaVersion = 1;
 }
 
 //users-----------------------------------------------------------------------
@@ -525,6 +581,29 @@ if(!IsTablePresent("stat",sock))
 return 0;
 }
 //-----------------------------------------------------------------------------
+int MYSQL_STORE::MakeUpdates(MYSQL * sock)
+{
+if (schemaVersion  < 1)
+    {
+    if (MysqlQuery("ALTER TABLE tariffs ADD period VARCHAR(32) NOT NULL DEFAULT 'month'", sock))
+        {
+        errorStr = "Couldn't update tariffs table to version 1. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+    if (MysqlQuery("UPDATE info SET version = 1", sock))
+        {
+        errorStr = "Couldn't update DB schema version to 1. With error:\n";
+        errorStr += mysql_error(sock);
+        mysql_close(sock);
+        return -1;
+        }
+    schemaVersion = 1;
+    logger("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
+    }
+return 0;
+}
 //-----------------------------------------------------------------------------
 
 int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList, 
@@ -824,7 +903,7 @@ for (int i = 0; i < DIR_NUM; i++)
         mysql_close(sock);
         return -1;
         }
-    stat->down[i] = traff;
+    stat->monthDown[i] = traff;
 
     sprintf(s, "U%d", i);
     if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
@@ -834,7 +913,7 @@ for (int i = 0; i < DIR_NUM; i++)
         mysql_close(sock);
         return -1;
         }
-    stat->up[i] = traff;
+    stat->monthUp[i] = traff;
     }//for
 
 startPos += (2*DIR_NUM);
@@ -954,10 +1033,10 @@ res = "UPDATE users SET";
 
 for (int i = 0; i < DIR_NUM; i++)
     {
-    strprintf(&param, " D%d=%lld,", i, stat.down[i]);
+    strprintf(&param, " D%d=%lld,", i, stat.monthDown[i]);
     res += param;
 
-    strprintf(&param, " U%d=%lld,", i, stat.up[i]);
+    strprintf(&param, " U%d=%lld,", i, stat.monthUp[i]);
     res += param;
     }
 
@@ -1117,10 +1196,10 @@ strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,",
     
 for (int i = 0; i < DIR_NUM; i++)
     {
-    strprintf(&param, " U%d=%lld,", i, stat.up[i]); 
+    strprintf(&param, " U%d=%lld,", i, stat.monthUp[i]); 
     res += param;
 
-    strprintf(&param, " D%d=%lld,", i, stat.down[i]);        
+    strprintf(&param, " D%d=%lld,", i, stat.monthDown[i]);        
     res += param;
     }
     
@@ -1561,6 +1640,26 @@ else
                 return -1;
                 }
 
+if (schemaVersion > 0)
+{
+    str = row[5+8*DIR_NUM];
+    param = "Period";
+
+    if (str.length() == 0)
+        {
+        mysql_free_result(res);
+        errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
+        mysql_close(sock);
+        return -1;
+        }
+
+    td->tariffConf.period = TARIFF::StringToPeriod(str);
+    }
+else
+    {
+    td->tariffConf.period = TARIFF::MONTH;
+    }
+
 mysql_free_result(res);
 mysql_close(sock);
 return 0;
@@ -1638,12 +1737,16 @@ switch (td.tariffConf.traffType)
         res += " TraffType='max'";
         break;
     }
+
+if (schemaVersion > 0)
+    res += ", Period='" + TARIFF::PeriodToString(td.tariffConf.period) + "'";
+
 strprintf(&param, " WHERE name='%s' LIMIT 1", tariffName.c_str());
 res += param;
 
 if(MysqlSetQuery(res.c_str()))
 {
-    errorStr = "Couldn't save admin:\n";
+    errorStr = "Couldn't save tariff:\n";
     //errorStr += mysql_error(sock);
     return -1;
 }
index af747c14518662884bbbf27359b22e7b8bff6758..4a492b3833694ece04130acf72fc81be96e78034 100644 (file)
@@ -132,6 +132,7 @@ private:
     virtual int WriteLogString(const std::string & str, const std::string & login) const;
     int GetAllParams(std::vector<std::string> * ParamList, const std::string & table, const std::string & name) const;
     int CheckAllTables(MYSQL * sock);
+    int MakeUpdates(MYSQL * sock);
     bool IsTablePresent(const std::string & str,MYSQL * sock);
     mutable std::string          errorStr;
     int                        MysqlQuery(const char* sQuery,MYSQL * sock) const;
@@ -141,6 +142,7 @@ private:
     std::string                  version;
     MYSQL_STORE_SETTINGS    storeSettings;
     MODULE_SETTINGS         settings;
+    int                     schemaVersion;
 
     PLUGIN_LOGGER           logger;
 };
index dd2fbbab7a168ed159feff737cf04e63be0f4898..37ff6dbdda10207f30a81ca520b8cc0234b1e6a0 100644 (file)
  *
  */
 
-#include <string>
-#include <vector>
-#include <algorithm>
-
-#include <libpq-fe.h>
+#include "postgresql_store.h"
 
 #include "stg/module_settings.h"
 #include "stg/plugin_creator.h"
-#include "postgresql_store_utils.h"
-#include "postgresql_store.h"
+
+#include <libpq-fe.h>
+
+#include <string>
+#include <vector>
 
 namespace
 {
@@ -93,37 +92,25 @@ pthread_mutex_destroy(&mutex);
 int POSTGRESQL_STORE::ParseSettings()
 {
 std::vector<PARAM_VALUE>::iterator i;
-std::string s;
 
 for(i = settings.moduleParams.begin(); i != settings.moduleParams.end(); ++i)
     {
-    s = i->param;
-    std::transform(s.begin(), s.end(), s.begin(), ToLower());
-    if (s == "server")
-        {
+    std::string param(ToLower(i->param));
+    if (param == "server")
         server = *(i->value.begin());
-        }
-    if (s == "database")
-        {
+    else if (param == "database")
         database = *(i->value.begin());
-        }
-    if (s == "user")
-        {
+    else if (param == "user")
         user = *(i->value.begin());
-        }
-    if (s == "password")
-        {
+    else if (param == "password")
         password = *(i->value.begin());
-        }
-    if (s == "retries")
-        {
+    else if (param == "retries")
         if (str2x(*(i->value.begin()), retries))
             {
             strError = "Invalid 'retries' value";
             printfd(__FILE__, "POSTGRESQL_STORE::ParseSettings(): '%s'\n", strError.c_str());
             return -1;
             }
-        }
     }
 
 clientEncoding = "KOI8";
@@ -237,6 +224,8 @@ if (CommitTransaction())
     return -1;
     }
 
+logger("POSTGRESQL_STORE: Current DB schema version: %d", version);
+
 return 0;
 }
 //-----------------------------------------------------------------------------
index fb8caf9dee0b97b9d9a8a76724bd3f4595ae0301..c9cb7ccfe79f19968eb646c81b2f57652f16985d 100644 (file)
@@ -122,9 +122,9 @@ if (EscapeString(ename))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -185,9 +185,9 @@ if (EscapeString(ename))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to escape name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::AddTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -249,9 +249,9 @@ if (EscapeString(ename))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to escape name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -286,9 +286,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -307,8 +307,12 @@ if (tuples != 1)
                   fee = " << td.tariffConf.fee << ", \
                   free = " << td.tariffConf.free << ", \
                   passive_cost = " << td.tariffConf.passiveCost << ", \
-                  traff_type = " << td.tariffConf.traffType << " \
-              WHERE pk_tariff = " << id;
+                  traff_type = " << td.tariffConf.traffType;
+
+    if (version > 6)
+        query << ", period = '" << TARIFF::PeriodToString(td.tariffConf.period) << "'";
+
+    query << " WHERE pk_tariff = " << id;
 
     result = PQexec(connection, query.str().c_str());
     }
@@ -426,9 +430,9 @@ if (EscapeString(ename))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to escape name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -437,10 +441,14 @@ td->tariffConf.name = tariffName;
 std::ostringstream query;
 query << "SELECT pk_tariff, \
                  fee, \
-                free, \
-                passive_cost, \
-                traff_type \
-         FROM tb_tariffs WHERE name = '" << ename << "'";
+                 free, \
+                 passive_cost, \
+                 traff_type";
+
+if (version > 6)
+    query << ", period";
+
+query << " FROM tb_tariffs WHERE name = '" << ename << "'";
 
 result = PQexec(connection, query.str().c_str());
 
@@ -464,9 +472,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -487,21 +495,24 @@ int id;
     tuple >> td->tariffConf.traffType;
     }
 
+if (version > 6)
+    td->tariffConf.period = TARIFF::StringToPeriod(PQgetvalue(result, 0, 5));
+
 PQclear(result);
 
 query.str("");
 query << "SELECT dir_num, \
                  price_day_a, \
                  price_day_b, \
-                price_night_a, \
-                price_night_b, \
-                threshold, \
-                EXTRACT(hour FROM time_day_begins), \
-                EXTRACT(minute FROM time_day_begins), \
-                EXTRACT(hour FROM time_day_ends), \
-                EXTRACT(minute FROM time_day_ends) \
-         FROM tb_tariffs_params \
-         WHERE fk_tariff = " << id;
+                 price_night_a, \
+                 price_night_b, \
+                 threshold, \
+                 EXTRACT(hour FROM time_day_begins), \
+                 EXTRACT(minute FROM time_day_begins), \
+                 EXTRACT(hour FROM time_day_ends), \
+                 EXTRACT(minute FROM time_day_ends) \
+          FROM tb_tariffs_params \
+          WHERE fk_tariff = " << id;
 
 result = PQexec(connection, query.str().c_str());
 
@@ -511,9 +522,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreTariff(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
index 4cd64418e9d3f370263e2d1553f13073da07c29b..3331a07d411692bfe957d6085b8e968afc903a75 100644 (file)
@@ -70,9 +70,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::GetUsersList(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -124,9 +124,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -141,9 +141,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::AddUser(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -188,9 +188,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -205,9 +205,9 @@ if (PQresultStatus(result) != PGRES_COMMAND_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::DelUser(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -260,9 +260,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -284,9 +284,9 @@ if (PQresultStatus(result) != PGRES_COMMAND_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -303,8 +303,8 @@ for (int dir = 0; dir < DIR_NUM; ++dir)
                 "'" << elogin << "', "
                 "CAST('" << date << "' AS DATE), "
                 "CAST(" << dir << " AS SMALLINT), "
-                "CAST(" << stat.up[dir] << " AS BIGINT), "
-                "CAST(" << stat.down[dir] << " AS BIGINT))";
+                "CAST(" << stat.monthUp[dir] << " AS BIGINT), "
+                "CAST(" << stat.monthDown[dir] << " AS BIGINT))";
 
     result = PQexec(connection, query.str().c_str());
 
@@ -363,9 +363,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -380,9 +380,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -394,9 +394,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -426,9 +426,9 @@ if (EscapeString(eaddress))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape address'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -436,9 +436,9 @@ if (EscapeString(eemail))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape email'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -446,9 +446,9 @@ if (EscapeString(egroup))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape group'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -456,9 +456,9 @@ if (EscapeString(enote))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape note'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -466,9 +466,9 @@ if (EscapeString(epassword))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape password'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -476,9 +476,9 @@ if (EscapeString(ephone))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape phone'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -486,9 +486,9 @@ if (EscapeString(erealname))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape real name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -496,9 +496,9 @@ if (EscapeString(etariffname))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape tariff name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -506,9 +506,9 @@ if (EscapeString(enexttariff))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape next tariff name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -516,9 +516,9 @@ if (EscapeString(ecorporation))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to escape corporation name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -556,9 +556,9 @@ if (PQresultStatus(result) != PGRES_COMMAND_OK)
     PQclear(result);
     printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): '%s'\n", strError.c_str());
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -634,9 +634,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -657,9 +657,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -671,9 +671,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -710,9 +710,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -728,8 +728,8 @@ for (int i = 0; i < tuples; ++i)
     int dir;
 
     tuple >> dir;
-    tuple >> stat->up[dir];
-    tuple >> stat->down[dir];
+    tuple >> stat->monthUp[dir];
+    tuple >> stat->monthDown[dir];
     }
 
 PQclear(result);
@@ -774,9 +774,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -804,9 +804,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -818,9 +818,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -873,9 +873,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -903,9 +903,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -945,9 +945,9 @@ if (PQresultStatus(result) != PGRES_TUPLES_OK)
     printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::RestoreUserConf(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1026,9 +1026,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1036,9 +1036,9 @@ if (EscapeString(eadminLogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape admin's login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1046,9 +1046,9 @@ if (EscapeString(eparam))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape param's name'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1056,9 +1056,9 @@ if (EscapeString(eold))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape old value'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1066,9 +1066,9 @@ if (EscapeString(enew))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to escape new value'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserChgLog(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1138,9 +1138,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserConnect(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1189,8 +1189,8 @@ return 0;
 
 //-----------------------------------------------------------------------------
 int POSTGRESQL_STORE::WriteUserDisconnect(const std::string & login,
-                    const DIR_TRAFF & up,
-                    const DIR_TRAFF & down,
+                    const DIR_TRAFF & monthUp,
+                    const DIR_TRAFF & monthDown,
                     const DIR_TRAFF & sessionUp,
                     const DIR_TRAFF & sessionDown,
                     double cash,
@@ -1224,9 +1224,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1236,9 +1236,9 @@ if (EscapeString(ereason))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to escape reason'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1285,9 +1285,9 @@ if (tuples != 1)
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Invalid number of tuples. Wanted 1, actulally %d'\n", tuples);
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1299,9 +1299,9 @@ if (str2x(PQgetvalue(result, 0, 0), lid))
     printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): '%s'\n", strError.c_str());
     PQclear(result);
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteUserDisconnect(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1322,8 +1322,8 @@ for (int i = 0; i < DIR_NUM; ++i)
                 << i << ", "
                 << sessionUp[i] << ", "
                 << sessionDown[i] << ", "
-                << up[i] << ", "
-                << down[i] << ")";
+                << monthUp[i] << ", "
+                << monthDown[i] << ")";
 
     result = PQexec(connection, query.str().c_str());
 
@@ -1383,9 +1383,9 @@ if (EscapeString(elogin))
     {
     printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to escape login'\n");
     if (RollbackTransaction())
-       {
-       printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
-       }
+        {
+        printfd(__FILE__, "POSTGRESQL_STORE::WriteDetailedStat(): 'Failed to rollback transaction'\n");
+        }
     return -1;
     }
 
@@ -1525,7 +1525,7 @@ if (PQresultStatus(result) != PGRES_COMMAND_OK)
 
 PQclear(result);
 
-for (int i = 0; i < ips.Count(); ++i)
+for (size_t i = 0; i < ips.Count(); ++i)
     {
     std::ostringstream query;
     query << "INSERT INTO tb_allowed_ip "
index f5dec89ff5ec223159423d3cabe3d2846157ed6e..ef70505389fc372eb2425398903256a805e4882f 100644 (file)
  *
  */
 
+#include "postgresql_store.h"
+
+#include "stg/common.h"
+
 #include <string>
 #include <ctime>
 
 #include <libpq-fe.h>
 
-#include "stg/common.h"
-#include "postgresql_store.h"
-
 extern volatile time_t stgTime;
 
 int POSTGRESQL_STORE::StartTransaction() const
@@ -93,10 +94,10 @@ int error = 0;
 char * buf = new char[(value.length() << 1) + 1];
 
 PQescapeStringConn(connection,
-                  buf,
-                  value.c_str(),
-                  value.length(),
-                  &error);
+                   buf,
+                   value.c_str(),
+                   value.length(),
+                   &error);
 
 if (error)
     {
@@ -114,7 +115,6 @@ return 0;
 
 std::string POSTGRESQL_STORE::Int2TS(time_t ts) const
 {
-char buf[32];
 struct tm brokenTime;
 
 brokenTime.tm_wday = 0;
@@ -123,6 +123,7 @@ brokenTime.tm_isdst = 0;
 
 gmtime_r(&ts, &brokenTime);
 
+char buf[32];
 strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &brokenTime);
 
 return buf;
@@ -160,8 +161,6 @@ if (year)
 else
     {
     time_t curTime = stgTime;
-    /*time(&curTime);*/
-
     localtime_r(&curTime, &brokenTime);
     }
 
@@ -173,4 +172,3 @@ strftime(buf, 32, "%Y-%m-%d", &brokenTime);
 
 date = buf;
 }
-
diff --git a/projects/stargazer/plugins/store/postgresql/postgresql_store_utils.h b/projects/stargazer/plugins/store/postgresql/postgresql_store_utils.h
deleted file mode 100644 (file)
index 4ffa6ec..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef POSTGRESQL_UTILS_STORE_H
-#define POSTGRESQL_UTILS_STORE_H
-
-#include <functional>
-
-struct ToLower : public std::unary_function<char, char>
-{
-char operator() (char c) const  { return static_cast<char>(std::tolower(c)); }
-};
-
-#endif
index 122dabd044de29178d083c0849c4b4ba857a9fef..f2f84d2630889f73432e9a191459c8174c37adf3 100644 (file)
@@ -71,6 +71,7 @@ public:
     double  GetPassiveCost() const { return tariffData.tariffConf.passiveCost; }
     double  GetFee() const { return tariffData.tariffConf.fee; }
     double  GetFree() const { return tariffData.tariffConf.free; }
+    PERIOD  GetPeriod() const { return tariffData.tariffConf.period; }
 
     void    Print() const;
 
index 17a786ff0a9697f7c9ccc0aa99eb247695950df3..fce475952537b598d5f39864d6975fe863d3be67 100644 (file)
@@ -738,8 +738,8 @@ if (ReadRules(true))
 
 FreeRules();
 ReadRules();
-printfd(__FILE__, "TRAFFCOUNTER_IMPL::Reload() -  Reload rules successfull.\n");
-WriteServLog("TRAFFCOUNTER: Reload rules successfull.");
+printfd(__FILE__, "TRAFFCOUNTER_IMPL::Reload() -  Reloaded rules successfully.\n");
+WriteServLog("TRAFFCOUNTER: Reloaded rules successfully.");
 return 0;
 }
 //-----------------------------------------------------------------------------
index fff3f58de26103710a4394f2398e1dbfbafb90c0..7f6ff352f7fb4677cd5947c0ebf9dbde4d12a20e 100644 (file)
 #define _GNU_SOURCE
 #endif
 
-#include <pthread.h>
-#include <unistd.h> // access
-
-#include <cassert>
-#include <cstdlib>
-#include <cmath>
+#include "user_impl.h"
+#include "settings_impl.h"
+#include "stg_timer.h"
 
 #include "stg/users.h"
 #include "stg/common.h"
 #include "stg/tariff.h"
 #include "stg/tariffs.h"
 #include "stg/admin.h"
-#include "user_impl.h"
-#include "settings_impl.h"
-#include "stg_timer.h"
+
+#include <algorithm>
+#include <functional>
+
+#include <cassert>
+#include <cstdlib>
+#include <cmath>
+
+#include <pthread.h>
+#include <unistd.h> // access
 
 #ifdef USE_ABSTRACT_SETTINGS
 USER_IMPL::USER_IMPL(const SETTINGS * s,
@@ -60,12 +64,9 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       property(s->GetScriptsDir()),
       WriteServLog(GetStgLogger()),
       lastScanMessages(0),
-      login(),
       id(0),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
-      userIDGenerator(),
       __currIP(0),
       currIP(__currIP),
       lastIPForDisconnect(0),
@@ -74,11 +75,8 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       store(st),
       tariffs(t),
       tariff(NULL),
-      traffStat(),
-      traffStatSaved(),
       settings(s),
-      authorizedBy(),
-      messages(),
+      authorizedModificationTime(0),
       deleted(false),
       lastWriteStat(0),
       lastWriteDetailedStat(0),
@@ -116,14 +114,10 @@ USER_IMPL::USER_IMPL(const SETTINGS * s,
       userdata7(property.userdata7),
       userdata8(property.userdata8),
       userdata9(property.userdata9),
-      sessionUpload(),
-      sessionDownload(),
       passiveNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 password = "*_EMPTY_PASSWORD_*";
 tariffName = NO_TARIFF_NAME;
@@ -153,12 +147,9 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       property(s->GetScriptsDir()),
       WriteServLog(GetStgLogger()),
       lastScanMessages(0),
-      login(),
       id(0),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
-      userIDGenerator(),
       __currIP(0),
       currIP(__currIP),
       lastIPForDisconnect(0),
@@ -167,11 +158,8 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       store(st),
       tariffs(t),
       tariff(NULL),
-      traffStat(),
-      traffStatSaved(),
       settings(s),
-      authorizedBy(),
-      messages(),
+      authorizedModificationTime(0),
       deleted(false),
       lastWriteStat(0),
       lastWriteDetailedStat(0),
@@ -209,15 +197,11 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s,
       userdata7(property.userdata7),
       userdata8(property.userdata8),
       userdata9(property.userdata9),
-      sessionUpload(),
-      sessionDownload(),
       passiveNotifier(this),
       disabledNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 password = "*_EMPTY_PASSWORD_*";
 tariffName = NO_TARIFF_NAME;
@@ -248,7 +232,6 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       id(u.id),
       __connected(0),
       connected(__connected),
-      enabledDirs(),
       userIDGenerator(u.userIDGenerator),
       __currIP(u.__currIP),
       currIP(__currIP),
@@ -261,7 +244,7 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       traffStat(u.traffStat),
       traffStatSaved(u.traffStatSaved),
       settings(u.settings),
-      authorizedBy(),
+      authorizedModificationTime(u.authorizedModificationTime),
       messages(u.messages),
       deleted(u.deleted),
       lastWriteStat(u.lastWriteStat),
@@ -306,9 +289,7 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u)
       disabledNotifier(this),
       tariffNotifier(this),
       cashNotifier(this),
-      ipNotifier(this),
-      mutex(),
-      errorStr()
+      ipNotifier(this)
 {
 if (&u == this)
     return;
@@ -535,6 +516,8 @@ else
         }
     }
 
+if (authorizedBy.empty())
+    authorizedModificationTime = stgTime;
 authorizedBy.insert(auth);
 
 ScanMessage();
@@ -542,7 +525,7 @@ ScanMessage();
 return 0;
 }
 //-----------------------------------------------------------------------------
-void USER_IMPL::Unauthorize(const AUTH * auth)
+void USER_IMPL::Unauthorize(const AUTH * auth, const std::string & reason)
 {
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 /*
@@ -553,6 +536,8 @@ if (!authorizedBy.erase(auth))
 
 if (authorizedBy.empty())
     {
+    authorizedModificationTime = stgTime;
+    lastDisconnectReason = reason;
     lastIPForDisconnect = currIP;
     currIP = 0; // DelUser in traffcounter
     return;
@@ -566,6 +551,13 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 return authorizedBy.find(auth) != authorizedBy.end();
 }
 //-----------------------------------------------------------------------------
+std::vector<std::string> USER_IMPL::GetAuthorizers() const
+{
+    std::vector<std::string> list;
+    std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), std::mem_fun(&AUTH::GetVersion));
+    return list;
+}
+//-----------------------------------------------------------------------------
 void USER_IMPL::Connect(bool fakeConnect)
 {
 /*
@@ -641,6 +633,7 @@ if (!lastIPForDisconnect)
 
 if (!fakeDisconnect)
     {
+    lastDisconnectReason = reason;
     std::string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect";
 
     if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
@@ -679,7 +672,12 @@ if (!fakeDisconnect)
     connected = false;
     }
 
-if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason))
+std::string reasonMessage(reason);
+if (!lastDisconnectReason.empty())
+    reasonMessage += ": " + lastDisconnectReason;
+
+if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload,
+                               cash, freeMb, reasonMessage))
     {
     WriteServLog("Cannot write disconnect for user %s.", login.c_str());
     WriteServLog("%s", store->GetStrError().c_str());
@@ -1255,6 +1253,9 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 if (passive.ConstData() || tariff == NULL)
     return;
 
+if (tariff->GetPeriod() != TARIFF::MONTH)
+    return;
+
 double fee = tariff->GetFee() / DaysInCurrentMonth();
 
 if (std::fabs(fee) < 1.0e-3)
@@ -1289,6 +1290,9 @@ STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 if (tariff == NULL)
     return;
 
+if (tariff->GetPeriod() != TARIFF::MONTH)
+    return;
+
 double passiveTimePart = 1.0;
 if (!settings->GetFullFee())
     {
@@ -1350,6 +1354,39 @@ switch (settings->GetFeeChargeType())
     }
 }
 //-----------------------------------------------------------------------------
+void USER_IMPL::ProcessDailyFee()
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+
+if (passive.ConstData() || tariff == NULL)
+    return;
+
+if (tariff->GetPeriod() != TARIFF::DAY)
+    return;
+
+double fee = tariff->GetFee();
+
+if (fee == 0.0)
+    return;
+
+double c = cash;
+switch (settings->GetFeeChargeType())
+    {
+    case 0:
+        property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+        break;
+    case 1:
+        if (c + credit >= 0)
+            property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+        break;
+    case 2:
+        if (c + credit >= fee)
+            property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+        break;
+    }
+ResetPassiveTime();
+}
+//-----------------------------------------------------------------------------
 void USER_IMPL::SetPrepaidTraff()
 {
 if (tariff != NULL)
index 38d3c013230cb44db4990a4e33b65b528c50a280..5b51fc5d040f4441c80d2b2ef124e5efe6c19d6d 100644 (file)
 #ifndef USER_IMPL_H
 #define USER_IMPL_H
 
-#include <ctime>
-#include <list>
-#include <string>
-#include <set>
-
 #include "stg/user.h"
-#include "stg/os_int.h"
-#include "stg/const.h"
 #include "stg/user_stat.h"
 #include "stg/user_conf.h"
 #include "stg/user_ips.h"
 #include "stg/auth.h"
 #include "stg/message.h"
 #include "stg/noncopyable.h"
+#include "stg/os_int.h"
+#include "stg/const.h"
+
+#include <list>
+#include <vector>
+#include <string>
+#include <set>
+
+#include <ctime>
 
 //-----------------------------------------------------------------------------
 class TARIFF;
@@ -182,10 +184,14 @@ public:
 
     bool            GetConnected() const { return connected; }
     time_t          GetConnectedModificationTime() const { return connected.ModificationTime(); }
+    const std::string & GetLastDisconnectReason() const { return lastDisconnectReason; }
     int             GetAuthorized() const { return static_cast<int>(authorizedBy.size()); }
+    time_t          GetAuthorizedModificationTime() const { return authorizedModificationTime; }
     int             Authorize(uint32_t ip, uint32_t enabledDirs, const AUTH * auth);
-    void            Unauthorize(const AUTH * auth);
+    void            Unauthorize(const AUTH * auth,
+                                const std::string & reason = std::string());
     bool            IsAuthorizedBy(const AUTH * auth) const;
+    std::vector<std::string> GetAuthorizers() const;
 
     int             AddMessage(STG_MSG * msg);
 
@@ -209,6 +215,7 @@ public:
     void            ProcessDayFee();
     void            ProcessDayFeeSpread();
     void            ProcessNewMonth();
+    void            ProcessDailyFee();
 
     bool            IsInetable();
     std::string     GetEnabledDirs() const;
@@ -249,6 +256,7 @@ private:
     USER_PROPERTY<uint32_t> currIP;
 
     uint32_t        lastIPForDisconnect; // User's ip after unauth but before disconnect
+    std::string     lastDisconnectReason;
 
     time_t          pingTime;
 
@@ -268,6 +276,7 @@ private:
 #endif
 
     std::set<const AUTH *> authorizedBy;
+    time_t          authorizedModificationTime;
 
     std::list<STG_MSG> messages;
 
index a94b60a4215d22b1e10bc520e286ef866124822d..a0c974bc2f71c086bd77461ad5267c5053fba443 100644 (file)
@@ -4,15 +4,14 @@ USER_PROPERTIES::USER_PROPERTIES(const std::string & sd)
     : stat(),
       conf(),
       cash            (stat.cash,             "cash",             false, true, GetStgLogger(), sd, properties),
-      up              (stat.up,               "upload",           false, true, GetStgLogger(), sd, properties),
-      down            (stat.down,             "download",         false, true, GetStgLogger(), sd, properties),
+      up              (stat.monthUp,          "upload",           false, true, GetStgLogger(), sd, properties),
+      down            (stat.monthDown,        "download",         false, true, GetStgLogger(), sd, properties),
       lastCashAdd     (stat.lastCashAdd,      "lastCashAdd",      false, true, GetStgLogger(), sd, properties),
       passiveTime     (stat.passiveTime,      "passiveTime",      false, true, GetStgLogger(), sd, properties),
       lastCashAddTime (stat.lastCashAddTime,  "lastCashAddTime",  false, true, GetStgLogger(), sd, properties),
       freeMb          (stat.freeMb,           "freeMb",           false, true, GetStgLogger(), sd, properties),
       lastActivityTime(stat.lastActivityTime, "lastActivityTime", false, true, GetStgLogger(), sd, properties),
 
-
       password    (conf.password,     "password",     true,  false, GetStgLogger(), sd, properties),
       passive     (conf.passive,      "passive",      false, false, GetStgLogger(), sd, properties),
       disabled    (conf.disabled,     "disabled",     false, false, GetStgLogger(), sd, properties),
index 17d1e4f77fcd88099fb75d6e00bf8163f48aaae4..f4b4dea0b800420259afb1caef46753936398332 100644 (file)
@@ -88,23 +88,39 @@ pthread_mutex_destroy(&mutex);
 //-----------------------------------------------------------------------------
 int USERS_IMPL::FindByNameNonLock(const std::string & login, user_iter * user)
 {
-std::map<std::string, user_iter>::iterator iter;
-iter = loginIndex.find(login);
-if (iter != loginIndex.end())
-    {
-    if (user)
-        *user = iter->second;
-    return 0;
-    }
-return -1;
+const std::map<std::string, user_iter>::const_iterator iter(loginIndex.find(login));
+if (iter == loginIndex.end())
+    return -1;
+if (user)
+    *user = iter->second;
+return 0;
+}
+//-----------------------------------------------------------------------------
+int USERS_IMPL::FindByNameNonLock(const std::string & login, const_user_iter * user) const
+{
+const std::map<std::string, user_iter>::const_iterator iter(loginIndex.find(login));
+if (iter == loginIndex.end())
+    return -1;
+if (user)
+    *user = iter->second;
+return 0;
 }
 //-----------------------------------------------------------------------------
 int USERS_IMPL::FindByName(const std::string & login, USER_PTR * user)
 {
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 user_iter u;
-int res = FindByNameNonLock(login, &u);
-if (res)
+if (FindByNameNonLock(login, &u))
+    return -1;
+*user = &(*u);
+return 0;
+}
+//-----------------------------------------------------------------------------
+int USERS_IMPL::FindByName(const std::string & login, CONST_USER_PTR * user) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+const_user_iter u;
+if (FindByNameNonLock(login, &u))
     return -1;
 *user = &(*u);
 return 0;
@@ -298,7 +314,9 @@ AddToIPIdx(iter);
 return true;
 }
 //-----------------------------------------------------------------------------
-bool USERS_IMPL::Unauthorize(const std::string & login, const AUTH * auth)
+bool USERS_IMPL::Unauthorize(const std::string & login,
+                             const AUTH * auth,
+                             const std::string & reason)
 {
 user_iter iter;
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
@@ -310,7 +328,7 @@ if (FindByNameNonLock(login, &iter))
 
 uint32_t ip = iter->GetCurrIP();
 
-iter->Unauthorize(auth);
+iter->Unauthorize(auth, reason);
 
 if (!iter->GetAuthorized())
     DelFromIPIdx(ip);
@@ -495,6 +513,8 @@ else
         }
     }
 
+std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee));
+
 if (settings->GetDayFeeIsLastDay())
     {
     printfd(__FILE__, "DayResetTraff - 2 -\n");
@@ -695,6 +715,26 @@ std::map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
 return it != ipIndex.end();
 }
 //-----------------------------------------------------------------------------
+bool USERS_IMPL::IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+std::list<USER_IMPL>::const_iterator iter;
+iter = users.begin();
+while (iter != users.end())
+    {
+    if (iter->GetLogin() != login &&
+        !iter->GetProperty().ips.Get().IsAnyIP() &&
+        iter->GetProperty().ips.Get().IsIPInIPS(ip))
+        {
+        if (user != NULL)
+            *user = &(*iter);
+        return true;
+        }
+    ++iter;
+    }
+return false;
+}
+//-----------------------------------------------------------------------------
 void USERS_IMPL::AddNotifierUserAdd(NOTIFIER_BASE<USER_PTR> * n)
 {
 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
index 69f3fbae8d9aca286e1aa9d1ae9f3ac0c9cc04c6..43065bdeb18753f3ab9bbeeb1c68491892cc2b48 100644 (file)
@@ -75,6 +75,7 @@ public:
     virtual ~USERS_IMPL();
 
     int             FindByName(const std::string & login, USER_PTR * user);
+    int             FindByName(const std::string & login, CONST_USER_PTR * user) const;
 
     bool            TariffInUse(const std::string & tariffName) const;
 
@@ -95,7 +96,9 @@ public:
 
     bool            Authorize(const std::string & login, uint32_t ip,
                               uint32_t enabledDirs, const AUTH * auth);
-    bool            Unauthorize(const std::string & login, const AUTH * auth);
+    bool            Unauthorize(const std::string & login,
+                                const AUTH * auth,
+                                const std::string & reason = std::string());
 
     int             ReadUsers();
     size_t          Count() const { return users.size(); }
@@ -103,6 +106,7 @@ public:
     int             FindByIPIdx(uint32_t ip, USER_PTR * user) const;
     int             FindByIPIdx(uint32_t ip, USER_IMPL ** user) const;
     bool            IsIPInIndex(uint32_t ip) const;
+    bool            IsIPInUse(uint32_t ip, const std::string & login, CONST_USER_PTR * user) const;
 
     int             OpenSearch();
     int             SearchNext(int handler, USER_PTR * user);
@@ -121,6 +125,7 @@ private:
     bool            FindByIPIdx(uint32_t ip, user_iter & iter) const;
 
     int             FindByNameNonLock(const std::string & login, user_iter * user);
+    int             FindByNameNonLock(const std::string & login, const_user_iter * user) const;
 
     void            RealDelUser();
     void            ProcessActions();
index 787b813d3728bf975571f4401756ad3863526a8a..7ba78e1d8b311e149ea0b705ee3b0102a3af423f 100644 (file)
@@ -347,6 +347,20 @@ for (size_t i = 0; i < src.length() / 2; i++)
     }
 }
 //---------------------------------------------------------------------------
+std::string Encode12str(const std::string & src)
+{
+std::string res;
+Encode12str(res, src);
+return res;
+}
+//---------------------------------------------------------------------------
+std::string Decode21str(const std::string & src)
+{
+std::string res;
+Decode21str(res, src);
+return res;
+}
+//---------------------------------------------------------------------------
 void Encode12(char * dst, const char * src, size_t srcLen)
 {
 for (size_t i = 0; i <= srcLen; i++)
@@ -790,6 +804,13 @@ const std::string & x2str(uint64_t x, std::string & s)
 return unsigned2str(x, s);
 }
 //---------------------------------------------------------------------------
+const std::string & x2str(double x, std::string & s)
+{
+char buf[256];
+s = snprintf(buf, sizeof(buf), "%f", x);
+return s;
+}
+//---------------------------------------------------------------------------
 std::string & TrimL(std::string & val)
 {
 size_t pos = val.find_first_not_of(" \t");
@@ -819,6 +840,28 @@ std::string & Trim(std::string & val)
 return TrimR(TrimL(val));
 }
 //---------------------------------------------------------------------------
+std::string Trim(const std::string & val)
+{
+std::string res(val);
+return TrimR(TrimL(res));
+}
+//---------------------------------------------------------------------------
+std::string ToLower(const std::string & value)
+{
+    std::string res;
+    for (std::string::size_type pos = 0; pos < value.length(); ++pos)
+        res += tolower(value[pos]);
+    return res;
+}
+//---------------------------------------------------------------------------
+std::string ToUpper(const std::string & value)
+{
+    std::string res;
+    for (std::string::size_type pos = 0; pos < value.length(); ++pos)
+        res += toupper(value[pos]);
+    return res;
+}
+//---------------------------------------------------------------------------
 #ifdef WIN32
 static int is_leap(unsigned y)
 {
index 80d32aba45a45116b523e81a4340e30b16e8c3fa..f2e4e7e2432ab52aa75ed29efbe684726a7fe5ea 100644 (file)
@@ -56,15 +56,16 @@ const char    * IntToKMG(int64_t a, int statType = ST_F);
 const char    * LogDate(time_t t);
 int             ParesTimeStat(const char * str);
 int             IsTimeStat(struct tm * t, int statTime);
-/*bool            IsDigit(char c);
-bool            IsAlpha(char c);*/
-int             strtodouble2(const char * s, double &a);
+int             strtodouble2(const char * str, double & value);
+inline int      strtodouble2(const std::string & str, double & value) { return strtodouble2(str.c_str(), value); }
 int             printfd(const char * __file__, const char * fmt, ...);
 void            Encode12(char * dst, const char * src, size_t srcLen);
 void            Decode21(char * dst, const char * src);
 
 void            Encode12str(std::string & dst, const std::string & src);
 void            Decode21str(std::string & dst, const std::string & src);
+std::string     Encode12str(const std::string & src);
+std::string     Decode21str(const std::string & src);
 
 int             ParseIPString(const char * str, uint32_t * ips, int maxIP);
 void            KOIToWin(const char * s1, char * s2, int l);
@@ -74,7 +75,6 @@ void            WinToKOI(const std::string & s1, std::string * s2);
 int             DaysInMonth(unsigned year, unsigned mon);
 int             DaysInCurrentMonth();
 int             Min8(int a);
-//char          * inet_ntostr(unsigned long);
 std::string     inet_ntostring(uint32_t);
 uint32_t        inet_strington(const std::string & value);
 int             strprintf(std::string * str, const char * fmt, ...);
@@ -95,6 +95,10 @@ void            SwapBytes(int64_t & value);
 std::string &   TrimL(std::string & val);
 std::string &   TrimR(std::string & val);
 std::string &   Trim(std::string & val);
+std::string     Trim(const std::string & val);
+
+std::string     ToLower(const std::string & value);
+std::string     ToUpper(const std::string & value);
 
 std::string     IconvString(const std::string & source, const std::string & from, const std::string & to);
 
@@ -107,12 +111,30 @@ int ParseYesNo(const std::string & str, bool * val);
 
 bool WaitPackets(int sd);
 
+//-----------------------------------------------------------------------------
+int str2x(const std::string & str, int32_t & x);
+int str2x(const std::string & str, uint32_t & x);
+#ifndef WIN32
+int str2x(const std::string & str, int64_t & x);
+int str2x(const std::string & str, uint64_t & x);
+#endif
+//-----------------------------------------------------------------------------
+const std::string & x2str(uint32_t x, std::string & s);
+const std::string & x2str(uint64_t x, std::string & s);
+//-----------------------------------------------------------------------------
+const std::string & x2str(double x, std::string & s);
+//-----------------------------------------------------------------------------
+
 template <typename varT>
 int str2x(const std::string & str, varT & x);
 template <typename varT>
 const std::string & x2str(varT x, std::string & s);
 template <typename varT>
+std::string x2str(varT x) { std::string s; return x2str(x, s); }
+template <typename varT>
 const std::string & unsigned2str(varT x, std::string & s);
+template <typename varT>
+std::string unsigned2str(varT x) { std::string s; return unsigned2str(x, s); }
 
 //-----------------------------------------------------------------------------
 template <typename varT>
@@ -148,7 +170,7 @@ int str2x(const std::string & str, varT & x)
         x += str[i] - '0';
     }
 
-    x*= minus;
+    x *= minus;
 
     return 0;
 }
@@ -236,16 +258,6 @@ const std::string & unsigned2str(varT x, std::string & s)
     return s;
 }
 //-----------------------------------------------------------------------------
-int str2x(const std::string & str, int32_t & x);
-int str2x(const std::string & str, uint32_t & x);
-#ifndef WIN32
-int str2x(const std::string & str, int64_t & x);
-int str2x(const std::string & str, uint64_t & x);
-#endif
-//-----------------------------------------------------------------------------
-const std::string & x2str(uint32_t x, std::string & s);
-const std::string & x2str(uint64_t x, std::string & s);
-//-----------------------------------------------------------------------------
 char * stg_strptime(const char *, const char *, struct tm *);
 time_t stg_timegm(struct tm *);
 
index a8800d7533201b6fe8ac195bd43d7d612544f362..c99833403e23d893ed32c8920ec4d226f6775afb 100644 (file)
 #define MAXKEYBYTES 56          /* 448 bits */
 
 #ifdef __cplusplus
+#include <cstddef> // size_t
 extern "C" {
+#else
+#include <stddef.h> // size_t
 #endif
 
 typedef struct {
index b25f68472235640cbedc72e596cbe4bebb61b789..91608dbbc2b38c8341943635f6e8dc8878967bcf 100644 (file)
@@ -18,7 +18,7 @@
 #include <netinet/ip_icmp.h>
 #endif
 
-#if defined (FREE_BSD) || defined (FREE_BSD5)
+#if defined (FREE_BSD) || defined (FREE_BSD5) || defined(DARWIN)
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
index 41b02a2fdf8927bd57e9a959253af4e56b20f21a..947669c785b433f0bd9874e4010ba98b3e1efecc 100644 (file)
@@ -6,7 +6,7 @@ extern "C" {
 #endif
 
 int ScriptExec(const char * str);
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
 void Executer(int msgID, pid_t pid, char * procName);
 #else
 void Executer(int msgID, pid_t pid);
index bf45105a8332652d31df6b850d9eefc05afe1afd..728082ae350ba079e5404f4b6a3168eb0e805002 100644 (file)
@@ -40,7 +40,7 @@ if (msgsnd(msgid, (void *)&sd, MAX_SCRIPT_LEN, 0) < 0)
 return 0;
 }
 //-----------------------------------------------------------------------------
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
 void Executer(int msgID, pid_t pid, char * procName)
 #else
 void Executer(int msgID, pid_t pid)
@@ -56,7 +56,7 @@ if (pid)
     return;
 nonstop = 1;
 
-#ifdef LINUX
+#if defined(LINUX) || defined(DARWIN)
 memset(procName, 0, strlen(procName));
 strcpy(procName, "stg-exec");
 #else
index e3bfa76219fdab686afac6203e6a76186be74e83..d7bc80c01390fdb372f611ff9a11880b4a9b07a4 100644 (file)
@@ -8,14 +8,28 @@ STGLIBS = -lstgcommon \
           -lstgcrypto
 LIBS = -lexpat
 
-SRCS =         netunit.cpp \
-        parser.cpp \
+SRCS =  parsers/property.cpp \
+        parsers/simple.cpp \
+        parsers/server_info.cpp \
+        parsers/get_admin.cpp \
+        parsers/chg_admin.cpp \
+        parsers/get_tariff.cpp \
+        parsers/chg_tariff.cpp \
+        parsers/auth_by.cpp \
+        parsers/get_user.cpp \
+        parsers/chg_user.cpp \
+        parsers/get_service.cpp \
+        parsers/chg_service.cpp \
+        parsers/get_corp.cpp \
+        parsers/chg_corp.cpp \
+        netunit.cpp \
         servconf.cpp
 
+
 INCS = servconf.h \
        netunit.h
 
 LIB_INCS = -I ../common.lib/include \
-          -I ../crypto.lib/include
+           -I ../crypto.lib/include
 
 include ../Makefile.in
diff --git a/stglibs/srvconf.lib/include/stg/netunit.h b/stglibs/srvconf.lib/include/stg/netunit.h
deleted file mode 100644 (file)
index e288df8..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *    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.6 $
- $Date: 2010/02/11 12:32:53 $
- $Author: faust $
- */
-
-#ifndef NetUnitH
-#define NetUnitH
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <list>
-#include <string>
-
-#include "stg/blowfish.h"
-
-#define  STG_HEADER     "SG04"
-#define  OK_HEADER      "OKHD"
-#define  ERR_HEADER     "ERHD"
-#define  OK_LOGIN       "OKLG"
-#define  ERR_LOGIN      "ERLG"
-#define  OK_LOGINS      "OKLS"
-#define  ERR_LOGINS     "ERLS"
-
-// äÌÉÎÎÁ ÛÉÆÒÕÅÍÏÇÏ É ÐÅÒÅÄÁ×ÁÅÍÏÇ ÚÁ ÏÄÉΠÒÁÚ ÂÌÏËÁ ÉÎÆÏÒÍÁÃÉÉ
-#define  ENC_MSG_LEN    (8)
-
-#define MAX_ERR_STR_LEN (64)
-
-typedef int(*RxCallback_t)(void *, std::list<std::string> *);
-
-enum status
-{
-st_ok = 0,
-st_conn_fail,
-st_send_fail,
-st_recv_fail,
-st_header_err,
-st_login_err,
-st_logins_err,
-st_data_err,
-st_unknown_err,
-st_dns_err,
-st_xml_parse_error,
-st_data_error
-};
-
-enum CONF_STATE
-{
-confHdr = 0,
-confLogin,
-confLoginCipher,
-confData
-};
-//---------------------------------------------------------------------------
-class NETTRANSACT
-{
-public:
-    NETTRANSACT();
-    int     Transact(const char * data);
-    const std::string & GetError() const;
-
-    void    SetRxCallback(void * data, RxCallback_t);
-
-    void    SetServer(const char * serverName);
-    void    SetServerPort(short unsigned p);
-
-    void    SetLogin(const char * l);
-    void    SetPassword(const char * p);
-    ////////////////////////////////////////////
-    int     Connect();
-    int     Disconnect();
-    void    Reset();
-private:
-    int     TxHeader();
-    int     RxHeaderAnswer();
-
-    int     TxLogin();
-    int     RxLoginAnswer();
-
-    int     TxLoginS();
-    int     RxLoginSAnswer();
-
-    int     TxData(const char * text);
-    int     TxData(char * data);
-    int     RxDataAnswer();
-
-    void Encrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
-    void EnDecryptInit(const char * passwd, int passwdLen, BLOWFISH_CTX *ctx);
-    void Decrypt(char * d, const char * s, BLOWFISH_CTX *ctx);
-
-    std::string server;
-    short unsigned  port;
-    std::string login;
-    std::string password;
-    int     outerSocket;
-    std::list<std::string>   answerList;
-    RxCallback_t RxCallBack;
-    void *  dataRxCallBack;
-    std::string errorMsg;
-};
-//---------------------------------------------------------------------------
-#endif
index 67c2f248dbae85c49b08fb1cf7f4eaa0189170e2..2a2dbcaac0a13af69badfc3143eb3fd023c6fbb5 100644 (file)
 
 /*
  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
  */
 
- /*
- $Revision: 1.10 $
- $Date: 2009/03/17 09:52:35 $
- $Author: faust $
- */
-
-#ifndef SERVCONF_H
-#define SERVCONF_H
+#ifndef __STG_STGLIBS_SERVCONF_H__
+#define __STG_STGLIBS_SERVCONF_H__
 
-#include <expat.h>
-
-#include <list>
-#include <string>
+#include "stg/servconf_types.h"
 
+#include "stg/admin_conf.h"
 #include "stg/os_int.h"
-#include "stg/const.h"
-#include "netunit.h"
 
-void Start(void *data, const char *el, const char **attr);
-void End(void *data, const char *el);
+#include <string>
 
-#define MAX_ERR_STR_LEN (64)
-#define IP_STRING_LEN   (255)
-#define UNAME_LEN       (256)
-#define SERV_VER_LEN    (64)
-#define DIRNAME_LEN     (16)
+struct USER_CONF_RES;
+struct USER_STAT_RES;
+struct TARIFF_DATA_RES;
+struct SERVICE_CONF_RES;
+struct CORP_CONF_RES;
 
-//-----------------------------------------------------------------------------
-struct STAT
-{
-    long long   su[DIR_NUM];
-    long long   sd[DIR_NUM];
-    long long   mu[DIR_NUM];
-    long long   md[DIR_NUM];
-    double      freeMb;
-};
-//-----------------------------------------------------------------------------
-struct SERVERINFO
-{
-    std::string version;
-    int         tariffNum;
-    int         tariffType;
-    int         usersNum;
-    std::string uname;
-    int         dirNum;
-    std::string dirName[DIR_NUM];
-};
-//-----------------------------------------------------------------------------
-struct USERDATA
-{
-    std::string     login;
-    std::string     password;
-    double          cash;
-    double          credit;
-    time_t          creditExpire;
-    double          lastCash;
-    double          prepaidTraff;
-    int             down;
-    int             passive;
-    int             disableDetailStat;
-    int             connected;
-    int             alwaysOnline;
-    uint32_t        ip;
-    std::string     ips;
-    std::string     tariff;
-    std::string     iface;
-    std::string     group;
-    std::string     note;
-    std::string     email;
-    std::string     name;
-    std::string     address;
-    std::string     phone;
-    STAT            stat;
-    std::string     userData[USERDATA_NUM];
-
-    struct USERDATA * next;
-};
-//-----------------------------------------------------------------------------
-typedef void(*RecvUserDataCb_t)(USERDATA * ud, void * data);
-typedef void(*RecvServerInfoDataCb_t)(SERVERINFO * si, void * data);
-typedef int(*RecvChgUserCb_t)(const char * asnwer, void * data);
-typedef int(*RecvCheckUserCb_t)(const char * answer, void * data);
-typedef int(*RecvSendMessageCb_t)(const char * answer, void * data);
-//-----------------------------------------------------------------------------
-struct ADMINDATA
-{
-    char login[ADM_LOGIN_LEN];
-};
-//-----------------------------------------------------------------------------
-class PARSER
-{
-public:
-    PARSER() {}
-    virtual ~PARSER() {}
-    virtual int ParseStart(const char *el, const char **attr) = 0;
-    virtual void ParseEnd(const char *el) = 0;
-};
-//-----------------------------------------------------------------------------
-class PARSER_CHG_USER: public PARSER
-{
-public:
-    PARSER_CHG_USER();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseAnswer(const char *el, const char **attr);
-    void SetChgUserRecvCb(RecvChgUserCb_t, void * data);
-private:
-    RecvChgUserCb_t RecvChgUserCb;
-    void * chgUserCbData;
-    int depth;
-    bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_CHECK_USER: public PARSER
-{
-public:
-    PARSER_CHECK_USER();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseAnswer(const char *el, const char **attr);
-    void SetCheckUserRecvCb(RecvCheckUserCb_t, void * data);
-private:
-    RecvCheckUserCb_t RecvCheckUserCb;
-    void * checkUserCbData;
-    int depth;
-    bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_USERS: public PARSER
+namespace STG
 {
-public:
-    PARSER_GET_USERS();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseUsers(const char *el, const char **attr);
-    void ParseUser(const char *el, const char **attr);
-    void ParseUserParams(const char *el, const char **attr);
-    void ParseUserLoadStat(const char * el, const char ** attr);
-    void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
-private:
-    RecvUserDataCb_t RecvUserDataCb;
-    void * userDataCb;
-    USERDATA user;
-    int depth;
-    bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_USER: public PARSER
-{
-public:
-    PARSER_GET_USER();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseUsers(const char *el, const char **attr);
-    void ParseUser(const char *el, const char **attr);
-    void ParseUserParams(const char *el, const char **attr);
-    void ParseUserLoadStat(const char * el, const char ** attr);
-    void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
-private:
-    RecvUserDataCb_t RecvUserDataCb;
-    void * userDataCb;
-    USERDATA user;
-    int depth;
-    bool error;
-};
-//-----------------------------------------------------------------------------
-class PARSER_GET_SERVER_INFO: public PARSER
-{
-public:
-    PARSER_GET_SERVER_INFO();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseServerInfo(const char *el, const char **attr);
-    bool GetError();
-    void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
-private:
-    void ParseUname(const char ** attr);
-    void ParseServerVersion(const char ** attr);
-    void ParseUsersNum(const char ** attr);
-    void ParseTariffsNum(const char ** attr);
-    void ParseTariffType(const char ** attr);
-    void ParseDirNum(const char **attr);
-    void ParseDirName(const char **attr, int d);
 
-    RecvServerInfoDataCb_t RecvServerInfoDataCb;
-    void * serverInfoDataCb;
-    int depth;
-    bool error;
-    SERVERINFO serverInfo;
-};
-//-----------------------------------------------------------------------------
-class PARSER_SEND_MESSAGE: public PARSER
-{
-public:
-    PARSER_SEND_MESSAGE();
-    int  ParseStart(const char *el, const char **attr);
-    void ParseEnd(const char *el);
-    void ParseAnswer(const char *el, const char **attr);
-    void SetSendMessageRecvCb(RecvSendMessageCb_t, void * data);
-private:
-    RecvSendMessageCb_t RecvSendMessageCb;
-    void * sendMessageCbData;
-    int depth;
-    bool error;
-};
-//-----------------------------------------------------------------------------
 class SERVCONF
 {
 public:
-    SERVCONF();
-    void SetServer(const char * server);
-    void SetPort(uint16_t port);
-
-    void SetAdmLogin(const char * login);
-    void SetAdmPassword(const char * password);
-
-    void SetUserDataRecvCb(RecvUserDataCb_t, void * data);
-    void SetServerInfoRecvCb(RecvServerInfoDataCb_t, void * data);
-    void SetChgUserCb(RecvChgUserCb_t, void * data);
-    void SetCheckUserCb(RecvCheckUserCb_t, void * data);
-    void SetGetUserDataRecvCb(RecvUserDataCb_t, void * data);
-    void SetSendMessageCb(RecvSendMessageCb_t, void * data);
-
-    int GetUsers();
-    int GetUser(const char * login);
-    int ChgUser(const char * request);
-    // TODO: Remove this shit!
-    int MsgUser(const char * request);
-    int SendMessage(const char * login, const char * message, int prio);
-    int GetServerInfo();
-    int CheckUser(const char * login, const char * password);
+    SERVCONF(const std::string & server, uint16_t port,
+             const std::string & login, const std::string & password);
+    ~SERVCONF();
+
+    int ServerInfo(SERVER_INFO::CALLBACK f, void * data);
+
+    int RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data);
+
+    int GetAdmins(GET_CONTAINER::CALLBACK<GET_ADMIN::INFO>::TYPE f, void * data);
+    int GetAdmin(const std::string & login, GET_ADMIN::CALLBACK f, void * data);
+    int ChgAdmin(const ADMIN_CONF_RES & conf, SIMPLE::CALLBACK f, void * data);
+    int AddAdmin(const std::string & login,
+                 const ADMIN_CONF_RES & conf,
+                 SIMPLE::CALLBACK f, void * data);
+    int DelAdmin(const std::string & login, SIMPLE::CALLBACK f, void * data);
+
+    int GetTariffs(GET_CONTAINER::CALLBACK<GET_TARIFF::INFO>::TYPE f, void * data);
+    int GetTariff(const std::string & name, GET_TARIFF::CALLBACK f, void * data);
+    int ChgTariff(const TARIFF_DATA_RES & conf, SIMPLE::CALLBACK f, void * data);
+    int AddTariff(const std::string & name,
+                  const TARIFF_DATA_RES & conf,
+                  SIMPLE::CALLBACK f, void * data);
+    int DelTariff(const std::string & name, SIMPLE::CALLBACK f, void * data);
+
+    int GetUsers(GET_CONTAINER::CALLBACK<GET_USER::INFO>::TYPE f, void * data);
+    int GetUser(const std::string & login, GET_USER::CALLBACK f, void * data);
+    int ChgUser(const std::string & login,
+                const USER_CONF_RES & conf,
+                const USER_STAT_RES & stat,
+                SIMPLE::CALLBACK f, void * data);
+    int DelUser(const std::string & login, SIMPLE::CALLBACK f, void * data);
+    int AddUser(const std::string & login, SIMPLE::CALLBACK f, void * data);
+    int AuthBy(const std::string & login, AUTH_BY::CALLBACK f, void * data);
+    int SendMessage(const std::string & login, const std::string & text, SIMPLE::CALLBACK f, void * data);
+    int CheckUser(const std::string & login, const std::string & password, SIMPLE::CALLBACK f, void * data);
+
+    int GetServices(GET_CONTAINER::CALLBACK<GET_SERVICE::INFO>::TYPE f, void * data);
+    int GetService(const std::string & name, GET_SERVICE::CALLBACK f, void * data);
+    int ChgService(const SERVICE_CONF_RES & conf, SIMPLE::CALLBACK f, void * data);
+    int AddService(const std::string & name,
+                   const SERVICE_CONF_RES & conf,
+                   SIMPLE::CALLBACK f, void * data);
+    int DelService(const std::string & name, SIMPLE::CALLBACK f, void * data);
+
+    int GetCorporations(GET_CONTAINER::CALLBACK<GET_CORP::INFO>::TYPE f, void * data);
+    int GetCorp(const std::string & name, GET_CORP::CALLBACK f, void * data);
+    int ChgCorp(const CORP_CONF_RES & conf, SIMPLE::CALLBACK f, void * data);
+    int AddCorp(const std::string & name,
+                const CORP_CONF_RES & conf,
+                SIMPLE::CALLBACK f, void * data);
+    int DelCorp(const std::string & name, SIMPLE::CALLBACK f, void * data);
 
     const std::string & GetStrError() const;
-    int GetError();
-    int Start(const char *el, const char **attr);
-    void End(const char *el);
 
 private:
-    PARSER * currParser;
-
-    PARSER_GET_USERS parserGetUsers;
-    PARSER_GET_USER parserGetUser;
-    PARSER_GET_SERVER_INFO  parserServerInfo;
-    PARSER_CHG_USER parserChgUser;
-    PARSER_CHECK_USER parserCheckUser;
-    PARSER_SEND_MESSAGE parserSendMessage;
-
-    NETTRANSACT nt;
-    int parseDepth;
-
-    std::string errorMsg;
-    int error;
-    XML_Parser parser;
-
-    RecvUserDataCb_t RecvUserDataCb;
-    RecvUserDataCb_t RecvGetUserDataCb;
-    RecvServerInfoDataCb_t RecvServerInfoDataCb;
-    RecvChgUserCb_t RecvChgUserCb;
-    RecvCheckUserCb_t RecvCheckUserCb;
-    RecvSendMessageCb_t RecvSendMessageCb;
-
-    void * getUserDataDataCb;
-    void * getUsersDataDataCb;
-    void * getServerInfoDataCb;
-    void * chgUserDataCb;
-    void * checkUserDataCb;
-    void * sendMessageDataCb;
-
-    friend int AnsRecv(void * data, std::list<std::string> * list);
+    class IMPL;
+    IMPL * pImpl;
 };
-//-----------------------------------------------------------------------------
 
-#endif  /* _SERVCONF_H_ */
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/include/stg/servconf_types.h b/stglibs/srvconf.lib/include/stg/servconf_types.h
new file mode 100644 (file)
index 0000000..f323e99
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_TYPES_H__
+#define __STG_STGLIBS_SRVCONF_TYPES_H__
+
+#include "stg/const.h" // DIR_NUM
+#include "stg/os_int.h" // uint32_t, etc...
+
+#include <string>
+#include <vector>
+#include <ctime>
+
+#define  STG_HEADER     "SG04"
+#define  OK_HEADER      "OKHD"
+#define  ERR_HEADER     "ERHD"
+#define  OK_LOGIN       "OKLG"
+#define  ERR_LOGIN      "ERLG"
+#define  OK_LOGINS      "OKLS"
+#define  ERR_LOGINS     "ERLS"
+
+#define  ENC_MSG_LEN    (8)
+
+struct ADMIN_CONF;
+struct TARIFF_DATA;
+struct SERVICE_CONF;
+struct CORP_CONF;
+
+namespace STG
+{
+
+enum status
+{
+st_ok = 0,
+st_conn_fail,
+st_send_fail,
+st_recv_fail,
+st_header_err,
+st_login_err,
+st_logins_err,
+st_data_err,
+st_unknown_err,
+st_dns_err,
+st_xml_parse_error,
+st_data_error
+};
+
+enum CONF_STATE
+{
+confHdr = 0,
+confLogin,
+confLoginCipher,
+confData
+};
+
+namespace SIMPLE
+{
+
+typedef void (* CALLBACK)(bool result, const std::string & reason, void * data);
+
+} // namespace SIMPLE
+
+namespace GET_CONTAINER
+{
+
+template <typename INFO>
+struct CALLBACK
+{
+typedef void (* TYPE)(bool result, const std::string & reason, const std::vector<INFO> & info, void * data);
+};
+
+}
+
+namespace AUTH_BY
+{
+
+typedef std::vector<std::string> INFO;
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+} // namespace AUTH_BY
+
+namespace SERVER_INFO
+{
+
+struct INFO
+{
+    std::string version;
+    int         tariffNum;
+    int         tariffType;
+    int         usersNum;
+    std::string uname;
+    int         dirNum;
+    std::string dirName[DIR_NUM];
+};
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+} // namespace SERVER_INFO
+
+namespace RAW_XML
+{
+
+typedef void (* CALLBACK)(bool result, const std::string & reason, const std::string & response, void * data);
+
+}
+
+namespace GET_USER
+{
+
+struct STAT
+{
+    long long  su[DIR_NUM];
+    long long  sd[DIR_NUM];
+    long long  mu[DIR_NUM];
+    long long  md[DIR_NUM];
+    double     freeMb;
+};
+
+struct INFO
+{
+    std::string login;
+    std::string password;
+    double      cash;
+    double      credit;
+    time_t      creditExpire;
+    double      lastCash;
+    double      prepaidTraff;
+    int         down;
+    int         passive;
+    int         disableDetailStat;
+    int         connected;
+    int         alwaysOnline;
+    uint32_t    ip;
+    std::string ips;
+    std::string tariff;
+    std::string group;
+    std::string note;
+    std::string email;
+    std::string name;
+    std::string address;
+    std::string phone;
+    STAT        stat;
+    std::string userData[USERDATA_NUM];
+};
+
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+} // namespace GET_USER
+
+namespace GET_ADMIN
+{
+
+typedef ADMIN_CONF INFO;
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+}
+
+namespace GET_TARIFF
+{
+
+typedef TARIFF_DATA INFO;
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+}
+
+namespace GET_SERVICE
+{
+
+typedef SERVICE_CONF INFO;
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+}
+
+namespace GET_CORP
+{
+
+typedef CORP_CONF INFO;
+typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+
+}
+
+} // namespace STG
+
+#endif
index 9a653d5bf5e76621be46b3b6367a1463dccdf771..164823d8395d42d41f81f11a728dfdba5c34c958 100644 (file)
  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
  */
 
- /*
- $Revision: 1.6 $
- $Date: 2009/02/06 10:25:54 $
- $Author: faust $
- */
+#include "netunit.h"
+
+#include "stg/servconf_types.h"
+#include "stg/common.h"
+#include "stg/blowfish.h"
+
+#include <algorithm> // std::min
+
+#include <cstdio>
+#include <cerrno>
+#include <cstring>
 
-//---------------------------------------------------------------------------
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <unistd.h>
 
-#include <cstdio>
-#include <cstring>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 
-#include "stg/netunit.h"
-#include "stg/common.h"
+using namespace STG;
+
+namespace
+{
+
+const std::string::size_type MAX_XML_CHUNK_LENGTH = 2048;
+
+}
 
 //---------------------------------------------------------------------------
 
 #define RECV_HEADER_ANSWER_ERROR    "Recv header answer error!"
 
 //---------------------------------------------------------------------------
-NETTRANSACT::NETTRANSACT()
-    : port(0),
-      outerSocket(-1),
-      RxCallBack(NULL),
-      dataRxCallBack(NULL)
-{
-}
-//-----------------------------------------------------------------------------
-void NETTRANSACT::EnDecryptInit(const char * passwd, int, BLOWFISH_CTX *ctx)
+NETTRANSACT::NETTRANSACT(const std::string & s, uint16_t p,
+                         const std::string & l, const std::string & pwd)
+    : server(s),
+      port(p),
+      login(l),
+      password(pwd),
+      outerSocket(-1)
 {
-unsigned char * keyL = NULL;
-
-keyL = new unsigned char[PASSWD_LEN];
-
-memset(keyL, 0, PASSWD_LEN);
-
-strncpy((char *)keyL, passwd, PASSWD_LEN);
-
-Blowfish_Init(ctx, keyL, PASSWD_LEN);
-
-delete[] keyL;
-}
-//-----------------------------------------------------------------------------
-void NETTRANSACT::Encrypt(char * d, const char * s, BLOWFISH_CTX *ctx)
-{
-EncodeString(d, s, ctx);
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::Decrypt(char * d, const char * s, BLOWFISH_CTX *ctx)
-{
-DecodeString(d, s, ctx);
 }
 //---------------------------------------------------------------------------
 int NETTRANSACT::Connect()
 {
-int ret;
-
 outerSocket = socket(PF_INET, SOCK_STREAM, 0);
 if (outerSocket < 0)
     {
@@ -98,46 +85,42 @@ if (outerSocket < 0)
 struct sockaddr_in outerAddr;
 memset(&outerAddr, 0, sizeof(outerAddr));
 
-struct hostent he;
-struct hostent * phe;
-
-unsigned long ip;
-ip = inet_addr(server.c_str());
+unsigned long ip = inet_addr(server.c_str());
 
 if (ip == INADDR_NONE)
     {
-    phe = gethostbyname(server.c_str());
+    struct hostent * phe = gethostbyname(server.c_str());
     if (phe == NULL)
         {
         errorMsg = "DNS error.\nCan not reslove " + server;
         return st_dns_err;
         }
 
+    struct hostent he;
     memcpy(&he, phe, sizeof(he));
-    ip = *((long*)he.h_addr_list[0]);
+    ip = *((long *)he.h_addr_list[0]);
     }
+
 outerAddr.sin_family = AF_INET;
 outerAddr.sin_port = htons(port);
 outerAddr.sin_addr.s_addr = ip;
 
-ret = connect(outerSocket, (struct sockaddr*)&outerAddr, sizeof(outerAddr));
-
-if (ret < 0)
+if (connect(outerSocket, (struct sockaddr *)&outerAddr, sizeof(outerAddr)) < 0)
     {
     errorMsg = CONNECT_FAILED;
     close(outerSocket);
     return st_conn_fail;
     }
+
 return st_ok;
 }
 //---------------------------------------------------------------------------
-int NETTRANSACT::Disconnect()
+void NETTRANSACT::Disconnect()
 {
 close(outerSocket);
-return 0;
 }
 //---------------------------------------------------------------------------
-int NETTRANSACT::Transact(const char * data)
+int NETTRANSACT::Transact(const std::string & request, CALLBACK callback, void * data)
 {
 int ret;
 if ((ret = TxHeader()) != st_ok)
@@ -176,13 +159,13 @@ if ((ret = RxLoginSAnswer()) != st_ok)
     return ret;
     }
 
-if ((ret = TxData(data)) != st_ok)
+if ((ret = TxData(request)) != st_ok)
     {
     Disconnect();
     return ret;
     }
 
-if ((ret = RxDataAnswer()) != st_ok)
+if ((ret = RxDataAnswer(callback, data)) != st_ok)
     {
     Disconnect();
     return ret;
@@ -193,9 +176,7 @@ return st_ok;
 //---------------------------------------------------------------------------
 int NETTRANSACT::TxHeader()
 {
-int ret;
-ret = send(outerSocket, STG_HEADER, strlen(STG_HEADER), 0);
-if (ret <= 0)
+if (send(outerSocket, STG_HEADER, strlen(STG_HEADER), 0) <= 0)
     {
     errorMsg = SEND_HEADER_ERROR;
     return st_send_fail;
@@ -206,12 +187,11 @@ return st_ok;
 //---------------------------------------------------------------------------
 int NETTRANSACT::RxHeaderAnswer()
 {
-char buffer[sizeof(STG_HEADER)+1];
-int ret;
+char buffer[sizeof(STG_HEADER) + 1];
 
-ret = recv(outerSocket, buffer, strlen(OK_HEADER), 0);
-if (ret <= 0)
+if (recv(outerSocket, buffer, strlen(OK_HEADER), 0) <= 0)
     {
+    printf("Receive header answer error: '%s'\n", strerror(errno));
     errorMsg = RECV_HEADER_ANSWER_ERROR;
     return st_recv_fail;
     }
@@ -238,13 +218,10 @@ else
 int NETTRANSACT::TxLogin()
 {
 char loginZ[ADM_LOGIN_LEN];
-int ret;
-
 memset(loginZ, 0, ADM_LOGIN_LEN);
 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
-ret = send(outerSocket, loginZ, ADM_LOGIN_LEN, 0);
 
-if (ret <= 0)
+if (send(outerSocket, loginZ, ADM_LOGIN_LEN, 0) <= 0)
     {
     errorMsg = SEND_LOGIN_ERROR;
     return st_send_fail;
@@ -255,12 +232,11 @@ return st_ok;
 //---------------------------------------------------------------------------
 int NETTRANSACT::RxLoginAnswer()
 {
-char buffer[sizeof(OK_LOGIN)+1];
-int ret;
+char buffer[sizeof(OK_LOGIN) + 1];
 
-ret = recv(outerSocket, buffer, strlen(OK_LOGIN), 0);
-if (ret <= 0)
+if (recv(outerSocket, buffer, strlen(OK_LOGIN), 0) <= 0)
     {
+    printf("Receive login answer error: '%s'\n", strerror(errno));
     errorMsg = RECV_LOGIN_ANSWER_ERROR;
     return st_recv_fail;
     }
@@ -287,20 +263,17 @@ else
 int NETTRANSACT::TxLoginS()
 {
 char loginZ[ADM_LOGIN_LEN];
-char ct[ENC_MSG_LEN];
-int ret;
-
 memset(loginZ, 0, ADM_LOGIN_LEN);
 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
 
 BLOWFISH_CTX ctx;
-EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
+EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
 for (int j = 0; j < ADM_LOGIN_LEN / ENC_MSG_LEN; j++)
     {
-    Encrypt(ct, loginZ + j*ENC_MSG_LEN, &ctx);
-    ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
-    if (ret <= 0)
+    char ct[ENC_MSG_LEN];
+    EncodeString(ct, loginZ + j * ENC_MSG_LEN, &ctx);
+    if (send(outerSocket, ct, ENC_MSG_LEN, 0) <= 0)
         {
         errorMsg = SEND_LOGIN_ERROR;
         return st_send_fail;
@@ -312,12 +285,11 @@ return st_ok;
 //---------------------------------------------------------------------------
 int NETTRANSACT::RxLoginSAnswer()
 {
-char buffer[sizeof(OK_LOGINS)+1];
-int ret;
+char buffer[sizeof(OK_LOGINS) + 1];
 
-ret = recv(outerSocket, buffer, strlen(OK_LOGINS), 0);
-if (ret <= 0)
+if (recv(outerSocket, buffer, strlen(OK_LOGINS), 0) <= 0)
     {
+    printf("Receive secret login answer error: '%s'\n", strerror(errno));
     errorMsg = RECV_LOGIN_ANSWER_ERROR;
     return st_recv_fail;
     }
@@ -341,152 +313,75 @@ else
     }
 }
 //---------------------------------------------------------------------------
-int NETTRANSACT::TxData(const char * text)
+int NETTRANSACT::TxData(const std::string & text)
 {
-char textZ[ENC_MSG_LEN];
-char ct[ENC_MSG_LEN];
-int ret;
-int j;
-
-int n = strlen(text) / ENC_MSG_LEN;
-int r = strlen(text) % ENC_MSG_LEN;
-
 BLOWFISH_CTX ctx;
-EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
+EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
-for (j = 0; j < n; j++)
+size_t pos = 0;
+while (pos < text.size())
     {
-    strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
-    Encrypt(ct, textZ, &ctx);
-    ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
-    if (ret <= 0)
+    char textZ[ENC_MSG_LEN];
+    if (text.size() - pos < ENC_MSG_LEN)
+        memset(textZ, 0, ENC_MSG_LEN);
+    strncpy(textZ, text.c_str() + pos, std::min(ENC_MSG_LEN, (int)(text.size() - pos)));
+    char ct[ENC_MSG_LEN];
+    EncodeString(ct, textZ, &ctx);
+    if (send(outerSocket, ct, ENC_MSG_LEN, 0) <= 0)
         {
         errorMsg = SEND_DATA_ERROR;
         return st_send_fail;
         }
-    }
-
-memset(textZ, 0, ENC_MSG_LEN);
-if (r)
-    strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
-
-EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
-
-Encrypt(ct, textZ, &ctx);
-ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
-if (ret <= 0)
-    {
-    errorMsg = SEND_DATA_ERROR;
-    return st_send_fail;
+    pos += ENC_MSG_LEN;
     }
 
 return st_ok;
 }
 //---------------------------------------------------------------------------
-int NETTRANSACT::TxData(char * data)
-{
-char buff[ENC_MSG_LEN];
-char buffS[ENC_MSG_LEN];
-char passwd[ADM_PASSWD_LEN];
-
-memset(passwd, 0, ADM_PASSWD_LEN);
-strncpy(passwd, password.c_str(), ADM_PASSWD_LEN);
-memset(buff, 0, ENC_MSG_LEN);
-
-int l = strlen(data)/ENC_MSG_LEN;
-if (strlen(data)%ENC_MSG_LEN)
-    l++;
-
-BLOWFISH_CTX ctx;
-EnDecryptInit(passwd, PASSWD_LEN, &ctx);
-
-for (int j = 0; j < l; j++)
-    {
-    strncpy(buff, &data[j*ENC_MSG_LEN], ENC_MSG_LEN);
-    Encrypt(buffS, buff, &ctx);
-    send(outerSocket, buffS, ENC_MSG_LEN, 0);
-    }
-
-return 0;
-}
-//---------------------------------------------------------------------------
-int NETTRANSACT::RxDataAnswer()
+int NETTRANSACT::RxDataAnswer(CALLBACK callback, void * data)
 {
-int n = 0;
-int ret;
-char bufferS[ENC_MSG_LEN];
-char buffer[ENC_MSG_LEN + 1];
-
 BLOWFISH_CTX ctx;
-EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
+EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
-while (1)
+std::string chunk;
+while (true)
     {
-    ret = recv(outerSocket, &bufferS[n++], 1, 0);
-    if (ret <= 0)
+    char bufferS[ENC_MSG_LEN];
+    size_t toRead = ENC_MSG_LEN;
+    while (toRead > 0)
         {
-        close(outerSocket);
-        errorMsg = RECV_DATA_ANSWER_ERROR;
-        return st_recv_fail;
+        int ret = recv(outerSocket, &bufferS[ENC_MSG_LEN - toRead], toRead, 0);
+        if (ret <= 0)
+            {
+            printf("Receive data error: '%s'\n", strerror(errno));
+            close(outerSocket);
+            errorMsg = RECV_DATA_ANSWER_ERROR;
+            return st_recv_fail;
+            }
+        toRead -= ret;
         }
 
-    if (n == ENC_MSG_LEN)
-        {
-        n = 0;
-        Decrypt(buffer, bufferS, &ctx);
-        buffer[ENC_MSG_LEN] = 0;
+    char buffer[ENC_MSG_LEN];
+    DecodeString(buffer, bufferS, &ctx);
 
-        answerList.push_back(buffer);
+    bool final = false;
+    size_t pos = 0;
+    for (; pos < ENC_MSG_LEN && buffer[pos] != 0; pos++) ;
+    if (pos < ENC_MSG_LEN && buffer[pos] == 0)
+        final = true;
 
-        for (int j = 0; j < ENC_MSG_LEN; j++)
-            {
-            if (buffer[j] == 0)
-                {
-                if (RxCallBack)
-                    if (st_ok != RxCallBack(dataRxCallBack, &answerList))
-                        {
-                        return st_xml_parse_error;
-                        }
-                return st_ok;
-                }
-            }
+    if (pos > 0)
+        chunk.append(&buffer[0], &buffer[pos]);
+
+    if (chunk.length() > MAX_XML_CHUNK_LENGTH || final)
+        {
+        if (callback)
+            if (!callback(chunk, final, data))
+                return st_xml_parse_error;
+        chunk.clear();
         }
+
+    if (final)
+        return st_ok;
     }
 }
-//---------------------------------------------------------------------------
-void NETTRANSACT::SetLogin(const char * l)
-{
-login = l;
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::SetPassword(const char * p)
-{
-password = p;
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::SetServer(const char * serverName)
-{
-server = serverName;
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::SetServerPort(short unsigned p)
-{
-port = p;
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::SetRxCallback(void * data, RxCallback_t cb)
-{
-RxCallBack = cb;
-dataRxCallBack = data;
-}
-//---------------------------------------------------------------------------
-const std::string & NETTRANSACT::GetError() const
-{
-return errorMsg;
-}
-//---------------------------------------------------------------------------
-void NETTRANSACT::Reset()
-{
-answerList.clear();
-}
-//---------------------------------------------------------------------------
diff --git a/stglibs/srvconf.lib/netunit.h b/stglibs/srvconf.lib/netunit.h
new file mode 100644 (file)
index 0000000..f87fb3a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *    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>
+ */
+
+#ifndef NetUnitH
+#define NetUnitH
+
+#include "stg/os_int.h"
+
+#include <string>
+
+class NETTRANSACT
+{
+public:
+    typedef bool (* CALLBACK)(const std::string &, bool, void *);
+
+    NETTRANSACT(const std::string & server, uint16_t port,
+                const std::string & login, const std::string & password);
+    int Transact(const std::string & request, CALLBACK f, void * data);
+    const std::string & GetError() const { return errorMsg; }
+
+    int  Connect();
+    void Disconnect();
+private:
+    int  TxHeader();
+    int  RxHeaderAnswer();
+
+    int  TxLogin();
+    int  RxLoginAnswer();
+
+    int  TxLoginS();
+    int  RxLoginSAnswer();
+
+    int  TxData(const std::string & text);
+    int  RxDataAnswer(CALLBACK f, void * data);
+
+    std::string server;
+    uint16_t  port;
+    std::string login;
+    std::string password;
+    int outerSocket;
+    std::string errorMsg;
+};
+
+#endif
diff --git a/stglibs/srvconf.lib/parser.cpp b/stglibs/srvconf.lib/parser.cpp
deleted file mode 100644 (file)
index a87266e..0000000
+++ /dev/null
@@ -1,955 +0,0 @@
-/*
- *    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.18 $
- $Date: 2010/08/04 00:40:00 $
- $Author: faust $
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string>
-
-#include "stg/common.h"
-#include "stg/const.h"
-#include "stg/servconf.h"
-
-using namespace std;
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_GET_USERS::PARSER_GET_USERS()
-    : RecvUserDataCb(NULL),
-      userDataCb(NULL),
-      user(),
-      depth(0),
-      error(false)
-{
-}
-//-----------------------------------------------------------------------------
-int PARSER_GET_USERS::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    ParseUsers(el, attr);
-    }
-
-if (depth == 2)
-    {
-    ParseUser(el, attr);
-    }
-
-if (depth == 3)
-    {
-    ParseUserParams(el, attr);
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::ParseEnd(const char *)
-{
-depth--;
-if (depth == 1)
-    {
-    if (RecvUserDataCb)
-        {
-        RecvUserDataCb(&user, userDataCb);
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::ParseUsers(const char * el, const char ** attr)
-{
-if (strcasecmp(el, "users") == 0)
-    {
-    if (*attr != NULL)
-        return;
-    return;
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::ParseUser(const char * el, const char ** attr)
-{
-if (el && attr[0])
-    {
-    if (strcasecmp(el, "user") != 0)
-        {
-        return;
-        }
-
-    if (strcasecmp(attr[0], "login") != 0)
-        {
-        return;
-        }
-    user.login = attr[1];
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::ParseUserParams(const char * el, const char ** attr)
-{
-if (strcasecmp(el, "cash") == 0)
-    {
-    if (strtodouble2(attr[1], user.cash) < 0)
-        {
-        return;
-        }
-    }
-
-/*if (strcasecmp(el, "LastCash") == 0)
-    {
-    if (strtodouble2(attr[1], user.lastCash) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }*/
-
-/*if (strcasecmp(el, "LastActivityTime") == 0)
-    {
-    if (strtol(attr[1], user.lastActivityTime) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }*/
-
-
-/*if (strcasecmp(el, "LastTimeCash") == 0)
-    {
-    if (strtol(attr[1], user.lastTimeCash) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }*/
-
-/*if (strcasecmp(el, "CashExpire") == 0)
-    {
-    if (strtol(attr[1], user.cashExpire) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }*/
-
-if (strcasecmp(el, "credit") == 0)
-    {
-    if (strtodouble2(attr[1], user.credit) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "creditExpire") == 0)
-    {
-    if (str2x(attr[1], user.creditExpire) < 0)
-        {
-        return;
-        }
-    }
-
-/*if (strcasecmp(el, "freemb") == 0)
-    {
-    if (strtodouble2(attr[1], user.freeMb) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }*/
-
-if (strcasecmp(el, "down") == 0)
-    {
-    if (str2x(attr[1], user.down) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "passive") == 0)
-    {
-    if (str2x(attr[1], user.passive) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "disableDetailStat") == 0)
-    {
-    if (str2x(attr[1], user.disableDetailStat) < 0)
-        {
-        return;
-        }
-    }
-
-
-if (strcasecmp(el, "status") == 0)
-    {
-    if (str2x(attr[1], user.connected) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "aonline") == 0)
-    {
-    if (str2x(attr[1], user.alwaysOnline) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "currip") == 0)
-    {
-    user.ip = inet_addr(attr[1]);
-    }
-
-if (strcasecmp(el, "ip") == 0)
-    {
-    user.ips = attr[1];
-    }
-
-
-if (strcasecmp(el, "tariff") == 0)
-    {
-    //KOIToWin(user.tariff, *(attr+1), TARIFF_LEN);
-    user.tariff = attr[1];
-    return;
-    }
-
-if (strcasecmp(el, "password") == 0)
-    {
-    user.password = *(attr+1);
-    return;
-    }
-
-if (strcasecmp(el, "iface") == 0)
-    {
-    user.iface = attr[1];
-    return;
-    }
-
-/*if (strcasecmp(el, "name") == 0)
-    {
-    / *char nameEnc[REALNM_LEN * 2 + 1];
-    char name[REALNM_LEN];
-    strncpy(nameEnc, attr[1], REALNM_LEN * 2 + 1);
-    Decode21(name, nameEnc);
-    KOIToWin(user.realName, name, REALNM_LEN);* /
-    Decode21str(user.realName, attr[1]);
-    return;
-    }*/
-
-if (strcasecmp(el, "address") == 0)
-    {
-    /*char addressEnc[ADDR_LEN * 2 + 1];
-    char address[ADDR_LEN];
-    strncpy(addressEnc, attr[1], ADDR_LEN * 2 + 1);
-    Decode21(address, addressEnc);
-    KOIToWin(user.address, address, ADDR_LEN);*/
-    Decode21str(user.address, attr[1]);
-    return;
-    }
-
-if (strcasecmp(el, "phone") == 0)
-    {
-    /*char phoneEnc[PHONE_LEN * 2 + 1];
-    char phone[PHONE_LEN];
-    strncpy(phoneEnc, attr[1], PHONE_LEN * 2 + 1);
-    Decode21(phone, phoneEnc);
-    KOIToWin(user.phone, phone, PHONE_LEN);*/
-    Decode21str(user.phone, attr[1]);
-    return;
-    }
-
-if (strcasecmp(el, "note") == 0)
-    {
-    /*char noteEnc[NOTE_LEN * 2 + 1];
-    char note[NOTE_LEN];
-    strncpy(noteEnc, attr[1], NOTE_LEN * 2 + 1);*/
-    //KOIToWin(user.note, note, NOTE_LEN);
-    //user.note = note;
-    Decode21str(user.note, attr[1]);
-    return;
-    }
-
-if (strcasecmp(el, "email") == 0)
-    {
-    /*char emailEnc[EMAIL_LEN * 2 + 1];
-    char email[EMAIL_LEN];
-    strncpy(emailEnc, attr[1], EMAIL_LEN * 2 + 1);
-    Decode21(email, emailEnc);
-    //KOIToWin(user.email, email, EMAIL_LEN);
-    user.email = email;*/
-    Decode21str(user.email, attr[1]);
-    return;
-    }
-
-if (strcasecmp(el, "group") == 0)
-    {
-    /*char groupEnc[GROUP_LEN * 2 + 1];
-    char group[GROUP_LEN];
-    strncpy(groupEnc, attr[1], GROUP_LEN * 2 + 1);
-    Decode21(group, groupEnc);
-    //KOIToWin(user.group, group, GROUP_LEN);
-    user.group = group;*/
-    Decode21str(user.group, attr[1]);
-    return;
-    }
-
-if (strcasecmp(el, "traff") == 0)
-    {
-    ParseUserLoadStat(el, attr);
-    return;
-    }
-
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::ParseUserLoadStat(const char *, const char ** attr)
-{
-int i = 0;
-char dir[6];
-while (attr[i])
-    {
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "MU%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.mu[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "MD%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.md[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "SU%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.su[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "SD%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.sd[j]);
-            break;
-            }
-        }
-    i+=2;
-    }
-return;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USERS::SetUserDataRecvCb(RecvUserDataCb_t f, void * data)
-{
-RecvUserDataCb = f;
-userDataCb = data;
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_GET_USER::PARSER_GET_USER()
-    : RecvUserDataCb(NULL),
-      userDataCb(NULL),
-      user(),
-      depth(0),
-      error(false)
-{
-}
-//-----------------------------------------------------------------------------
-int PARSER_GET_USER::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    ParseUser(el, attr);
-    }
-
-if (depth == 2)
-    {
-    ParseUserParams(el, attr);
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USER::ParseEnd(const char *)
-{
-depth--;
-if (depth == 0)
-    {
-    if (RecvUserDataCb)
-        {
-        RecvUserDataCb(&user, userDataCb);
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USER::ParseUser(const char * el, const char ** attr)
-{
-if (strcasecmp(el, "user") == 0)
-    {
-    if (strcasecmp(attr[1], "error") == 0)
-        user.login = "";
-    return;
-    }
-}
-//-----------------------------------------------------------------------------
-struct ParsedStringParams
-{
-string    * param;
-string      paramName;
-};
-//-----------------------------------------------------------------------------
-struct ParsedDoubleParams
-{
-double    * param;
-string      paramName;
-};
-//-----------------------------------------------------------------------------
-void PARSER_GET_USER::ParseUserParams(const char * el, const char ** attr)
-{
-//printf("PARSER_GET_USER::ParseUserParams el=%s attr[1]=%s\n", el, attr[1]);
-
-if (strcasecmp(el, "login") == 0)
-    {
-    user.login = attr[1];
-    }
-
-
-/*if (strcasecmp(el, "LastActivityTime") == 0)
-    {
-    if (strtol(attr[1], user.lastActivityTime) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }
-
-
-if (strcasecmp(el, "LastTimeCash") == 0)
-    {
-    if (strtol(attr[1], user.lastTimeCash) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }
-
-if (strcasecmp(el, "CashExpire") == 0)
-    {
-    if (strtol(attr[1], user.cashExpire) < 0)
-        {
-        MessageDlg("Error in answer", mtError, TMsgDlgButtons() << mbOK, 0);
-        return 0;
-        }
-    }
-*/
-
-if (strcasecmp(el, "down") == 0)
-    {
-    if (str2x(attr[1], user.down) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "passive") == 0)
-    {
-    if (str2x(attr[1], user.passive) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "disableDetailStat") == 0)
-    {
-    if (str2x(attr[1], user.disableDetailStat) < 0)
-        {
-        return;
-        }
-    }
-
-
-if (strcasecmp(el, "status") == 0)
-    {
-    if (str2x(attr[1], user.connected) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "aonline") == 0)
-    {
-    if (str2x(attr[1], user.alwaysOnline) < 0)
-        {
-        return;
-        }
-    }
-
-if (strcasecmp(el, "currip") == 0)
-    {
-    user.ip = inet_addr(attr[1]);
-    }
-
-if (strcasecmp(el, "creditExpire") == 0)
-    {
-    if (str2x(attr[1], user.creditExpire) < 0)
-        {
-        return;
-        }
-    }
-
-for (int i = 0; i < USERDATA_NUM; i++)
-    {
-    string num;
-    x2str(i, num);
-    string udName = "UserData" + num;
-    if (strcasecmp(el, udName.c_str()) == 0)
-        {
-        Decode21str(user.userData[i], attr[1]);
-        return;
-        }
-    }
-
-ParsedStringParams psp[] =
-{
-    {&user.ips,         "ip"},
-    {&user.tariff,      "tariff"},
-    {&user.password,    "password"},
-    {&user.iface,       "iface"},
-};
-
-for (unsigned i = 0; i < sizeof(psp)/sizeof(ParsedStringParams); i++)
-    {
-    if (strcasecmp(el, psp[i].paramName.c_str()) == 0)
-        {
-        *psp[i].param = attr[1];
-        return;
-        }
-    }
-
-ParsedStringParams pspEnc[] =
-{
-    {&user.note,    "note"},
-    {&user.email,   "email"},
-    {&user.group,   "group"},
-    {&user.name,    "name"},
-    {&user.address, "address"},
-    {&user.phone,   "phone"}
-};
-
-for (unsigned i = 0; i < sizeof(pspEnc)/sizeof(ParsedStringParams); i++)
-    {
-    if (strcasecmp(el, pspEnc[i].paramName.c_str()) == 0)
-        {
-        Decode21str(*pspEnc[i].param, attr[1]);
-        return;
-        }
-    }
-
-ParsedDoubleParams pdp[] =
-{
-    {&user.cash,            "cash"},
-    {&user.credit,          "credit"},
-    {&user.lastCash,        "lastCash"},
-    {&user.prepaidTraff,    "freemb"},
-};
-
-for (unsigned i = 0; i < sizeof(pdp)/sizeof(ParsedDoubleParams); i++)
-    {
-    if (strcasecmp(el, pdp[i].paramName.c_str()) == 0)
-        {
-        strtodouble2(attr[1], *pdp[i].param);
-        return;
-        }
-    }
-
-if (strcasecmp(el, "traff") == 0)
-    {
-    ParseUserLoadStat(el, attr);
-    return;
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USER::ParseUserLoadStat(const char *, const char ** attr)
-{
-int i = 0;
-char dir[6];
-while (attr[i])
-    {
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "MU%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.mu[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "MD%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.md[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "SU%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.su[j]);
-            break;
-            }
-        }
-    for (int j = 0; j < DIR_NUM; j++)
-        {
-        sprintf(dir, "SD%d", j);
-        if (strcasecmp(dir, attr[i]) == 0)
-            {
-            str2x(attr[i+1], user.stat.sd[j]);
-            break;
-            }
-        }
-    i+=2;
-    }
-return;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_USER::SetUserDataRecvCb(RecvUserDataCb_t f, void * data)
-{
-RecvUserDataCb = f;
-userDataCb = data;
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_GET_SERVER_INFO::PARSER_GET_SERVER_INFO()
-    : RecvServerInfoDataCb(NULL),
-      serverInfoDataCb(NULL),
-      depth(0),
-      error(false),
-      serverInfo()
-{
-}
-//-----------------------------------------------------------------------------
-int PARSER_GET_SERVER_INFO::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    if (strcasecmp(el, "ServerInfo") != 0)
-        {
-        //printf("%s\n", el);
-        }
-    }
-else
-    {
-    if (depth == 2)
-        {
-        if (strcasecmp(el, "uname") == 0)
-            {
-            ParseUname(attr);
-            return 0;
-            }
-        if (strcasecmp(el, "version") == 0)
-            {
-            ParseServerVersion(attr);
-            return 0;
-            }
-        if (strcasecmp(el, "tariff") == 0)
-            {
-            ParseTariffType(attr);
-            return 0;
-            }
-        if (strcasecmp(el, "dir_num") == 0)
-            {
-            ParseDirNum(attr);
-            return 0;
-            }
-        if (strcasecmp(el, "users_num") == 0)
-            {
-            ParseUsersNum(attr);
-            return 0;
-            }
-        if (strcasecmp(el, "tariff_num") == 0)
-            {
-            ParseTariffsNum(attr);
-            return 0;
-            }
-
-        for (int j = 0; j < DIR_NUM; j++)
-            {
-            char str[16];
-            sprintf(str, "dir_name_%d", j);
-            if (strcasecmp(el, str) == 0)
-                {
-                ParseDirName(attr, j);
-                }
-            }
-
-        }
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseEnd(const char *)
-{
-depth--;
-if (depth == 0)
-    {
-    RecvServerInfoDataCb(&serverInfo, serverInfoDataCb);
-    }
-}
-//-----------------------------------------------------------------------------
-/*void PARSER_GET_SERVER_INFO::ParseServerInfo(const char * el, const char ** attr)
-    {
-    }*/
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::SetServerInfoRecvCb(RecvServerInfoDataCb_t f, void * data)
-{
-RecvServerInfoDataCb = f;
-serverInfoDataCb = data;
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseUname(const char ** attr)
-{
-if (strcmp(*attr, "value") == 0)
-    serverInfo.uname = attr[1];
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseServerVersion(const char ** attr)
-{
-if (strcmp(*attr, "value") == 0)
-    serverInfo.version = attr[1];
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseUsersNum(const char ** attr)
-{
-if (strcmp(*attr, "value") == 0)
-    {
-    if (str2x(attr[1], serverInfo.usersNum) < 0)
-        {
-        serverInfo.usersNum = -1;
-        return;
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseTariffsNum(const char ** attr)
-{
-if (strcmp(*attr, "value") == 0)
-    {
-    if (str2x(attr[1], serverInfo.tariffNum) < 0)
-        {
-        serverInfo.tariffNum = -1;
-        return;
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseTariffType(const char ** attr)
-{
-if (strcmp(*attr, "value") == 0)
-    {
-    if (str2x(attr[1], serverInfo.tariffType) < 0)
-        {
-        serverInfo.tariffType = -1;
-        return;
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseDirNum(const char **attr)
-{
-if (strcasecmp(*attr, "value") == 0)
-    {
-    if (str2x(attr[1], serverInfo.dirNum) < 0)
-        {
-        serverInfo.dirNum = -1;
-        return;
-        }
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_GET_SERVER_INFO::ParseDirName(const char **attr, int d)
-{
-if (strcmp(attr[0], "value") == 0)
-    {
-    char str[2*DIRNAME_LEN + 1];
-    Decode21(str, attr[1]);
-    serverInfo.dirName[d] = str;
-    }
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_CHG_USER::PARSER_CHG_USER()
-    : RecvChgUserCb(NULL),
-      chgUserCbData(NULL),
-      depth(0),
-      error(false)
-{
-}
-//-----------------------------------------------------------------------------
-int PARSER_CHG_USER::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    if (strcasecmp(el, "SetUser") == 0)
-        {
-        ParseAnswer(el, attr);
-        }
-    else if (strcasecmp(el, "DelUser") == 0)
-        {
-        ParseAnswer(el, attr);
-        }
-    else if (strcasecmp(el, "AddUser") == 0)
-        {
-        ParseAnswer(el, attr);
-        }
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHG_USER::ParseEnd(const char *)
-{
-depth--;
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHG_USER::ParseAnswer(const char *, const char **attr)
-{
-if (RecvChgUserCb)
-    {
-    RecvChgUserCb(attr[1], chgUserCbData);
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHG_USER::SetChgUserRecvCb(RecvChgUserCb_t f, void * data)
-{
-RecvChgUserCb = f;
-chgUserCbData = data;
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_CHECK_USER::PARSER_CHECK_USER()
-    : RecvCheckUserCb(NULL),
-      checkUserCbData(NULL),
-      depth(0),
-      error(false)
-{
-}
-//-----------------------------------------------------------------------------
-int PARSER_CHECK_USER::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    if (strcasecmp(el, "CheckUser") == 0)
-        {
-        //printf("el=%s attr[0]=%s attr[1]=%s\n", el, attr[0], attr[1]);
-        ParseAnswer(el, attr);
-        }
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHECK_USER::ParseEnd(const char *)
-{
-depth--;
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHECK_USER::ParseAnswer(const char *, const char **attr)
-{
-if (RecvCheckUserCb)
-    {
-    RecvCheckUserCb(attr[1], checkUserCbData);
-    }
-}
-//-----------------------------------------------------------------------------
-void PARSER_CHECK_USER::SetCheckUserRecvCb(RecvCheckUserCb_t f, void * data)
-{
-RecvCheckUserCb = f;
-checkUserCbData = data;
-}
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-PARSER_SEND_MESSAGE::PARSER_SEND_MESSAGE()
-    : RecvSendMessageCb(NULL),
-      sendMessageCbData(NULL),
-      depth(0),
-      error(false)
-{
-}
-//-----------------------------------------------------------------------------
-int  PARSER_SEND_MESSAGE::ParseStart(const char *el, const char **attr)
-{
-depth++;
-if (depth == 1)
-    {
-    if (strcasecmp(el, "SendMessageResult") == 0)
-        {
-        ParseAnswer(el, attr);
-        }
-    }
-return 0;
-}
-//-----------------------------------------------------------------------------
-void PARSER_SEND_MESSAGE::ParseEnd(const char *)
-{
-depth--;
-}
-//-----------------------------------------------------------------------------
-void PARSER_SEND_MESSAGE::ParseAnswer(const char *, const char **attr)
-{
-if (RecvSendMessageCb)
-    RecvSendMessageCb(attr[1], sendMessageCbData);
-}
-//-----------------------------------------------------------------------------
-void PARSER_SEND_MESSAGE::SetSendMessageRecvCb(RecvSendMessageCb_t f, void * data)
-{
-RecvSendMessageCb = f;
-sendMessageCbData = data;
-}
-//-----------------------------------------------------------------------------
diff --git a/stglibs/srvconf.lib/parsers/auth_by.cpp b/stglibs/srvconf.lib/parsers/auth_by.cpp
new file mode 100644 (file)
index 0000000..61f590b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *    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 "auth_by.h"
+
+#include <strings.h> // strcasecmp
+
+using namespace STG;
+
+AUTH_BY::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+}
+//-----------------------------------------------------------------------------
+int AUTH_BY::PARSER::ParseStart(const char *el, const char **attr)
+{
+depth++;
+if (depth == 1)
+    {
+    if (strcasecmp(el, "AuthorizedBy") == 0)
+        if (attr && attr[0] && attr[1])
+            {
+            if (strcasecmp(attr[1], "error") == 0)
+                {
+                if (attr[2] && attr[3])
+                    error = attr[3];
+                else
+                    error = "User not found.";
+                }
+            else
+                parsingAnswer = true;
+            }
+    }
+else
+    {
+    if (depth == 2)
+        {
+        if (parsingAnswer && strcasecmp(el, "Auth") == 0)
+            {
+            if (attr && attr[0] && attr[1] && strcasecmp(attr[0], "name") == 0)
+                info.push_back(attr[1]);
+            return 0;
+            }
+        }
+    }
+return 0;
+}
+//-----------------------------------------------------------------------------
+void AUTH_BY::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    info.clear();
+    error.clear();
+    }
+}
diff --git a/stglibs/srvconf.lib/parsers/auth_by.h b/stglibs/srvconf.lib/parsers/auth_by.h
new file mode 100644 (file)
index 0000000..f285d2b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_AUTH_BY_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_AUTH_BY_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace AUTH_BY
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    PARSER(CALLBACK f, void * data);
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    CALLBACK callback;
+    void * data;
+    int depth;
+    bool parsingAnswer;
+    INFO info;
+    std::string error;
+};
+
+} // namespace AUTH_BY
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/base.h b/stglibs/srvconf.lib/parsers/base.h
new file mode 100644 (file)
index 0000000..8d695a3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_SRVCONF_PARSER_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_H__
+
+namespace STG
+{
+
+class PARSER
+{
+public:
+    virtual ~PARSER() {}
+    virtual int ParseStart(const char *el, const char **attr) = 0;
+    virtual void ParseEnd(const char *el) = 0;
+};
+
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/chg_admin.cpp b/stglibs/srvconf.lib/parsers/chg_admin.cpp
new file mode 100644 (file)
index 0000000..a4265ef
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *    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 "chg_admin.h"
+
+#include "stg/admin_conf.h"
+#include "stg/common.h"
+
+#include <strings.h>
+
+using namespace STG;
+
+std::string CHG_ADMIN::Serialize(const ADMIN_CONF_RES & conf)
+{
+std::string params;
+if (!conf.login.empty())
+    params += " login=\"" + conf.login.data() + "\"";
+if (!conf.password.empty())
+    params += " password=\"" + conf.password.data() + "\"";
+if (!conf.priv.empty())
+    params += " priv=\"" + unsigned2str(conf.priv.data().ToInt()) + "\"";
+return params;
+}
diff --git a/stglibs/srvconf.lib/parsers/chg_admin.h b/stglibs/srvconf.lib/parsers/chg_admin.h
new file mode 100644 (file)
index 0000000..c10332c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_CHG_ADMIN_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_CHG_ADMIN_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+struct ADMIN_CONF_RES;
+
+namespace STG
+{
+namespace CHG_ADMIN
+{
+
+std::string Serialize(const ADMIN_CONF_RES & conf);
+
+} // namespace CHG_ADMIN
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/chg_corp.cpp b/stglibs/srvconf.lib/parsers/chg_corp.cpp
new file mode 100644 (file)
index 0000000..dc88422
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *    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 "chg_corp.h"
+
+#include "resetable_utils.h"
+
+#include "stg/corp_conf.h"
+#include "stg/common.h"
+
+#include <sstream>
+
+using namespace STG;
+
+std::string CHG_CORP::Serialize(const CORP_CONF_RES & conf)
+{
+std::ostringstream stream;
+
+appendResetable(stream, "name", conf.name);
+appendResetable(stream, "cash", conf.cash);
+
+return stream.str();
+}
diff --git a/stglibs/srvconf.lib/parsers/chg_corp.h b/stglibs/srvconf.lib/parsers/chg_corp.h
new file mode 100644 (file)
index 0000000..8b75fbd
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_CHG_CORP_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_CHG_CORP_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+struct CORP_CONF_RES;
+
+namespace STG
+{
+namespace CHG_CORP
+{
+
+std::string Serialize(const CORP_CONF_RES & conf);
+
+} // namespace CHG_CORP
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/chg_service.cpp b/stglibs/srvconf.lib/parsers/chg_service.cpp
new file mode 100644 (file)
index 0000000..f862761
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *    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 "chg_service.h"
+
+#include "resetable_utils.h"
+
+#include "stg/service_conf.h"
+#include "stg/common.h"
+
+#include <sstream>
+
+using namespace STG;
+
+std::string CHG_SERVICE::Serialize(const SERVICE_CONF_RES & conf)
+{
+std::ostringstream stream;
+
+appendResetable(stream, "name", conf.name);
+appendResetable(stream, "comment", conf.comment);
+appendResetable(stream, "cost", conf.cost);
+appendResetable(stream, "payDay", conf.payDay);
+
+return stream.str();
+}
diff --git a/stglibs/srvconf.lib/parsers/chg_service.h b/stglibs/srvconf.lib/parsers/chg_service.h
new file mode 100644 (file)
index 0000000..10fbf6f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_CHG_SERVICE_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_CHG_SERVICE_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+struct SERVICE_CONF_RES;
+
+namespace STG
+{
+namespace CHG_SERVICE
+{
+
+std::string Serialize(const SERVICE_CONF_RES & conf);
+
+} // namespace CHG_SERVICE
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/chg_tariff.cpp b/stglibs/srvconf.lib/parsers/chg_tariff.cpp
new file mode 100644 (file)
index 0000000..cb7d947
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *    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 "chg_tariff.h"
+
+#include "resetable_utils.h"
+
+#include "stg/tariff_conf.h"
+#include "stg/common.h"
+
+#include <sstream>
+
+#include <strings.h>
+
+using namespace STG;
+
+namespace
+{
+
+template <typename A, typename T>
+void appendSlashedResetable(std::ostream & stream, const std::string & name, const A & array, T A::value_type:: * field)
+{
+std::string res;
+for (typename A::size_type i = 0; i < array.size(); ++i)
+    {
+    if ((array[i].*field).empty()) // All values must be set
+        return;
+    if (!res.empty())
+        res += "/";
+    res += x2str((array[i].*field).data());
+    }
+stream << "<" << name << " value=\"" << res << "\"/>";
+}
+
+} // namespace anonymous
+
+std::string CHG_TARIFF::Serialize(const TARIFF_DATA_RES & data)
+{
+std::ostringstream stream;
+
+appendResetable(stream, "fee", data.tariffConf.fee);
+appendResetable(stream, "passiveCost", data.tariffConf.passiveCost);
+appendResetable(stream, "free", data.tariffConf.free);
+
+if (!data.tariffConf.traffType.empty())
+    switch (data.tariffConf.traffType.data())
+        {
+        case TRAFF_UP: stream << "<traffType value=\"up\"/>"; break;
+        case TRAFF_DOWN: stream << "<traffType value=\"down\"/>"; break;
+        case TRAFF_UP_DOWN: stream << "<traffType value=\"up+down\"/>"; break;
+        case TRAFF_MAX: stream << "<traffType value=\"max\"/>"; break;
+        }
+
+for (size_t i = 0; i < DIR_NUM; ++i)
+    if (!data.dirPrice[i].hDay.empty() &&
+        !data.dirPrice[i].mDay.empty() &&
+        !data.dirPrice[i].hNight.empty() &&
+        !data.dirPrice[i].mNight.empty())
+        stream << "<time" << i << " value=\"" << data.dirPrice[i].hDay.data() << ":"
+                                              << data.dirPrice[i].mDay.data() << "-"
+                                              << data.dirPrice[i].hNight.data() << ":"
+                                              << data.dirPrice[i].mNight.data() << "\"/>";
+
+appendSlashedResetable(stream, "priceDayA", data.dirPrice, &DIRPRICE_DATA_RES::priceDayA);
+appendSlashedResetable(stream, "priceDayB", data.dirPrice, &DIRPRICE_DATA_RES::priceDayB);
+appendSlashedResetable(stream, "priceNightA", data.dirPrice, &DIRPRICE_DATA_RES::priceNightA);
+appendSlashedResetable(stream, "priceNightB", data.dirPrice, &DIRPRICE_DATA_RES::priceNightB);
+appendSlashedResetable(stream, "singlePrice", data.dirPrice, &DIRPRICE_DATA_RES::singlePrice);
+appendSlashedResetable(stream, "noDiscount", data.dirPrice, &DIRPRICE_DATA_RES::noDiscount);
+appendSlashedResetable(stream, "threshold", data.dirPrice, &DIRPRICE_DATA_RES::threshold);
+
+return stream.str();
+}
diff --git a/stglibs/srvconf.lib/parsers/chg_tariff.h b/stglibs/srvconf.lib/parsers/chg_tariff.h
new file mode 100644 (file)
index 0000000..c5cc0f0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_CHG_TARIFF_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_CHG_TARIFF_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+struct TARIFF_DATA_RES;
+
+namespace STG
+{
+namespace CHG_TARIFF
+{
+
+std::string Serialize(const TARIFF_DATA_RES & data);
+
+} // namespace CHG_TARIFF
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/chg_user.cpp b/stglibs/srvconf.lib/parsers/chg_user.cpp
new file mode 100644 (file)
index 0000000..ed2002b
--- /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 : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "chg_user.h"
+
+#include "resetable_utils.h"
+
+#include "stg/user_conf.h"
+#include "stg/user_stat.h"
+
+#include <sstream>
+
+#include <strings.h>
+
+using namespace STG;
+
+CHG_USER::PARSER::PARSER(SIMPLE::CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0)
+{
+}
+//-----------------------------------------------------------------------------
+int CHG_USER::PARSER::ParseStart(const char *el, const char **attr)
+{
+depth++;
+if (depth == 1)
+    {
+    if (strcasecmp(el, "SetUser") == 0)
+        ParseAnswer(el, attr);
+    else if (strcasecmp(el, "DelUser") == 0)
+        ParseAnswer(el, attr);
+    else if (strcasecmp(el, "AddUser") == 0)
+        ParseAnswer(el, attr);
+    }
+return 0;
+}
+//-----------------------------------------------------------------------------
+void CHG_USER::PARSER::ParseEnd(const char *)
+{
+depth--;
+}
+//-----------------------------------------------------------------------------
+void CHG_USER::PARSER::ParseAnswer(const char * /*el*/, const char ** attr)
+{
+if (!callback)
+    return;
+if (attr && attr[0] && attr[1])
+    callback(strcasecmp(attr[1], "ok") == 0, attr[2] && attr[3] ? attr[3] : "", data);
+else
+    callback(false, "Invalid response.", data);
+}
+
+std::string CHG_USER::Serialize(const USER_CONF_RES & conf, const USER_STAT_RES & stat)
+{
+std::ostringstream stream;
+
+// Conf
+
+appendResetable(stream, "credit", conf.credit);
+appendResetable(stream, "creditExpire", conf.creditExpire);
+appendResetable(stream, "password", conf.password);
+appendResetable(stream, "down", conf.disabled); // TODO: down -> disabled
+appendResetable(stream, "passive", conf.passive);
+appendResetable(stream, "disableDetailStat", conf.disabledDetailStat); // TODO: disable -> disabled
+appendResetable(stream, "aonline", conf.alwaysOnline); // TODO: aonline -> alwaysOnline
+appendResetable(stream, "ip", conf.ips); // TODO: ip -> ips
+
+if (!conf.nextTariff.empty())
+    stream << "<tariff delayed=\"" << conf.nextTariff.data() << "\"/>";
+else if (!conf.tariffName.empty())
+    stream << "<tariff now=\"" << conf.nextTariff.data() << "\"/>";
+
+appendResetable(stream, "note", conf.note);
+appendResetable(stream, "name", conf.realName); // TODO: name -> realName
+appendResetable(stream, "address", conf.address);
+appendResetable(stream, "email", conf.email);
+appendResetable(stream, "phone", conf.phone);
+appendResetable(stream, "group", conf.group);
+
+for (size_t i = 0; i < conf.userdata.size(); ++i)
+    appendResetable(stream, "userdata", i, conf.userdata[i]);
+
+// Stat
+
+if (!stat.cashAdd.empty())
+    stream << "<cash add=\"" << stat.cashAdd.data().first << "\" msg=\"" << stat.cashAdd.data().second << "\"/>";
+else if (!stat.cashSet.empty())
+    stream << "<cash set=\"" << stat.cashAdd.data().first << "\" msg=\"" << stat.cashAdd.data().second << "\"/>";
+
+appendResetable(stream, "freeMb", stat.freeMb);
+
+std::ostringstream traff;
+for (size_t i = 0; i < stat.sessionUp.size(); ++i)
+    if (!stat.sessionUp[i].empty())
+        traff << " SU" << i << "=\"" << stat.sessionUp[i].data() << "\"";
+for (size_t i = 0; i < stat.sessionDown.size(); ++i)
+    if (!stat.sessionDown[i].empty())
+        traff << " SD" << i << "=\"" << stat.sessionDown[i].data() << "\"";
+for (size_t i = 0; i < stat.monthUp.size(); ++i)
+    if (!stat.monthUp[i].empty())
+        traff << " MU" << i << "=\"" << stat.monthUp[i].data() << "\"";
+for (size_t i = 0; i < stat.monthDown.size(); ++i)
+    if (!stat.monthDown[i].empty())
+        traff << " MD" << i << "=\"" << stat.monthDown[i].data() << "\"";
+
+std::string traffData = traff.str();
+if (!traffData.empty())
+    stream << "<traff" << traffData << "/>";
+
+return stream.str();
+}
diff --git a/stglibs/srvconf.lib/parsers/chg_user.h b/stglibs/srvconf.lib/parsers/chg_user.h
new file mode 100644 (file)
index 0000000..9f8e6b0
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_SRVCONF_PARSER_CHG_USER_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_CHG_USER_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+struct USER_CONF_RES;
+struct USER_STAT_RES;
+
+namespace STG
+{
+namespace CHG_USER
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    PARSER(SIMPLE::CALLBACK f, void * data);
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    SIMPLE::CALLBACK callback;
+    void * data;
+    int depth;
+
+    void ParseAnswer(const char * el, const char ** attr);
+};
+
+std::string Serialize(const USER_CONF_RES & conf, const USER_STAT_RES & stat);
+
+} // namespace CHG_USER
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_admin.cpp b/stglibs/srvconf.lib/parsers/get_admin.cpp
new file mode 100644 (file)
index 0000000..41217df
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *    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 "get_admin.h"
+
+#include "stg/common.h"
+
+#include <map>
+#include <utility>
+
+#include <strings.h>
+
+using namespace STG;
+
+namespace STG
+{
+
+template <>
+inline
+bool GetValue<PRIV>(const char ** attr, PRIV & value)
+{
+uint32_t priv;
+if (!GetValue(attr, priv))
+    return false;
+value = priv;
+return true;
+}
+
+} // namespace STG
+
+GET_ADMIN::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "login", info.login);
+    AddParser(propertyParsers, "password", info.password);
+    AddParser(propertyParsers, "priv", info.priv);
+}
+//-----------------------------------------------------------------------------
+GET_ADMIN::PARSER::~PARSER()
+{
+    PROPERTY_PARSERS::iterator it(propertyParsers.begin());
+    while (it != propertyParsers.end())
+        delete (it++)->second;
+}
+//-----------------------------------------------------------------------------
+int GET_ADMIN::PARSER::ParseStart(const char * el, const char ** attr)
+{
+depth++;
+if (depth == 1)
+    ParseAdmin(el, attr);
+
+if (depth == 2 && parsingAnswer)
+    ParseAdminParams(el, attr);
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+void GET_ADMIN::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_ADMIN::PARSER::ParseAdmin(const char * el, const char ** attr)
+{
+if (strcasecmp(el, "admin") == 0)
+    {
+    if (attr && attr[0] && attr[1])
+        {
+        if (strcasecmp(attr[1], "error") == 0)
+            {
+            if (attr[2] && attr[3])
+                error = attr[3];
+            else
+                error = "Admin not found.";
+            }
+        else
+            parsingAnswer = true;
+        }
+    else
+        parsingAnswer = true;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_ADMIN::PARSER::ParseAdminParams(const char * el, const char ** attr)
+{
+if (!TryParse(propertyParsers, ToLower(el), attr))
+    error = "Invalid parameter.";
+}
diff --git a/stglibs/srvconf.lib/parsers/get_admin.h b/stglibs/srvconf.lib/parsers/get_admin.h
new file mode 100644 (file)
index 0000000..d8e2fe9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_GET_ADMIN_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_ADMIN_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/admin_conf.h"
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace GET_ADMIN
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    typedef GET_ADMIN::INFO INFO;
+
+    PARSER(CALLBACK f, void * data);
+    virtual ~PARSER();
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void ParseAdmin(const char * el, const char ** attr);
+    void ParseAdminParams(const char * el, const char ** attr);
+};
+
+} // namespace GET_ADMIN
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_container.h b/stglibs/srvconf.lib/parsers/get_container.h
new file mode 100644 (file)
index 0000000..c07e9e1
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_GET_CONTAINER_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_CONTAINER_H__
+
+#include "base.h"
+
+#include <string>
+
+#include <strings.h>
+
+namespace STG
+{
+namespace GET_CONTAINER
+{
+
+template <typename ELEMENT_PARSER>
+class PARSER: public STG::PARSER
+{
+public:
+    typedef std::vector<typename ELEMENT_PARSER::INFO> INFO;
+    typedef void (* CALLBACK)(bool result, const std::string & reason, const INFO & info, void * data);
+    PARSER(const std::string & t, CALLBACK f, void * d)
+        : tag(t), callback(f), data(d),
+          elementParser(&PARSER<ELEMENT_PARSER>::ElementCallback, this),
+          depth(0), parsingAnswer(false)
+    {}
+    int  ParseStart(const char * el, const char ** attr)
+    {
+    depth++;
+    if (depth == 1 && strcasecmp(el, tag.c_str()) == 0)
+        parsingAnswer = true;
+
+    if (depth > 1 && parsingAnswer)
+        elementParser.ParseStart(el, attr);
+
+    return 0;
+    }
+    void ParseEnd(const char * el)
+    {
+    depth--;
+    if (depth > 0 && parsingAnswer)
+        elementParser.ParseEnd(el);
+
+    if (depth == 0 && parsingAnswer)
+        {
+        if (callback)
+            callback(error.empty(), error, info, data);
+        error.clear();
+        info.clear();
+        parsingAnswer = false;
+        }
+    }
+
+private:
+    std::string tag;
+    CALLBACK callback;
+    void * data;
+    ELEMENT_PARSER elementParser;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void AddElement(const typename ELEMENT_PARSER::INFO & elementInfo)
+    {
+    info.push_back(elementInfo);
+    }
+    void SetError(const std::string & e) { error = e; }
+
+    static void ElementCallback(bool result, const std::string& reason, const typename ELEMENT_PARSER::INFO & info, void * data)
+    {
+    PARSER<ELEMENT_PARSER> * parser = static_cast<PARSER<ELEMENT_PARSER> *>(data);
+    if (!result)
+        parser->SetError(reason);
+    else
+        parser->AddElement(info);
+    }
+};
+
+} // namespace GET_CONTAINER
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_corp.cpp b/stglibs/srvconf.lib/parsers/get_corp.cpp
new file mode 100644 (file)
index 0000000..339d1eb
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *    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 "get_corp.h"
+
+#include "parsers/property.h"
+
+#include "stg/common.h"
+
+#include <strings.h>
+
+using namespace STG;
+
+GET_CORP::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "name", info.name);
+    AddParser(propertyParsers, "cash", info.cash);
+}
+//-----------------------------------------------------------------------------
+GET_CORP::PARSER::~PARSER()
+{
+    PROPERTY_PARSERS::iterator it(propertyParsers.begin());
+    while (it != propertyParsers.end())
+        delete (it++)->second;
+}
+//-----------------------------------------------------------------------------
+int GET_CORP::PARSER::ParseStart(const char * el, const char ** attr)
+{
+depth++;
+if (depth == 1)
+    ParseCorp(el, attr);
+
+if (depth == 2 && parsingAnswer)
+    ParseCorpParams(el, attr);
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+void GET_CORP::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_CORP::PARSER::ParseCorp(const char * el, const char ** attr)
+{
+if (strcasecmp(el, "corp") == 0)
+    {
+    if (attr && attr[0] && attr[1])
+        {
+        if (strcasecmp(attr[1], "error") == 0)
+            {
+            if (attr[2] && attr[3])
+                error = attr[3];
+            else
+                error = "Corp not found.";
+            }
+        else
+            parsingAnswer = true;
+        }
+    else
+        parsingAnswer = true;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_CORP::PARSER::ParseCorpParams(const char * el, const char ** attr)
+{
+if (!TryParse(propertyParsers, ToLower(el), attr))
+    error = "Invalid parameter.";
+}
diff --git a/stglibs/srvconf.lib/parsers/get_corp.h b/stglibs/srvconf.lib/parsers/get_corp.h
new file mode 100644 (file)
index 0000000..a01fe26
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_GET_CORP_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_CORP_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/corp_conf.h"
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace GET_CORP
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    typedef GET_CORP::INFO INFO;
+
+    PARSER(CALLBACK f, void * data);
+    virtual ~PARSER();
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void ParseCorp(const char * el, const char ** attr);
+    void ParseCorpParams(const char * el, const char ** attr);
+};
+
+} // namespace GET_CORP
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_service.cpp b/stglibs/srvconf.lib/parsers/get_service.cpp
new file mode 100644 (file)
index 0000000..105b739
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *    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 "get_service.h"
+
+#include "parsers/property.h"
+
+#include "stg/common.h"
+
+#include <strings.h>
+
+using namespace STG;
+
+GET_SERVICE::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "name", info.name);
+    AddParser(propertyParsers, "comment", info.comment);
+    AddParser(propertyParsers, "cost", info.cost);
+    AddParser(propertyParsers, "payDay", info.payDay);
+}
+//-----------------------------------------------------------------------------
+GET_SERVICE::PARSER::~PARSER()
+{
+    PROPERTY_PARSERS::iterator it(propertyParsers.begin());
+    while (it != propertyParsers.end())
+        delete (it++)->second;
+}
+//-----------------------------------------------------------------------------
+int GET_SERVICE::PARSER::ParseStart(const char * el, const char ** attr)
+{
+depth++;
+if (depth == 1)
+    ParseService(el, attr);
+
+if (depth == 2 && parsingAnswer)
+    ParseServiceParams(el, attr);
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+void GET_SERVICE::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_SERVICE::PARSER::ParseService(const char * el, const char ** attr)
+{
+if (strcasecmp(el, "service") == 0)
+    {
+    if (attr && attr[0] && attr[1])
+        {
+        if (strcasecmp(attr[1], "error") == 0)
+            {
+            if (attr[2] && attr[3])
+                error = attr[3];
+            else
+                error = "Service not found.";
+            }
+        else
+            parsingAnswer = true;
+        }
+    else
+        parsingAnswer = true;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_SERVICE::PARSER::ParseServiceParams(const char * el, const char ** attr)
+{
+if (!TryParse(propertyParsers, ToLower(el), attr))
+    error = "Invalid parameter.";
+}
diff --git a/stglibs/srvconf.lib/parsers/get_service.h b/stglibs/srvconf.lib/parsers/get_service.h
new file mode 100644 (file)
index 0000000..847d8bf
--- /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>
+ */
+
+#ifndef __STG_STGLIBS_SRVCONF_PARSER_GET_SERVICE_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_SERVICE_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/service_conf.h"
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace GET_SERVICE
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    typedef GET_SERVICE::INFO INFO;
+    PARSER(CALLBACK f, void * data);
+    virtual ~PARSER();
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void ParseService(const char * el, const char ** attr);
+    void ParseServiceParams(const char * el, const char ** attr);
+};
+
+} // namespace GET_SERVICE
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_tariff.cpp b/stglibs/srvconf.lib/parsers/get_tariff.cpp
new file mode 100644 (file)
index 0000000..e861843
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *    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 "get_tariff.h"
+
+#include "parsers/property.h"
+
+#include "stg/common.h"
+
+#include <utility>
+
+#include <strings.h>
+
+using namespace STG;
+
+namespace
+{
+
+template <typename A, typename T>
+class AOS_PARSER : public BASE_PROPERTY_PARSER
+{
+    public:
+        typedef bool (* FUNC)(const char **, A &, T A::value_type:: *);
+        AOS_PARSER(A & a, T A::value_type:: * fld, FUNC f) : array(a), field(fld), func(f) {}
+        virtual bool Parse(const char ** attr) { return func(attr, array, field); }
+    private:
+        A & array;
+        T A::value_type:: * field;
+        FUNC func;
+};
+
+template <typename A, typename T>
+inline
+void AddAOSParser(PROPERTY_PARSERS & parsers, const std::string & name, A & array, T A::value_type:: * field, const typename AOS_PARSER<A, T>::FUNC & func)
+{
+    parsers.insert(std::make_pair(ToLower(name), new AOS_PARSER<A, T>(array, field, func)));
+}
+
+bool GetTimeSpan(const char ** attr, DIRPRICE_DATA & value)
+{
+int hb = 0;
+int mb = 0;
+int he = 0;
+int me = 0;
+if (CheckValue(attr))
+    if (ParseTariffTimeStr(attr[1], hb, mb, he, me) == 0)
+        {
+        value.hDay = hb;
+        value.mDay = mb;
+        value.hNight = he;
+        value.mNight = me;
+        return true;
+        }
+return false;
+}
+
+template <typename T>
+bool GetTraffType(const char ** attr, T & value)
+{
+if (!CheckValue(attr))
+    return false;
+std::string type(attr[1]);
+if (type == "up")
+    value = TRAFF_UP;
+else if (type == "down")
+    value = TRAFF_DOWN;
+else if (type == "up+down")
+    value = TRAFF_UP_DOWN;
+else if (type == "max")
+    value = TRAFF_MAX;
+else
+    return false;
+return true;
+}
+
+template <typename A, typename T>
+bool GetSlashedValue(const char ** attr, A & array, T A::value_type:: * field)
+{
+if (!CheckValue(attr))
+    return false;
+const char * start = attr[1];
+size_t item = 0;
+const char * pos = NULL;
+while ((pos = strchr(start, '/')) && item < array.size())
+    {
+    if (str2x(std::string(start, pos), array[item++].*field))
+            return false;
+    start = pos + 1;
+    }
+if (item < array.size())
+    if (str2x(start, array[item].*field))
+        return false;
+return true;
+}
+
+} // namespace anonymous
+
+GET_TARIFF::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "fee", info.tariffConf.fee);
+    AddParser(propertyParsers, "passiveCost", info.tariffConf.passiveCost);
+    AddParser(propertyParsers, "free", info.tariffConf.free);
+    AddParser(propertyParsers, "traffType", info.tariffConf.traffType, GetTraffType);
+    for (size_t i = 0; i < DIR_NUM; ++i)
+        AddParser(propertyParsers, "time" + unsigned2str(i), info.dirPrice[i], GetTimeSpan);
+    AddAOSParser(propertyParsers, "priceDayA", info.dirPrice, &DIRPRICE_DATA::priceDayA, GetSlashedValue);
+    AddAOSParser(propertyParsers, "priceDayB", info.dirPrice, &DIRPRICE_DATA::priceDayB, GetSlashedValue);
+    AddAOSParser(propertyParsers, "priceNightA", info.dirPrice, &DIRPRICE_DATA::priceNightA, GetSlashedValue);
+    AddAOSParser(propertyParsers, "priceNightB", info.dirPrice, &DIRPRICE_DATA::priceNightB, GetSlashedValue);
+    AddAOSParser(propertyParsers, "singlePrice", info.dirPrice, &DIRPRICE_DATA::singlePrice, GetSlashedValue);
+    AddAOSParser(propertyParsers, "noDiscount", info.dirPrice, &DIRPRICE_DATA::noDiscount, GetSlashedValue);
+    AddAOSParser(propertyParsers, "threshold", info.dirPrice, &DIRPRICE_DATA::threshold, GetSlashedValue);
+}
+//-----------------------------------------------------------------------------
+GET_TARIFF::PARSER::~PARSER()
+{
+    PROPERTY_PARSERS::iterator it(propertyParsers.begin());
+    while (it != propertyParsers.end())
+        delete (it++)->second;
+}
+//-----------------------------------------------------------------------------
+int GET_TARIFF::PARSER::ParseStart(const char * el, const char ** attr)
+{
+depth++;
+if (depth == 1)
+    ParseTariff(el, attr);
+
+if (depth == 2 && parsingAnswer)
+    ParseTariffParams(el, attr);
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+void GET_TARIFF::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_TARIFF::PARSER::ParseTariff(const char * el, const char ** attr)
+{
+if (strcasecmp(el, "tariff") == 0)
+    {
+    if (attr && attr[0] && attr[1])
+        {
+        if (strcasecmp(attr[1], "error") == 0)
+            {
+            if (attr[2] && attr[3])
+                error = attr[3];
+            else
+                error = "Tariff not found.";
+            }
+        else
+            parsingAnswer = true;
+        }
+    else
+        parsingAnswer = true;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_TARIFF::PARSER::ParseTariffParams(const char * el, const char ** attr)
+{
+if (!TryParse(propertyParsers, ToLower(el), attr))
+    error = "Invalid parameter.";
+}
diff --git a/stglibs/srvconf.lib/parsers/get_tariff.h b/stglibs/srvconf.lib/parsers/get_tariff.h
new file mode 100644 (file)
index 0000000..e655825
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFF_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_TARIFF_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/tariff_conf.h"
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace GET_TARIFF
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    typedef GET_TARIFF::INFO INFO;
+
+    PARSER(CALLBACK f, void * data);
+    virtual ~PARSER();
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void ParseTariff(const char * el, const char ** attr);
+    void ParseTariffParams(const char * el, const char ** attr);
+};
+
+} // namespace GET_TARIFF
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/get_user.cpp b/stglibs/srvconf.lib/parsers/get_user.cpp
new file mode 100644 (file)
index 0000000..54cfc0f
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "get_user.h"
+
+#include "stg/common.h"
+
+#include <map>
+#include <utility>
+
+#include <strings.h>
+
+using namespace STG;
+
+namespace STG
+{
+
+template <>
+bool GetValue<GET_USER::STAT>(const char ** attr, GET_USER::STAT & value)
+{
+if (!attr)
+    return false;
+std::map<std::string, long long *> props;
+for (size_t i = 0; i < DIR_NUM; ++i)
+    {
+    props.insert(std::pair<std::string, long long *>("su" + unsigned2str(i), &value.su[i]));
+    props.insert(std::pair<std::string, long long *>("sd" + unsigned2str(i), &value.sd[i]));
+    props.insert(std::pair<std::string, long long *>("mu" + unsigned2str(i), &value.mu[i]));
+    props.insert(std::pair<std::string, long long *>("md" + unsigned2str(i), &value.md[i]));
+    }
+size_t pos = 0;
+while (attr[pos])
+    {
+        std::string name(ToLower(attr[pos++]));
+        std::map<std::string, long long *>::iterator it(props.find(name));
+        if (it != props.end())
+            if (str2x(attr[pos++], *it->second) < 0)
+                return false;
+    }
+return true;
+}
+
+}
+
+GET_USER::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "login", info.login);
+    AddParser(propertyParsers, "password", info.password);
+    AddParser(propertyParsers, "cash", info.cash);
+    AddParser(propertyParsers, "credit", info.credit);
+    AddParser(propertyParsers, "creditExpire", info.creditExpire);
+    AddParser(propertyParsers, "lastCash", info.lastCash);
+    AddParser(propertyParsers, "prepaidTraff", info.prepaidTraff);
+    AddParser(propertyParsers, "down", info.down);
+    AddParser(propertyParsers, "passive", info.passive);
+    AddParser(propertyParsers, "disableDetailStat", info.disableDetailStat);
+    AddParser(propertyParsers, "connected", info.connected);
+    AddParser(propertyParsers, "aonline", info.alwaysOnline);
+    AddParser(propertyParsers, "currIP", info.ip, GetIPValue);
+    AddParser(propertyParsers, "ip", info.ips);
+    AddParser(propertyParsers, "tariff", info.tariff);
+    AddParser(propertyParsers, "group", info.group, GetEncodedValue);
+    AddParser(propertyParsers, "note", info.note, GetEncodedValue);
+    AddParser(propertyParsers, "email", info.email, GetEncodedValue);
+    AddParser(propertyParsers, "name", info.name, GetEncodedValue);
+    AddParser(propertyParsers, "address", info.address, GetEncodedValue);
+    AddParser(propertyParsers, "phone", info.phone, GetEncodedValue);
+    AddParser(propertyParsers, "traff", info.stat);
+
+    for (size_t i = 0; i < USERDATA_NUM; ++i)
+        AddParser(propertyParsers, "userData" + unsigned2str(i), info.userData[i], GetEncodedValue);
+}
+//-----------------------------------------------------------------------------
+GET_USER::PARSER::~PARSER()
+{
+    PROPERTY_PARSERS::iterator it(propertyParsers.begin());
+    while (it != propertyParsers.end())
+        delete (it++)->second;
+}
+//-----------------------------------------------------------------------------
+int GET_USER::PARSER::ParseStart(const char * el, const char ** attr)
+{
+depth++;
+if (depth == 1)
+    ParseUser(el, attr);
+
+if (depth == 2 && parsingAnswer)
+    ParseUserParams(el, attr);
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+void GET_USER::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_USER::PARSER::ParseUser(const char * el, const char ** attr)
+{
+if (strcasecmp(el, "user") == 0)
+    {
+    if (attr && attr[0] && attr[1])
+        {
+        if (strcasecmp(attr[1], "error") == 0)
+            {
+            if (attr[2] && attr[3])
+                error = attr[3];
+            else
+                error = "User not found.";
+            }
+        else
+            parsingAnswer = true;
+        }
+    else
+        parsingAnswer = true;
+    }
+}
+//-----------------------------------------------------------------------------
+void GET_USER::PARSER::ParseUserParams(const char * el, const char ** attr)
+{
+if (!TryParse(propertyParsers, ToLower(el), attr))
+    error = "Invalid parameter.";
+}
diff --git a/stglibs/srvconf.lib/parsers/get_user.h b/stglibs/srvconf.lib/parsers/get_user.h
new file mode 100644 (file)
index 0000000..519d67b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_SRVCONF_PARSER_GET_USER_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_GET_USER_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace GET_USER
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    typedef GET_USER::INFO INFO;
+
+    PARSER(CALLBACK f, void * data);
+    virtual ~PARSER();
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    INFO info;
+    int depth;
+    bool parsingAnswer;
+    std::string error;
+
+    void ParseUser(const char * el, const char ** attr);
+    void ParseUserParams(const char * el, const char ** attr);
+};
+
+} // namespace GET_USER
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/property.cpp b/stglibs/srvconf.lib/parsers/property.cpp
new file mode 100644 (file)
index 0000000..8a78fe7
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ *    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 "property.h"
+
+#include <strings.h>
+
+bool STG::CheckValue(const char ** attr)
+{
+return attr && attr[0] && attr[1] && strcasecmp(attr[0], "value") == 0;
+}
+
+bool STG::GetEncodedValue(const char ** attr, std::string & value)
+{
+if (!CheckValue(attr))
+    return false;
+Decode21str(value, attr[1]);
+return true;
+}
+
+bool STG::GetIPValue(const char ** attr, uint32_t & value)
+{
+if (!CheckValue(attr))
+    return false;
+std::string ip(attr[1]);
+value = inet_strington(attr[1]);
+if (value == 0 && ip != "0.0.0.0")
+    return false;
+return true;
+}
+
+bool STG::TryParse(PROPERTY_PARSERS & parsers, const std::string & name, const char ** attr)
+{
+    PROPERTY_PARSERS::iterator it(parsers.find(name));
+    if (it != parsers.end())
+        return it->second->Parse(attr);
+    return true; // Assume that non-existing params are ok.
+}
diff --git a/stglibs/srvconf.lib/parsers/property.h b/stglibs/srvconf.lib/parsers/property.h
new file mode 100644 (file)
index 0000000..3469b98
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PROPERTY_PARSERS_H__
+#define __STG_STGLIBS_SRVCONF_PROPERTY_PARSERS_H__
+
+#include "stg/common.h"
+
+#include <map>
+#include <string>
+
+namespace STG
+{
+
+class BASE_PROPERTY_PARSER
+{
+    public:
+        virtual ~BASE_PROPERTY_PARSER() {}
+        virtual bool Parse(const char ** attr) = 0;
+};
+
+template <typename T>
+class PROPERTY_PARSER : public BASE_PROPERTY_PARSER
+{
+    public:
+        typedef bool (* FUNC)(const char **, T &);
+        PROPERTY_PARSER(T & v, FUNC f) : value(v), func(f) {}
+        virtual bool Parse(const char ** attr) { return func(attr, value); }
+    private:
+        T & value;
+        FUNC func;
+};
+
+typedef std::map<std::string, BASE_PROPERTY_PARSER *> PROPERTY_PARSERS;
+
+bool CheckValue(const char ** attr);
+
+template <typename T>
+inline
+bool GetValue(const char ** attr, T & value)
+{
+if (CheckValue(attr))
+    if (str2x(attr[1], value) < 0)
+        return false;
+return true;
+}
+
+template <>
+inline
+bool GetValue<std::string>(const char ** attr, std::string & value)
+{
+if (!CheckValue(attr))
+    return false;
+value = attr[1];
+return true;
+}
+
+template <>
+inline
+bool GetValue<double>(const char ** attr, double & value)
+{
+if (CheckValue(attr))
+    if (strtodouble2(attr[1], value))
+        return false;
+return true;
+}
+
+bool GetEncodedValue(const char ** attr, std::string & value);
+
+bool GetIPValue(const char ** attr, uint32_t& value);
+
+template <typename T>
+void AddParser(PROPERTY_PARSERS & parsers, const std::string & name, T & value, const typename PROPERTY_PARSER<T>::FUNC & func = GetValue<T>);
+
+template <typename T>
+inline
+void AddParser(PROPERTY_PARSERS & parsers, const std::string & name, T & value, const typename PROPERTY_PARSER<T>::FUNC & func)
+{
+    parsers.insert(std::make_pair(ToLower(name), new PROPERTY_PARSER<T>(value, func)));
+}
+
+bool TryParse(PROPERTY_PARSERS & parsers, const std::string & name, const char ** attr);
+
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/resetable_utils.h b/stglibs/srvconf.lib/parsers/resetable_utils.h
new file mode 100644 (file)
index 0000000..ed1cd30
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_RESETABLE_UTILS_H__
+#define __STG_STGLIBS_SRVCONF_RESETABLE_UTILS_H__
+
+#include "stg/resetable.h"
+
+#include <string>
+#include <ostream>
+
+namespace STG
+{
+
+template <typename T>
+void appendResetable(std::ostream & stream, const std::string & name, const T & value)
+{
+if (!value.empty())
+    stream << "<" << name << " value=\"" << value.data() << "\"/>";
+}
+
+template <typename T>
+void appendResetable(std::ostream & stream, const std::string & name, size_t suffix, const T & value)
+{
+if (!value.empty())
+    stream << "<" << name << suffix << " value=\"" << value.data() << "\"/>";
+}
+
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/server_info.cpp b/stglibs/srvconf.lib/parsers/server_info.cpp
new file mode 100644 (file)
index 0000000..fbefb2d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#include "server_info.h"
+
+#include "stg/common.h"
+
+#include <cstdio> // sprintf
+
+#include <strings.h>
+
+using namespace STG;
+
+namespace
+{
+
+const size_t UNAME_LEN    = 256;
+const size_t SERV_VER_LEN = 64;
+const size_t DIRNAME_LEN  = 16;
+
+}
+
+SERVER_INFO::PARSER::PARSER(CALLBACK f, void * d)
+    : callback(f),
+      data(d),
+      depth(0),
+      parsingAnswer(false)
+{
+    AddParser(propertyParsers, "uname", info.uname);
+    AddParser(propertyParsers, "version", info.version);
+    AddParser(propertyParsers, "tariff", info.tariffType);
+    AddParser(propertyParsers, "dir_num", info.dirNum);
+    AddParser(propertyParsers, "users_num", info.usersNum);
+    AddParser(propertyParsers, "tariff_num", info.tariffNum);
+
+    for (size_t i = 0; i < DIR_NUM; i++)
+        AddParser(propertyParsers, "dir_name_" + unsigned2str(i), info.dirName[i], GetEncodedValue);
+}
+//-----------------------------------------------------------------------------
+int SERVER_INFO::PARSER::ParseStart(const char *el, const char **attr)
+{
+depth++;
+if (depth == 1)
+    {
+    if (strcasecmp(el, "ServerInfo") == 0)
+        parsingAnswer = true;
+    }
+else
+    {
+    if (depth == 2 && parsingAnswer)
+        if (!TryParse(propertyParsers, ToLower(el), attr))
+            error = "Invalid parameter.";
+    }
+return 0;
+}
+//-----------------------------------------------------------------------------
+void SERVER_INFO::PARSER::ParseEnd(const char * /*el*/)
+{
+depth--;
+if (depth == 0 && parsingAnswer)
+    {
+    if (callback)
+        callback(error.empty(), error, info, data);
+    error.clear();
+    parsingAnswer = false;
+    }
+}
diff --git a/stglibs/srvconf.lib/parsers/server_info.h b/stglibs/srvconf.lib/parsers/server_info.h
new file mode 100644 (file)
index 0000000..7f5b8e9
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *    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>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#ifndef __STG_STGLIBS_SRVCONF_PARSER_SERVER_INFO_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_SERVER_INFO_H__
+
+#include "base.h"
+#include "property.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace SERVER_INFO
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    PARSER(CALLBACK f, void * data);
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    PROPERTY_PARSERS propertyParsers;
+    CALLBACK callback;
+    void * data;
+    int depth;
+    bool parsingAnswer;
+    INFO info;
+    std::string error;
+};
+
+} // namespace SERVER_INFO
+} // namespace STG
+
+#endif
diff --git a/stglibs/srvconf.lib/parsers/simple.cpp b/stglibs/srvconf.lib/parsers/simple.cpp
new file mode 100644 (file)
index 0000000..89537f2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *    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 "simple.h"
+
+#include <strings.h>
+
+using namespace STG;
+
+SIMPLE::PARSER::PARSER(const std::string & t, CALLBACK f, void * d)
+    : tag(t),
+      callback(f),
+      data(d),
+      depth(0)
+{
+}
+//-----------------------------------------------------------------------------
+int SIMPLE::PARSER::ParseStart(const char *el, const char **attr)
+{
+depth++;
+if (depth == 1)
+    if (strcasecmp(el, tag.c_str()) == 0)
+        ParseAnswer(el, attr);
+return 0;
+}
+//-----------------------------------------------------------------------------
+void SIMPLE::PARSER::ParseEnd(const char *)
+{
+depth--;
+}
+//-----------------------------------------------------------------------------
+void SIMPLE::PARSER::ParseAnswer(const char * /*el*/, const char ** attr)
+{
+if (!callback)
+    return;
+if (attr && attr[0] && attr[1])
+    callback(strcasecmp(attr[1], "ok") == 0, attr[2] && attr[3] ? attr[3] : attr[1], data);
+else
+    callback(false, "Invalid response.", data);
+}
diff --git a/stglibs/srvconf.lib/parsers/simple.h b/stglibs/srvconf.lib/parsers/simple.h
new file mode 100644 (file)
index 0000000..03c950b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *    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 __STG_STGLIBS_SRVCONF_PARSER_SIMPLE_H__
+#define __STG_STGLIBS_SRVCONF_PARSER_SIMPLE_H__
+
+#include "base.h"
+
+#include "stg/servconf_types.h"
+
+#include <string>
+
+namespace STG
+{
+namespace SIMPLE
+{
+
+class PARSER: public STG::PARSER
+{
+public:
+    PARSER(const std::string & tag, CALLBACK f, void * data);
+    int  ParseStart(const char * el, const char ** attr);
+    void ParseEnd(const char * el);
+
+private:
+    std::string tag;
+    CALLBACK callback;
+    void * data;
+    int depth;
+
+    void ParseAnswer(const char * el, const char ** attr);
+};
+
+} // namespace SIMPLE
+} // namespace STG
+
+#endif
index ab386cf753dfab06b631806d5faea58d63776050..430de3c146d20d430a564201cd592c02e5a75eea 100644 (file)
 
 /*
  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
  */
 
- /*
- $Revision: 1.8 $
- $Date: 2010/08/04 00:40:38 $
- $Author: faust $
- */
+#include "stg/servconf.h"
+
+#include "netunit.h"
+
+#include "parsers/simple.h"
+#include "parsers/get_container.h"
+
+#include "parsers/server_info.h"
+
+#include "parsers/get_admin.h"
+#include "parsers/chg_admin.h"
+
+#include "parsers/get_tariff.h"
+#include "parsers/chg_tariff.h"
+
+#include "parsers/auth_by.h"
+#include "parsers/get_user.h"
+#include "parsers/chg_user.h"
+
+#include "parsers/get_service.h"
+#include "parsers/chg_service.h"
+
+#include "parsers/get_corp.h"
+#include "parsers/chg_corp.h"
+
+#include "parsers/base.h"
+
+#include "stg/common.h"
 
 #include <cstdio>
 #include <cstring>
 
-#include "stg/common.h"
-#include "stg/servconf.h"
+#include <expat.h>
 
-using namespace std;
+using namespace STG;
 
-//-----------------------------------------------------------------------------
-int AnsRecv(void * data, list<string> * list1)
+class SERVCONF::IMPL
 {
-//NODE * node;
-SERVCONF * sc;
-char ans[ENC_MSG_LEN + 1];
-int len, done = 0;
-
-sc = (SERVCONF*)data;
+public:
+    IMPL(const std::string & server, uint16_t port,
+         const std::string & login, const std::string & password);
 
-XML_ParserReset(sc->parser, NULL);
-XML_SetElementHandler(sc->parser, Start, End);
-XML_SetUserData(sc->parser, data);
+    const std::string & GetStrError() const;
+    static void Start(void * data, const char * el, const char ** attr);
+    static void End(void * data, const char * el);
 
-//loop parsing
-list<string>::iterator node;
-node = list1->begin();
+    int RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data);
 
-if (node == list1->end())
+    template <class P, typename C>
+    int Exec(const std::string & request, C callback, void * data)
     {
-    return st_ok;
+        P cp(callback, data);
+        return ExecImpl(request, cp);
     }
 
-while (node != list1->end())
+    template <class P, typename C>
+    int Exec(const std::string & tag, const std::string & request, C callback, void * data)
     {
-    strncpy(ans, node->c_str(), ENC_MSG_LEN);
-    ans[ENC_MSG_LEN] = 0;
-       //printf("---> %s\n", ans);
-    len = strlen(ans);
-
-    if (XML_Parse(sc->parser, ans, len, done) == XML_STATUS_ERROR)
-        {
-        strprintf(&sc->errorMsg, "XML parse error at line %d: %s",
-                  static_cast<int>(XML_GetCurrentLineNumber(sc->parser)),
-                  XML_ErrorString(XML_GetErrorCode(sc->parser)));
-        return st_xml_parse_error;
-        }
-    ++node;
+        P cp(tag, callback, data);
+        return ExecImpl(request, cp);
+    }
+
+private:
+    NETTRANSACT nt;
+
+    std::string errorMsg;
+    XML_Parser parser;
+
+    static bool ParserRecv(const std::string & chunk, bool final, void * data);
+    static bool SimpleRecv(const std::string & chunk, bool final, void * data);
+    int ExecImpl(const std::string & request, PARSER & cp);
+};
+
+bool SERVCONF::IMPL::ParserRecv(const std::string & chunk, bool final, void * data)
+{
+SERVCONF::IMPL * sc = static_cast<SERVCONF::IMPL *>(data);
 
+if (XML_Parse(sc->parser, chunk.c_str(), chunk.length(), final) == XML_STATUS_ERROR)
+    {
+    strprintf(&sc->errorMsg, "XML parse error at line %d: %s",
+              static_cast<int>(XML_GetCurrentLineNumber(sc->parser)),
+              XML_ErrorString(XML_GetErrorCode(sc->parser)));
+    printf("%s\n", sc->errorMsg.c_str());
+    return false;
     }
 
-return 0;
+return true;
 }
-//-----------------------------------------------------------------------------
-void Start(void *data, const char *el, const char **attr)
+
+bool SERVCONF::IMPL::SimpleRecv(const std::string & chunk, bool /*final*/, void * data)
 {
-SERVCONF * sc;
-sc = (SERVCONF*)data;
-sc->Start(el, attr);
+*static_cast<std::string *>(data) += chunk;
+return true;
 }
-//-----------------------------------------------------------------------------
-void End(void *data, const char *el)
+
+SERVCONF::SERVCONF(const std::string & server, uint16_t port,
+                   const std::string & login, const std::string & password)
+    : pImpl(new IMPL(server, port, login, password))
 {
-SERVCONF * sc;
-sc = (SERVCONF*)data;
-sc->End(el);
 }
-//-----------------------------------------------------------------------------
-SERVCONF::SERVCONF()
-    : currParser(NULL),
-      parseDepth(0),
-      error(0),
-      RecvUserDataCb(NULL),
-      RecvGetUserDataCb(NULL),
-      RecvServerInfoDataCb(NULL),
-      RecvChgUserCb(NULL),
-      RecvCheckUserCb(NULL),
-      RecvSendMessageCb(NULL),
-      getUserDataDataCb(NULL),
-      getUsersDataDataCb(NULL),
-      getServerInfoDataCb(NULL),
-      chgUserDataCb(NULL),
-      checkUserDataCb(NULL),
-      sendMessageDataCb(NULL)
+
+SERVCONF::~SERVCONF()
 {
-parser = XML_ParserCreate(NULL);
+delete pImpl;
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetServer(const char * server)
+
+int SERVCONF::ServerInfo(SERVER_INFO::CALLBACK f, void * data)
 {
-nt.SetServer(server);
+return pImpl->Exec<SERVER_INFO::PARSER>("<GetServerInfo/>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetPort(uint16_t port)
+
+int SERVCONF::RawXML(const std::string & request, RAW_XML::CALLBACK f, void * data)
 {
-nt.SetServerPort(port);
+return pImpl->RawXML(request, f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetAdmLogin(const char * login)
+
+// -- Admins --
+
+int SERVCONF::GetAdmins(GET_CONTAINER::CALLBACK<GET_ADMIN::INFO>::TYPE f, void * data)
 {
-nt.SetLogin(login);
+return pImpl->Exec<GET_CONTAINER::PARSER<GET_ADMIN::PARSER> >("admins", "<GetAdmins/>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetAdmPassword(const char * password)
+
+int SERVCONF::GetAdmin(const std::string & login, GET_ADMIN::CALLBACK f, void * data)
 {
-nt.SetPassword(password);
+return pImpl->Exec<GET_ADMIN::PARSER>("<GetAdmin login=\"" + login + "\"/>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::GetUser(const char * l)
-{
-char request[255];
-snprintf(request, 255, "<GetUser login=\"%s\"/>", l);
-int ret;
-
-currParser = &parserGetUser;
-((PARSER_GET_USER*)currParser)->SetUserDataRecvCb(RecvGetUserDataCb, getUserDataDataCb);
-
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
-
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
 
-return st_ok;
-}
-//-----------------------------------------------------------------------------
-int SERVCONF::GetUsers()
+int SERVCONF::ChgAdmin(const ADMIN_CONF_RES & conf, SIMPLE::CALLBACK f, void * data)
 {
-char request[] = "<GetUsers/>";
-int ret;
-
-currParser = &parserGetUsers;
-((PARSER_GET_USERS*)currParser)->SetUserDataRecvCb(RecvUserDataCb, getUsersDataDataCb);
-
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
-
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
+return pImpl->Exec<SIMPLE::PARSER>("ChgAdmin", "<ChgAdmin" + CHG_ADMIN::Serialize(conf) + "/>", f, data);
+}
 
-return st_ok;
+int SERVCONF::AddAdmin(const std::string & login,
+                       const ADMIN_CONF_RES & conf,
+                       SIMPLE::CALLBACK f, void * data)
+{
+int res = pImpl->Exec<SIMPLE::PARSER>("AddAdmin", "<AddAdmin login=\"" + login + "\"/>", f, data);
+if (res != st_ok)
+    return res;
+return pImpl->Exec<SIMPLE::PARSER>("ChgAdmin", "<ChgAdmin" + CHG_ADMIN::Serialize(conf) + "/>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::SendMessage(const char * login, const char * message, int prio)
+
+int SERVCONF::DelAdmin(const std::string & login, SIMPLE::CALLBACK f, void * data)
 {
-char request[1000];
-char msg[500];
-Encode12(msg, message, strlen(message));
-snprintf(request, 1000, "<Message login=\"%s\" priority=\"%d\" text=\"%s\"/>", login, prio, msg);
-int ret;
+return pImpl->Exec<SIMPLE::PARSER>("DelAdmin", "<DelAdmin login=\"" + login + "\"/>", f, data);
+}
 
-currParser = &parserSendMessage;
-parserSendMessage.SetSendMessageRecvCb(RecvSendMessageCb, sendMessageDataCb);
+// -- Tariffs --
 
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
+int SERVCONF::GetTariffs(GET_CONTAINER::CALLBACK<GET_TARIFF::INFO>::TYPE f, void * data)
+{
+return pImpl->Exec<GET_CONTAINER::PARSER<GET_TARIFF::PARSER> >("tariffs", "<GetTariffs/>", f, data);
+}
 
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
+int SERVCONF::GetTariff(const std::string & name, GET_TARIFF::CALLBACK f, void * data)
+{
+return pImpl->Exec<GET_TARIFF::PARSER>("<GetTariff name=\"" + name + "\"/>", f, data);
+}
 
-return st_ok;
+int SERVCONF::ChgTariff(const TARIFF_DATA_RES & tariffData, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("SetTariff", "<SetTariff name=\"" + tariffData.tariffConf.name.data() + "\">" + CHG_TARIFF::Serialize(tariffData) + "</SetTariff>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::GetServerInfo()
+
+int SERVCONF::AddTariff(const std::string & name,
+                       const TARIFF_DATA_RES & tariffData,
+                       SIMPLE::CALLBACK f, void * data)
 {
-char request[] = "<GetServerInfo/>";
-int ret;
+int res = pImpl->Exec<SIMPLE::PARSER>("AddTariff", "<AddTariff name=\"" + name + "\"/>", f, data);
+if (res != st_ok)
+    return res;
+return pImpl->Exec<SIMPLE::PARSER>("SetTariff", "<SetTariff name=\"" + name + "\">" + CHG_TARIFF::Serialize(tariffData) + "</SetTariff>", f, data);
+}
 
-currParser = &parserServerInfo;
-((PARSER_GET_SERVER_INFO*)currParser)->SetServerInfoRecvCb(RecvServerInfoDataCb, getServerInfoDataCb);
+int SERVCONF::DelTariff(const std::string & name, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("DelTariff", "<DelTariff name=\"" + name + "\"/>", f, data);
+}
 
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
+// -- Users --
 
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-
-return st_ok;
+int SERVCONF::GetUsers(GET_CONTAINER::CALLBACK<GET_USER::INFO>::TYPE f, void * data)
+{
+return pImpl->Exec<GET_CONTAINER::PARSER<GET_USER::PARSER> >("users", "<GetUsers/>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::ChgUser(const char * request)
+
+int SERVCONF::GetUser(const std::string & login, GET_USER::CALLBACK f, void * data)
 {
-int ret;
+return pImpl->Exec<GET_USER::PARSER>("<GetUser login=\"" + login + "\"/>", f, data);
+}
 
-currParser = &parserChgUser;
-((PARSER_CHG_USER*)currParser)->SetChgUserRecvCb(RecvChgUserCb, chgUserDataCb);
+int SERVCONF::ChgUser(const std::string & login,
+                      const USER_CONF_RES & conf,
+                      const USER_STAT_RES & stat,
+                      SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<CHG_USER::PARSER>("<SetUser><Login value=\"" + login + "\"/>" + CHG_USER::Serialize(conf, stat) + "</SetUser>", f, data);
+}
 
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
+int SERVCONF::DelUser(const std::string & login, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("DelUser", "<DelUser login=\"" + login + "\"/>", f, data);
+}
 
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
+int SERVCONF::AddUser(const std::string & login, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("AddUser", "<AddUser><Login value=\"" + login + "\"/></AddUser>", f, data);
+}
 
-return st_ok;
+int SERVCONF::AuthBy(const std::string & login, AUTH_BY::CALLBACK f, void * data)
+{
+return pImpl->Exec<AUTH_BY::PARSER>("<GetUserAuthBy login=\"" + login + "\"/>", f, data);
 }
-//-----------------------------------------------------------------------------
-//  TODO: remove this shit!
-//-----------------------------------------------------------------------------
-int SERVCONF::MsgUser(const char * request)
+
+int SERVCONF::SendMessage(const std::string & login, const std::string & text, SIMPLE::CALLBACK f, void * data)
 {
-int ret;
+return pImpl->Exec<SIMPLE::PARSER>("SendMessage", "<Message login=\"" + login + "\" msgver=\"1\" msgtype=\"1\" repeat=\"0\" repeatperiod=\"0\" showtime=\"0\" text=\"" + Encode12str(text) + "\"/>", f, data);
+}
 
-currParser = &parserSendMessage;
-parserSendMessage.SetSendMessageRecvCb(RecvSendMessageCb, sendMessageDataCb);
+int SERVCONF::CheckUser(const std::string & login, const std::string & password, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("CheckUser", "<CheckUser login=\"" + login + "\" password=\"" + password + "\"/>", f, data);
+}
 
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
+// -- Services --
 
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
+int SERVCONF::GetServices(GET_CONTAINER::CALLBACK<GET_SERVICE::INFO>::TYPE f, void * data)
+{
+return pImpl->Exec<GET_CONTAINER::PARSER<GET_SERVICE::PARSER> >("services", "<GetServices/>", f, data);
+}
 
-return st_ok;
+int SERVCONF::GetService(const std::string & name, GET_SERVICE::CALLBACK f, void * data)
+{
+return pImpl->Exec<GET_SERVICE::PARSER>("<GetService name=\"" + name + "\"/>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::CheckUser(const char * login, const char * password)
+
+int SERVCONF::ChgService(const SERVICE_CONF_RES & conf, SIMPLE::CALLBACK f, void * data)
 {
-char request[255];
-snprintf(request, 255, "<CheckUser login=\"%s\" password=\"%s\"/>", login, password);
-int ret;
+return pImpl->Exec<SIMPLE::PARSER>("SetService", "<SetService name=\"" + conf.name.data() + "\">" + CHG_SERVICE::Serialize(conf) + "</SetService>", f, data);
+}
 
-currParser = &parserCheckUser;
-((PARSER_CHECK_USER*)currParser)->SetCheckUserRecvCb(RecvCheckUserCb, checkUserDataCb);
+int SERVCONF::AddService(const std::string & name,
+                         const SERVICE_CONF_RES & conf,
+                         SIMPLE::CALLBACK f, void * data)
+{
+int res = pImpl->Exec<SIMPLE::PARSER>("AddService", "<AddService name=\"" + name + "\"/>", f, data);
+if (res != st_ok)
+    return res;
+return pImpl->Exec<SIMPLE::PARSER>("SetService", "<SetService name=\"" + name + "\">" + CHG_SERVICE::Serialize(conf) + "</SetService>", f, data);
+}
 
-nt.Reset();
-nt.SetRxCallback(this, AnsRecv);
+int SERVCONF::DelService(const std::string & name, SIMPLE::CALLBACK f, void * data)
+{
+return pImpl->Exec<SIMPLE::PARSER>("DelService", "<DelService name=\"" + name + "\"/>", f, data);
+}
 
-if ((ret = nt.Connect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Transact(request)) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
-if ((ret = nt.Disconnect()) != st_ok)
-    {
-    errorMsg = nt.GetError();
-    return ret;
-    }
+// -- Corporations --
 
-return st_ok;
+int SERVCONF::GetCorporations(GET_CONTAINER::CALLBACK<GET_CORP::INFO>::TYPE f, void * data)
+{
+return pImpl->Exec<GET_CONTAINER::PARSER<GET_CORP::PARSER> >("corporations", "<GetCorporations/>", f, data);
 }
-//-----------------------------------------------------------------------------
-int SERVCONF::Start(const char *el, const char **attr)
+
+int SERVCONF::GetCorp(const std::string & name, GET_CORP::CALLBACK f, void * data)
 {
-currParser->ParseStart(el, attr);
-return 0;
+return pImpl->Exec<GET_CORP::PARSER>("<GetCorp name=\"" + name + "\"/>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::End(const char *el)
+
+int SERVCONF::ChgCorp(const CORP_CONF_RES & conf, SIMPLE::CALLBACK f, void * data)
 {
-currParser->ParseEnd(el);
+return pImpl->Exec<SIMPLE::PARSER>("SetCorp", "<SetCorp name=\"" + conf.name.data() + "\">" + CHG_CORP::Serialize(conf) + "</SetCorp>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetUserDataRecvCb(RecvUserDataCb_t f, void * data)
+
+int SERVCONF::AddCorp(const std::string & name,
+                      const CORP_CONF_RES & conf,
+                      SIMPLE::CALLBACK f, void * data)
 {
-RecvUserDataCb = f;
-getUsersDataDataCb = data;
+int res = pImpl->Exec<SIMPLE::PARSER>("AddCorp", "<AddCorp name=\"" + name + "\"/>", f, data);
+if (res != st_ok)
+    return res;
+return pImpl->Exec<SIMPLE::PARSER>("SetCorp", "<SetCorp name=\"" + name + "\">" + CHG_CORP::Serialize(conf) + "</SetCorp>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetGetUserDataRecvCb(RecvUserDataCb_t f, void * data)
+
+int SERVCONF::DelCorp(const std::string & name, SIMPLE::CALLBACK f, void * data)
 {
-RecvGetUserDataCb = f;            //GET_USER
-getUserDataDataCb = data;
+return pImpl->Exec<SIMPLE::PARSER>("DelCorp", "<DelCorp name=\"" + name + "\"/>", f, data);
 }
-//-----------------------------------------------------------------------------
-void SERVCONF::SetServerInfoRecvCb(RecvServerInfoDataCb_t f, void * data)
+
+const std::string & SERVCONF::GetStrError() const
 {
-RecvServerInfoDataCb = f;
-getServerInfoDataCb = data;
+return pImpl->GetStrError();
 }
+
 //-----------------------------------------------------------------------------
-void SERVCONF::SetChgUserCb(RecvChgUserCb_t f, void * data)
+SERVCONF::IMPL::IMPL(const std::string & server, uint16_t port,
+                     const std::string & login, const std::string & password)
+    : nt( server, port, login, password )
 {
-RecvChgUserCb = f;
-chgUserDataCb = data;
+parser = XML_ParserCreate(NULL);
 }
 //-----------------------------------------------------------------------------
-void SERVCONF::SetCheckUserCb(RecvCheckUserCb_t f, void * data)
+void SERVCONF::IMPL::Start(void * data, const char * el, const char ** attr)
 {
-RecvCheckUserCb = f;
-checkUserDataCb = data;
+PARSER * currParser = static_cast<PARSER *>(data);
+currParser->ParseStart(el, attr);
 }
 //-----------------------------------------------------------------------------
-void SERVCONF::SetSendMessageCb(RecvSendMessageCb_t f, void * data)
+void SERVCONF::IMPL::End(void * data, const char * el)
 {
-RecvSendMessageCb = f;
-sendMessageDataCb = data;
+PARSER * currParser = static_cast<PARSER *>(data);
+currParser->ParseEnd(el);
 }
 //-----------------------------------------------------------------------------
-const std::string & SERVCONF::GetStrError() const
+const std::string & SERVCONF::IMPL::GetStrError() const
 {
 return errorMsg;
 }
 //-----------------------------------------------------------------------------
-int SERVCONF::GetError()
+int SERVCONF::IMPL::ExecImpl(const std::string & request, PARSER & cp)
 {
-int e = error;
-error = 0;
-return e;
+XML_ParserReset(parser, NULL);
+XML_SetElementHandler(parser, Start, End);
+XML_SetUserData(parser, &cp);
+
+int ret = 0;
+if ((ret = nt.Connect()) != st_ok)
+    {
+    errorMsg = nt.GetError();
+    return ret;
+    }
+if ((ret = nt.Transact(request, ParserRecv, this)) != st_ok)
+    {
+    errorMsg = nt.GetError();
+    return ret;
+    }
+
+nt.Disconnect();
+return st_ok;
+}
+
+int SERVCONF::IMPL::RawXML(const std::string & request, RAW_XML::CALLBACK callback, void * data)
+{
+int ret = 0;
+if ((ret = nt.Connect()) != st_ok)
+    {
+    errorMsg = nt.GetError();
+    callback(false, errorMsg, "", data);
+    return ret;
+    }
+std::string response;
+if ((ret = nt.Transact(request, SimpleRecv, &response)) != st_ok)
+    {
+    errorMsg = nt.GetError();
+    callback(false, errorMsg, "", data);
+    return ret;
+    }
+
+nt.Disconnect();
+callback(true, "", response, data);
+return st_ok;
 }
-//-----------------------------------------------------------------------------
diff --git a/stglibs/srvconf.lib/servconf.vpj b/stglibs/srvconf.lib/servconf.vpj
deleted file mode 100644 (file)
index c5f9b3c..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<!DOCTYPE Project SYSTEM "http://www.slickedit.com/dtd/vse/10.0/vpj.dtd">
-<Project
-       Version="10.0"
-       VendorName="SlickEdit"
-       WorkingDir="."
-       BuildSystem="automakefile"
-       BuildMakeFile="makefile">
-       <Config
-               Name="Debug"
-               Type="gnuc"
-               DebugCallbackName="gdb"
-               OutputFile="%bdservconf.a">
-               <Menu>
-                       <Target
-                               Name="Compile"
-                               MenuCaption="&amp;Compile"
-                               OutputExts="*.o"
-                               Dialog="_gnuc_options_form Compile"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveCurrent"
-                               Deletable="0">
-                               <Exec CmdLine='g++ -c %xup -pipe -g -Wall -ggdb -o "%bd%n%oe" %i "%f"'/>
-                       </Target>
-                       <Target
-                               Name="Link"
-                               MenuCaption="&amp;Link"
-                               ShowOnMenu="Never"
-                               Dialog="_gnuc_options_form Link"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveCurrent"
-                               Deletable="0">
-                               <Exec CmdLine='g++ %xup -pipe -g -Wall -o "%o" %f %libs'/>
-                       </Target>
-                       <Target
-                               Name="Build"
-                               MenuCaption="&amp;Build"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveWorkspaceFiles"
-                               Deletable="0">
-                               <Exec CmdLine="gmake -fMakefile"/>
-                       </Target>
-                       <Target
-                               Name="Rebuild"
-                               MenuCaption="&amp;Rebuild"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="Debug"
-                               MenuCaption="&amp;Debug"
-                               RunFromDir="%rw"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="Execute"
-                               MenuCaption="E&amp;xecute"
-                               RunFromDir="%rw"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="dash"
-                               MenuCaption="-"
-                               RunFromDir="%rw">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="GNU C Options"
-                               MenuCaption="GNU C &amp;Options..."
-                               ShowOnMenu="HideIfNoCmdLine"
-                               Deletable="0">
-                               <Exec
-                                       CmdLine="gnucoptions"
-                                       Type="Slick-C"/>
-                       </Target>
-               </Menu>
-               <Libs>
-                       <Lib File="/usr/lib/libexpat.a"/>
-               </Libs>
-       </Config>
-       <Config
-               Name="Release"
-               Type="gnuc"
-               DebugCallbackName="gdb"
-               OutputFile="%bdservconf.a">
-               <Menu>
-                       <Target
-                               Name="Compile"
-                               MenuCaption="&amp;Compile"
-                               OutputExts="*.o"
-                               Dialog="_gnuc_options_form Compile"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveCurrent"
-                               Deletable="0">
-                               <Exec CmdLine='g++ -c %xup -pipe -Wall -o "%bd%n%oe" %i "%f"'/>
-                       </Target>
-                       <Target
-                               Name="Link"
-                               MenuCaption="&amp;Link"
-                               ShowOnMenu="Never"
-                               Dialog="_gnuc_options_form Link"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveCurrent"
-                               Deletable="0">
-                               <Exec CmdLine='g++ %xup -pipe -Wall -o "%o" %f %libs'/>
-                       </Target>
-                       <Target
-                               Name="Build"
-                               MenuCaption="&amp;Build"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               SaveOption="SaveWorkspaceFiles"
-                               Deletable="0">
-                               <Exec CmdLine="gmake -fMakefile"/>
-                       </Target>
-                       <Target
-                               Name="Rebuild"
-                               MenuCaption="&amp;Rebuild"
-                               RunFromDir="%rw"
-                               CaptureOutputWith="ProcessBuffer"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="Debug"
-                               MenuCaption="&amp;Debug"
-                               RunFromDir="%rw"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="Execute"
-                               MenuCaption="E&amp;xecute"
-                               RunFromDir="%rw"
-                               Deletable="0">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="dash"
-                               MenuCaption="-"
-                               RunFromDir="%rw">
-                               <Exec/>
-                       </Target>
-                       <Target
-                               Name="GNU C Options"
-                               MenuCaption="GNU C &amp;Options..."
-                               ShowOnMenu="HideIfNoCmdLine"
-                               Deletable="0">
-                               <Exec
-                                       CmdLine="gnucoptions"
-                                       Type="Slick-C"/>
-                       </Target>
-               </Menu>
-               <Libs>
-                       <Lib File="/usr/lib/libexpat.a"/>
-               </Libs>
-       </Config>
-       <Files>
-               <Folder
-                       Name="Source Files"
-                       Filters="*.c;*.cc;*.cpp;*.cp;*.cxx;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl">
-                       <F N="netunit.cpp"/>
-                       <F N="parser.cpp"/>
-                       <F N="servconf.cpp"/>
-                       <F N="test.cpp"/>
-               </Folder>
-               <Folder
-                       Name="Header Files"
-                       Filters="*.h;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if">
-                       <F N="netunit.h"/>
-                       <F N="servconf.h"/>
-               </Folder>
-               <Folder
-                       Name="Resource Files"
-                       Filters="*.ico;*.cur;*.dlg"/>
-               <Folder
-                       Name="Bitmaps"
-                       Filters="*.bmp;*.xpm;*.xbm"/>
-               <Folder
-                       Name="Other Files"
-                       Filters=""/>
-       </Files>
-</Project>
diff --git a/stglibs/srvconf.lib/servconf.vpw b/stglibs/srvconf.lib/servconf.vpw
deleted file mode 100644 (file)
index 96ebe79..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-[Global]
-Version=8
-[ProjectFiles]
-servconf.vpj