]> git.stg.codes - stg.git/commitdiff
Merge branch 'stg-2.409'
authorMaxim Mamontov <faust.madf@gmail.com>
Sat, 21 Jan 2017 19:05:30 +0000 (21:05 +0200)
committerMaxim Mamontov <faust.madf@gmail.com>
Sat, 21 Jan 2017 19:05:30 +0000 (21:05 +0200)
1  2 
include/stg/admin_conf.h
include/stg/corp_conf.h
include/stg/user_traff.h
projects/stargazer/plugins/configuration/sgconfig/configproto.cpp
projects/stargazer/plugins/configuration/sgconfig/configproto.h
projects/stargazer/plugins/store/files/file_store.cpp
projects/stargazer/settings_impl.h
projects/stargazer/user_impl.cpp
projects/stargazer/user_impl.h
projects/stargazer/users_impl.cpp

diff --combined include/stg/admin_conf.h
index 6e073d6fe972765609c25f7c914e60cb4ba36f49,a2639d36963899224c812bb6189625910c562ebf..6f8005f5911ecaf5b1eb7e90e62b5584addf8d9e
@@@ -29,7 -29,7 +29,7 @@@ struct PRI
            serviceChg(0),
            corpChg(0)
      {}
-     PRIV(uint32_t p)
+     explicit PRIV(uint32_t p)
          : userStat((p & 0x00000003) >> 0x00),
            userConf((p & 0x0000000C) >> 0x02),
            userCash((p & 0x00000030) >> 0x04),
@@@ -62,11 -62,6 +62,6 @@@ struct ADMIN_CON
            login(),
            password("* NO PASSWORD *")
      {}
-     ADMIN_CONF(const ADMIN_CONF & rvalue)
-         : priv(rvalue.priv),
-           login(rvalue.login),
-           password(rvalue.password)
-     {}
      ADMIN_CONF(const PRIV & pr, const std::string & l, const std::string & p)
          : priv(pr),
            login(l),
  //-----------------------------------------------------------------------------
  struct ADMIN_CONF_RES
  {
 -    ADMIN_CONF_RES()
 +    ADMIN_CONF_RES() {}
 +    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;
diff --combined include/stg/corp_conf.h
index 9bbc03d326941e2edce782663cbec4e3cbd15163,3810516dfb8e73d3c786dfce5fba9ebdea4e4b24..5f941b954ec623b0447db1d7b78742dcc43abb98
@@@ -1,65 -1,18 +1,65 @@@
 +/*
 + *    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
  {
  CORP_CONF() : name(), cash(0) {}
- CORP_CONF(const std::string & n) : name(n), cash(0) {}
explicit CORP_CONF(const std::string & n) : name(n), cash(0) {}
  CORP_CONF(const std::string & n, double c) : name(n), cash(c) {}
  
  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)
  {
diff --combined include/stg/user_traff.h
index 8ef8e2608f8d3f2f569a7bb8cd4800e57a739b7b,d820588e3702d412436635474996da7d1a78b2c1..3ca9768ef185bc4f8d49be1d4a28658198846a57
@@@ -45,8 -45,6 +45,6 @@@ public
      typedef ContainerType::size_type IndexType;
  
      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(); }
@@@ -80,21 -78,25 +78,27 @@@ 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)
+     explicit DIR_TRAFF_RES(const DIR_TRAFF & ts)
          : traff(ts.size())
      {
      for (IndexType i = 0; i < ts.size(); ++i)
          traff[i] = ts[i];
      }
+     DIR_TRAFF_RES & operator=(const DIR_TRAFF & ts)
+     {
+         for (IndexType i = 0; i < ts.size(); ++i)
+             traff[i] = ts[i];
+         return *this;
+     }
      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;
index f5a57a48ca11a6c377620b0892481335d4e3f7ef,020c1365dcb76fc6e5de4d20d67fbfebf58bae6b..74f8abd6e15e0c9713be83680edc0c5e67a3f47a
@@@ -27,9 -27,7 +27,9 @@@
  #include "parser_admins.h"
  #include "parser_tariffs.h"
  #include "parser_users.h"
 +#include "parser_services.h"
  #include "parser_message.h"
 +#include "parser_user_info.h"
  #include "parser_auth_by.h"
  
  #include "stg/common.h"
@@@ -55,8 -53,6 +55,8 @@@ CONFIGPROTO::CONFIGPROTO(PLUGIN_LOGGER 
        m_admins(NULL),
        m_tariffs(NULL),
        m_users(NULL),
 +      m_services(NULL),
 +      m_corporations(NULL),
        m_store(NULL),
        m_port(0),
        m_bindAddress("0.0.0.0"),
  
  CONFIGPROTO::~CONFIGPROTO()
  {
+     {
      std::deque<STG::Conn *>::iterator it;
      for (it = m_conns.begin(); it != m_conns.end(); ++it)
          delete *it;
+     }
+     {
+     BASE_PARSER::REGISTRY::iterator it;
+     for (it = m_registry.begin(); it != m_registry.end(); ++it)
+         delete it->second;
+     }
  }
  
  int CONFIGPROTO::Prepare()
@@@ -83,6 -86,7 +90,6 @@@
      sigaddset(&sigmask, SIGUSR1);
      sigaddset(&sigmask, SIGHUP);
      pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
 -
      m_listenSocket = socket(PF_INET, SOCK_STREAM, 0);
  
      if (m_listenSocket < 0)
@@@ -210,8 -214,6 +217,8 @@@ void CONFIGPROTO::RegisterParsers(
      assert(m_admins != NULL);
      assert(m_users != NULL);
      assert(m_tariffs != NULL);
 +    assert(m_services != NULL);
 +    assert(m_corporations != NULL);
  
      SP::GET_SERVER_INFO::FACTORY::Register(m_registry, *m_settings, *m_users, *m_tariffs);
  
      SP::CHG_USER::FACTORY::Register(m_registry, *m_users, *m_store, *m_tariffs);
      SP::CHECK_USER::FACTORY::Register(m_registry, *m_users);
  
 +    SP::GET_SERVICES::FACTORY::Register(m_registry, *m_services);
 +    SP::GET_SERVICE::FACTORY::Register(m_registry, *m_services);
 +    SP::ADD_SERVICE::FACTORY::Register(m_registry, *m_services);
 +    SP::DEL_SERVICE::FACTORY::Register(m_registry, *m_services);
 +    SP::CHG_SERVICE::FACTORY::Register(m_registry, *m_services);
 +
      SP::SEND_MESSAGE::FACTORY::Register(m_registry, *m_users);
  
      SP::AUTH_BY::FACTORY::Register(m_registry, *m_users);
 +
 +    SP::USER_INFO::FACTORY::Register(m_registry, *m_users);
  }
  
  int CONFIGPROTO::MaxFD() const
index c464e95ee5c3b76481d0e50e37dfe9cc2f66f2cc,f80735754c6bb951e97258eb27c9b50729488a0d..87a5ef79dc59ef688eb149e77f47ad3da902b438
@@@ -38,8 -38,6 +38,8 @@@ class SETTINGS
  class ADMINS;
  class TARIFFS;
  class USERS;
 +class SERVICES;
 +class CORPORATIONS;
  class STORE;
  class PLUGIN_LOGGER;
  
@@@ -52,23 -50,21 +52,23 @@@ class Conn
  
  class CONFIGPROTO {
  public:
-     CONFIGPROTO(PLUGIN_LOGGER & l);
+     explicit CONFIGPROTO(PLUGIN_LOGGER & l);
      ~CONFIGPROTO();
  
 -    void            SetPort(uint16_t port) { m_port = port; }
 -    void            SetBindAddress(const std::string & address) { m_bindAddress = address; }
 -    void            SetSettings(const SETTINGS * settings) { m_settings = settings; }
 -    void            SetAdmins(ADMINS * admins) { m_admins = admins; }
 -    void            SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
 -    void            SetUsers(USERS * users) { m_users = users; }
 -    void            SetStore(STORE * store) { m_store = store; }
 -
 -    int             Prepare();
 -    int             Stop();
 +    void SetPort(uint16_t port) { m_port = port; }
 +    void SetBindAddress(const std::string & address) { m_bindAddress = address; }
 +    void SetSettings(const SETTINGS * settings) { m_settings = settings; }
 +    void SetAdmins(ADMINS * admins) { m_admins = admins; }
 +    void SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
 +    void SetUsers(USERS * users) { m_users = users; }
 +    void SetStore(STORE * store) { m_store = store; }
 +    void SetServices(SERVICES * services) { m_services = services; }
 +    void SetCorporations(CORPORATIONS * corporations) { m_corporations = corporations; }
 +
 +    int Prepare();
 +    int Stop();
      const std::string & GetStrError() const { return m_errorStr; }
 -    void            Run();
 +    void Run();
  
  private:
      CONFIGPROTO(const CONFIGPROTO & rvalue);
@@@ -78,8 -74,6 +78,8 @@@
      ADMINS *         m_admins;
      TARIFFS *        m_tariffs;
      USERS *          m_users;
 +    SERVICES *       m_services;
 +    CORPORATIONS *   m_corporations;
      STORE *          m_store;
  
      uint16_t         m_port;
      void CleanupConns();
      void HandleEvents(const fd_set & fds);
      void AcceptConnection();
 -
 -    //void WriteLogAccessFailed(uint32_t ip);
  };
  
  #endif //CONFIGPROTO_H
index 359b55e218bab974f07f2bb56a31d0c7695321fc,6f316072c086f886bbc4f588dae4c7a8bfb91644..4c95aa31da4bb9b30e19ba31e34393a5a0c8da0f
@@@ -67,16 -67,6 +67,16 @@@ const int pt_mega = 1024 * 1024
  namespace
  {
  PLUGIN_CREATOR<FILES_STORE> fsc;
 +
 +bool CheckAndCreate(const std::string & dir, mode_t mode)
 +{
 +if (access(dir.c_str(), F_OK) == 0)
 +    return true;
 +if (mkdir(dir.c_str(), mode) == 0)
 +    return true;
 +return false;
 +}
 +
  }
  
  extern "C" STORE * GetStore();
@@@ -254,33 -244,8 +254,33 @@@ if (workDir.size() && workDir[workDir.s
      workDir.resize(workDir.size() - 1);
      }
  usersDir = workDir + "/users/";
 +if (!CheckAndCreate(usersDir, GetConfModeDir()))
 +    {
 +    errorStr = usersDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  tariffsDir = workDir + "/tariffs/";
 +if (!CheckAndCreate(tariffsDir, GetConfModeDir()))
 +    {
 +    errorStr = tariffsDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  adminsDir = workDir + "/admins/";
 +if (!CheckAndCreate(adminsDir, GetConfModeDir()))
 +    {
 +    errorStr = adminsDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
 +servicesDir = workDir + "/services/";
 +if (!CheckAndCreate(servicesDir, GetConfModeDir()))
 +    {
 +    errorStr = servicesDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  
  return 0;
  }
@@@ -445,24 -410,6 +445,24 @@@ STG_LOCKER lock(&mutex)
  
  tariffList->swap(files);
  
 +return 0;
 +}
 +//-----------------------------------------------------------------------------
 +int FILES_STORE::GetServicesList(std::vector<std::string> * list) const
 +{
 +std::vector<std::string> files;
 +
 +if (GetFileList(&files, storeSettings.GetServicesDir(), S_IFREG, ".serv"))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Failed to open '" + storeSettings.GetServicesDir() + "': " + std::string(strerror(errno));
 +    return -1;
 +    }
 +
 +STG_LOCKER lock(&mutex);
 +
 +list->swap(files);
 +
  return 0;
  }
  //-----------------------------------------------------------------------------
@@@ -1524,10 -1471,7 +1524,7 @@@ if (conf.ReadString("ChangePolicy", &st
  else
      td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
  
- if (conf.ReadString("ChangePolicyTimeout", &str, "1970-01-01 00:00:00") < 0)
-     td->tariffConf.changePolicyTimeout = 0;
- else
-     td->tariffConf.changePolicyTimeout = readTime(str);
+ conf.ReadTime("ChangePolicyTimeout", &td->tariffConf.changePolicyTimeout, 0);
  return 0;
  }
  //-----------------------------------------------------------------------------
@@@ -1593,116 -1537,6 +1590,116 @@@ std::string fileName = storeSettings.Ge
      cf.WriteTime("ChangePolicyTimeout", td.tariffConf.changePolicyTimeout);
      }
  
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::AddService(const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +
 +if (Touch(fileName))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Cannot create file " + fileName;
 +    printfd(__FILE__, "FILES_STORE::AddService - failed to add service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::DelService(const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +if (unlink(fileName.c_str()))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "unlink failed. Message: '";
 +    errorStr += strerror(errno);
 +    errorStr += "'";
 +    printfd(__FILE__, "FILES_STORE::DelAdmin - unlink failed. Message: '%s'\n", strerror(errno));
 +    }
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::SaveService(const SERVICE_CONF & conf) const
 +{
 +std::string fileName;
 +
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), conf.name.c_str());
 +
 +    {
 +    CONFIGFILE cf(fileName, true);
 +
 +    int e = cf.Error();
 +
 +    if (e)
 +        {
 +        STG_LOCKER lock(&mutex);
 +        errorStr = "Cannot write service " + conf.name + ". " + fileName;
 +        printfd(__FILE__, "FILES_STORE::SaveService - failed to save service '%s'\n", conf.name.c_str());
 +        return -1;
 +        }
 +
 +    cf.WriteString("name", conf.name);
 +    cf.WriteString("comment", conf.comment);
 +    cf.WriteDouble("cost", conf.cost);
 +    cf.WriteInt("pay_day", conf.payDay);
 +    }
 +
 +return 0;
 +}
 +//-----------------------------------------------------------------------------
 +int FILES_STORE::RestoreService(SERVICE_CONF * conf, const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +CONFIGFILE cf(fileName);
 +
 +if (cf.Error())
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Cannot open " + fileName;
 +    printfd(__FILE__, "FILES_STORE::RestoreService - failed to restore service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadString("name", &conf->name, name))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'name'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - name read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadString("comment", &conf->comment, ""))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'comment'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - comment read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadDouble("cost", &conf->cost, 0.0))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'cost'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - cost read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +unsigned short value = 0;
 +if (cf.ReadUShortInt("pay_day", &value, 0))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'pay_day'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - pay day read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +conf->payDay = value;
 +
  return 0;
  }
  //-----------------------------------------------------------------------------
index de27b72884a8a46d5a3bceca78503f5bac3923f5,9bcce5b0f30bed2dbb9a259d6fa061202c06b40e..113df3ad4ef70cd095e3195dcd2f471ca9037ad7
  #ifndef SETTINGS_IMPL_H
  #define SETTINGS_IMPL_H
  
- #include <string>
- #include <vector>
  #include "stg/settings.h"
  #include "stg/common.h"
  #include "stg/module_settings.h"
  
+ #include <string>
+ #include <vector>
  //-----------------------------------------------------------------------------
  enum DETAIL_STAT_PERIOD {
  dsPeriod_1,
@@@ -57,7 -57,7 +57,7 @@@ class DOTCONFDocumentNode
  //-----------------------------------------------------------------------------
  class SETTINGS_IMPL : public SETTINGS {
  public:
-     SETTINGS_IMPL(const std::string &);
+     explicit SETTINGS_IMPL(const std::string &);
      SETTINGS_IMPL(const SETTINGS_IMPL &);
      virtual ~SETTINGS_IMPL() {}
      SETTINGS_IMPL & operator=(const SETTINGS_IMPL &);
@@@ -84,7 -84,6 +84,7 @@@
      bool                GetSpreadFee() const { return spreadFee; }
      bool                GetFreeMbAllowInet() const { return freeMbAllowInet; }
      bool                GetDayFeeIsLastDay() const { return dayFeeIsLastDay; }
 +    bool                GetStopOnError() const { return stopOnError; }
      bool                GetWriteFreeMbTraffCost() const
          { return writeFreeMbTraffCost; }
      bool                GetShowFeeInCash() const { return showFeeInCash; }
@@@ -133,7 -132,6 +133,7 @@@ private
      bool        spreadFee;
      bool        freeMbAllowInet;
      bool        dayFeeIsLastDay;
 +    bool        stopOnError;
      bool        writeFreeMbTraffCost;
      bool        showFeeInCash;
      unsigned    messageTimeout;
index 0e92975c2c0c064e97d1f8497cd78148aa27b086,d6c749b71c5c635f91c3631e8438e41cd06d72d6..bd3f060770fd0afda8f38678c305e20a19392862
@@@ -134,6 -134,8 +134,8 @@@ USER_IMPL::USER_IMPL(const SETTINGS * s
        userdata7(property.userdata7),
        userdata8(property.userdata8),
        userdata9(property.userdata9),
+       sessionUploadModTime(stgTime),
+       sessionDownloadModTime(stgTime),
        passiveNotifier(this),
        disabledNotifier(this),
        tariffNotifier(this),
@@@ -204,6 -206,8 +206,8 @@@ USER_IMPL::USER_IMPL(const SETTINGS_IMP
        userdata7(property.userdata7),
        userdata8(property.userdata8),
        userdata9(property.userdata9),
+       sessionUploadModTime(stgTime),
+       sessionDownloadModTime(stgTime),
        passiveNotifier(this),
        disabledNotifier(this),
        tariffNotifier(this),
@@@ -298,6 -302,8 +302,8 @@@ USER_IMPL::USER_IMPL(const USER_IMPL & 
        userdata9(property.userdata9),
        sessionUpload(),
        sessionDownload(),
+       sessionUploadModTime(stgTime),
+       sessionDownloadModTime(stgTime),
        passiveNotifier(this),
        disabledNotifier(this),
        tariffNotifier(this),
@@@ -1342,75 -1348,6 +1348,75 @@@ switch (settings->GetFeeChargeType()
  ResetPassiveTime();
  }
  //-----------------------------------------------------------------------------
 +void USER_IMPL::ProcessServices()
 +{
 +struct tm tms;
 +time_t t = stgTime;
 +localtime_r(&t, &tms);
 +
 +double passiveTimePart = 1.0;
 +if (!settings->GetFullFee())
 +    {
 +    passiveTimePart = GetPassiveTimePart();
 +    }
 +else
 +    {
 +    if (passive.ConstData())
 +        {
 +        printfd(__FILE__, "Don't charge fee `cause we are passive\n");
 +        return;
 +        }
 +    }
 +
 +for (size_t i = 0; i < property.Conf().services.size(); ++i)
 +    {
 +    SERVICE_CONF conf;
 +    if (m_services.Find(property.Conf().services[i], &conf))
 +        continue;
 +    if (conf.payDay == tms.tm_mday ||
 +        (conf.payDay == 0 && tms.tm_mday == DaysInCurrentMonth()))
 +        {
 +        double c = cash;
 +        double fee = conf.cost * passiveTimePart;
 +        printfd(__FILE__, "Service fee. login: %8s Cash=%f Credit=%f  Fee=%f PassiveTimePart=%f fee=%f\n",
 +                login.c_str(),
 +                cash.ConstData(),
 +                credit.ConstData(),
 +                tariff->GetFee(),
 +                passiveTimePart,
 +                fee);
 +        switch (settings->GetFeeChargeType())
 +            {
 +            case 0:
 +                property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                SetPrepaidTraff();
 +                break;
 +            case 1:
 +                if (c + credit >= 0)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            case 2:
 +                if (c + credit >= fee)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            case 3:
 +                if (c >= 0)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            }
 +        }
 +    }
 +}
 +//-----------------------------------------------------------------------------
  void USER_IMPL::SetPrepaidTraff()
  {
  if (tariff != NULL)
index 75f02a0e180c6d6db6611ab7f759f9aef71e34d1,8bc696648a0430de96d9bd5ba4a2306151787324..1d4db35f7cdfe1bc9015a73dcddce372d31f780c
@@@ -66,7 -66,7 +66,7 @@@ private
  class CHG_PASSIVE_NOTIFIER : public PROPERTY_NOTIFIER_BASE<int>,
                               private NONCOPYABLE {
  public:
-     CHG_PASSIVE_NOTIFIER(USER_IMPL * u) : user(u) {}
+     explicit CHG_PASSIVE_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const int & oldPassive, const int & newPassive);
  
  private:
@@@ -76,7 -76,7 +76,7 @@@
  class CHG_DISABLED_NOTIFIER : public PROPERTY_NOTIFIER_BASE<int>,
                               private NONCOPYABLE {
  public:
-     CHG_DISABLED_NOTIFIER(USER_IMPL * u) : user(u) {}
+     explicit CHG_DISABLED_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const int & oldValue, const int & newValue);
  
  private:
@@@ -86,7 -86,7 +86,7 @@@
  class CHG_TARIFF_NOTIFIER : public PROPERTY_NOTIFIER_BASE<std::string>,
                              private NONCOPYABLE {
  public:
-     CHG_TARIFF_NOTIFIER(USER_IMPL * u) : user(u) {}
+     explicit CHG_TARIFF_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const std::string & oldTariff, const std::string & newTariff);
  
  private:
@@@ -96,7 -96,7 +96,7 @@@
  class CHG_CASH_NOTIFIER : public PROPERTY_NOTIFIER_BASE<double>,
                            private NONCOPYABLE {
  public:
-     CHG_CASH_NOTIFIER(USER_IMPL * u) : user(u) {}
+     explicit CHG_CASH_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const double & oldCash, const double & newCash);
  
  private:
  class CHG_IPS_NOTIFIER : public PROPERTY_NOTIFIER_BASE<USER_IPS>,
                           private NONCOPYABLE {
  public:
-     CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
+     explicit CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const USER_IPS & oldIPs, const USER_IPS & newIPs);
  
  private:
@@@ -219,7 -219,6 +219,7 @@@ public
      void            ProcessDayFeeSpread();
      void            ProcessNewMonth();
      void            ProcessDailyFee();
 +    void            ProcessServices();
  
      bool            IsInetable();
      std::string     GetEnabledDirs() const;
index 9985615f85d06c58c9d3ba766cb668a224964379,e973d2cd7192197a7744e3ba5a06c9135a5b30a2..ef5e98caa796de93285766a0f13a6c8f876756ff
@@@ -345,7 -345,6 +345,7 @@@ if (store->GetUsersList(&usersList) < 0
  
  user_iter ui;
  
 +unsigned errors = 0;
  for (unsigned int i = 0; i < usersList.size(); i++)
      {
      USER_IMPL u(settings, store, tariffs, sysAdmin, this, m_services);
  
      AddUserIntoIndexes(ui);
  
 -    if (ui->ReadConf() < 0)
 -        return -1;
 +    if (settings->GetStopOnError())
 +        {
 +        if (ui->ReadConf() < 0)
 +            return -1;
 +
 +        if (ui->ReadStat() < 0)
 +            return -1;
 +        }
 +    else
 +        {
 +        if (ui->ReadConf() < 0)
 +            errors++;
  
 -    if (ui->ReadStat() < 0)
 -        return -1;
 +        if (ui->ReadStat() < 0)
 +            errors++;
 +        }
      }
  
 +if (errors > 0)
 +    return -1;
  return 0;
  }
  //-----------------------------------------------------------------------------
@@@ -433,7 -419,7 +433,7 @@@ while (us->nonstop
          {
          //printfd(__FILE__, "Monitor=%d file TRAFFCOUNTER %s\n", tc->monitoring, monFile.c_str());
          touchTime = stgTime;
-         TouchFile(monFile.c_str());
+         TouchFile(monFile);
          }
  
      stgUsleep(100000);
@@@ -517,7 -503,6 +517,7 @@@ els
      }
  
  std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee));
 +std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessServices));
  
  if (settings->GetDayFeeIsLastDay())
      {