]> git.stg.codes - stg.git/commitdiff
Merge branch 'new-daily-fee'
authorMaxim Mamontov <faust.madf@gmail.com>
Mon, 6 Jan 2014 15:51:09 +0000 (17:51 +0200)
committerMaxim Mamontov <faust.madf@gmail.com>
Mon, 6 Jan 2014 15:51:09 +0000 (17:51 +0200)
Conflicts:
include/stg/tariff_conf.h
projects/stargazer/plugins/store/firebird/Makefile
projects/stargazer/plugins/store/firebird/firebird_store.cpp
projects/stargazer/plugins/store/firebird/firebird_store.h
projects/stargazer/plugins/store/mysql/Makefile
projects/stargazer/plugins/store/mysql/mysql_store.cpp
projects/stargazer/plugins/store/mysql/mysql_store.h
projects/stargazer/plugins/store/postgresql/Makefile
projects/stargazer/plugins/store/postgresql/postgresql_store.cpp
projects/stargazer/plugins/store/postgresql/postgresql_store.h
projects/stargazer/plugins/store/postgresql/postgresql_store_tariffs.cpp

14 files changed:
1  2 
include/stg/tariff_conf.h
projects/stargazer/plugins/configuration/sgconfig/parser_tariff.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/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/tariff_impl.h
projects/stargazer/user_impl.cpp
projects/stargazer/user_impl.h
projects/stargazer/users_impl.cpp

index b554e14ac63f761c8c35f192653114fda156bf8e,376ed378e527fc1ed74c0a3d79ba290677661ebb..6a296230d8413e3b148d3969ffc69992fb115ae2
  #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 +103,21 @@@ struct DIRPRICE_DATA_RE
          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;
          }
  
  //-----------------------------------------------------------------------------
  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)
            free(0),
            traffType(TRAFF_UP_DOWN),
            passiveCost(0),
-           name(n)
+           name(n),
+           period(TARIFF::MONTH)
          {}
  };
  //-----------------------------------------------------------------------------
@@@ -165,7 -169,8 +169,8 @@@ struct TARIFF_CONF_RE
            free(),
            traffType(),
            passiveCost(),
-           name()
+           name(),
+           period()
          {}
  
      TARIFF_CONF_RES & operator=(const TARIFF_CONF & tc)
          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.period      = period;
 +        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 +242,7 @@@ struct TARIFF_DATA_RE
            dirPrice(DIR_NUM)
          {}
  
 -    TARIFF_DATA GetData()
 +    TARIFF_DATA GetData() const
          {
          TARIFF_DATA td;
          td.tariffConf = tariffConf.GetData();
index 7be1af9645a0107ff39a0ec839e45780f1817b08,bb855fafc07ba679c057b7bfbda772ae8424f0c6..0e001b224a559fdfee6f94411275387e7ec62926
@@@ -29,7 -29,7 +29,7 @@@ return -1
  //-----------------------------------------------------------------------------
  void PARSER_GET_TARIFFS::CreateAnswer()
  {
 -string s;
 +std::string s;
  char vs[100];
  int hd, hn, md, mn;
  
@@@ -145,6 -145,8 +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>");
@@@ -186,7 -188,7 +188,7 @@@ if (tariffs->Add(tariffToAdd, currAdmin
      }
  else
      {
 -    string s;
 +    std::string s;
      strprintf(&s, "<AddTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
      answerList->push_back(s);
      }
@@@ -222,7 -224,7 +224,7 @@@ answerList->erase(answerList->begin(), 
  
  if (users->TariffInUse(tariffToDel))
      {
 -    string s;
 +    std::string s;
      strprintf(&s, "<DelTariff Result=\"Error. Tariff \'%s\' cannot be deleted. Tariff in use.\"/>", tariffToDel.c_str());
      answerList->push_back(s);
      return;
@@@ -234,7 -236,7 +236,7 @@@ if (tariffs->Del(tariffToDel, currAdmin
      }
  else
      {
 -    string s;
 +    std::string s;
      strprintf(&s, "<DelTariff Result=\"Error. %s\"/>", tariffs->GetStrError().c_str());
      answerList->push_back(s);
      }
  //  CHG TARIFF
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
 -int PARSER_CHG_TARIFF::ParseSlashedIntParams(int paramsNum, const string & s, int * params)
 +int PARSER_CHG_TARIFF::ParseSlashedIntParams(int paramsNum, const std::string & s, int * params)
  {
  char * str = new char[s.size() + 1];
  char * p;
@@@ -272,7 -274,7 +274,7 @@@ delete[] str
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int PARSER_CHG_TARIFF::ParseSlashedDoubleParams(int paramsNum, const string & s, double * params)
 +int PARSER_CHG_TARIFF::ParseSlashedDoubleParams(int paramsNum, const std::string & s, double * params)
  {
  char * str = new char[s.size() + 1];
  char * p;
@@@ -317,7 -319,7 +319,7 @@@ if (depth == 1
      }
  else
      {
 -    string s;
 +    std::string s;
  
      if (strcasecmp(el, "PriceDayA") == 0)
          {
              }
          return 0;
          }
+     if (strcasecmp(el, "Period") == 0)
+         {
+         td.tariffConf.period = TARIFF::StringToPeriod(attr[1]);
+         return 0;
+         }
      }
  return -1;
  }
@@@ -485,7 -493,7 +493,7 @@@ if (!td.tariffConf.name.data().empty()
          }
      else
          {
 -        string s;
 +        std::string s;
          strprintf(&s, "<SetTariff Result=\"Change tariff error! %s\"/>", tariffs->GetStrError().c_str());
          answerList->push_back(s);
          return;
index 0f55b5300adcc4357eeb6ce95748c130833c7255,fa0483a8894213944c1215a694c8eefb4fe82343..0466b82490c97bfd576a2e477a7d0514257ab388
  
  #define adm_enc_passwd "cjeifY8m3"
  
 -using namespace std;
 -
 -int GetFileList(vector<string> * fileList, const string & directory, mode_t mode, const string & ext);
 +int GetFileList(std::vector<std::string> * fileList, const std::string & directory, mode_t mode, const std::string & ext);
  
  const int pt_mega = 1024 * 1024;
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
 +namespace
 +{
  PLUGIN_CREATOR<FILES_STORE> fsc;
 +}
 +
 +extern "C" STORE * GetStore();
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
@@@ -99,11 -96,11 +99,11 @@@ FILES_STORE_SETTINGS::FILES_STORE_SETTI
  {
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE_SETTINGS::ParseOwner(const vector<PARAM_VALUE> & moduleParams, const string & owner, uid_t * uid)
 +int FILES_STORE_SETTINGS::ParseOwner(const std::vector<PARAM_VALUE> & moduleParams, const std::string & owner, uid_t * uid)
  {
  PARAM_VALUE pv;
  pv.param = owner;
 -vector<PARAM_VALUE>::const_iterator pvi;
 +std::vector<PARAM_VALUE>::const_iterator pvi;
  pvi = find(moduleParams.begin(), moduleParams.end(), pv);
  if (pvi == moduleParams.end())
      {
@@@ -120,11 -117,11 +120,11 @@@ if (User2UID(pvi->value[0].c_str(), uid
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE_SETTINGS::ParseGroup(const vector<PARAM_VALUE> & moduleParams, const string & group, gid_t * gid)
 +int FILES_STORE_SETTINGS::ParseGroup(const std::vector<PARAM_VALUE> & moduleParams, const std::string & group, gid_t * gid)
  {
  PARAM_VALUE pv;
  pv.param = group;
 -vector<PARAM_VALUE>::const_iterator pvi;
 +std::vector<PARAM_VALUE>::const_iterator pvi;
  pvi = find(moduleParams.begin(), moduleParams.end(), pv);
  if (pvi == moduleParams.end())
      {
@@@ -141,7 -138,7 +141,7 @@@ if (Group2GID(pvi->value[0].c_str(), gi
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE_SETTINGS::ParseYesNo(const string & value, bool * val)
 +int FILES_STORE_SETTINGS::ParseYesNo(const std::string & value, bool * val)
  {
  if (0 == strcasecmp(value.c_str(), "yes"))
      {
@@@ -158,11 -155,11 +158,11 @@@ errorStr = "Incorrect value \'" + valu
  return -1;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE_SETTINGS::ParseMode(const vector<PARAM_VALUE> & moduleParams, const string & modeStr, mode_t * mode)
 +int FILES_STORE_SETTINGS::ParseMode(const std::vector<PARAM_VALUE> & moduleParams, const std::string & modeStr, mode_t * mode)
  {
  PARAM_VALUE pv;
  pv.param = modeStr;
 -vector<PARAM_VALUE>::const_iterator pvi;
 +std::vector<PARAM_VALUE>::const_iterator pvi;
  pvi = find(moduleParams.begin(), moduleParams.end(), pv);
  if (pvi == moduleParams.end())
      {
@@@ -202,7 -199,7 +202,7 @@@ if (ParseGroup(s.moduleParams, "UserLog
  if (ParseMode(s.moduleParams, "UserLogMode", &userLogMode) < 0)
      return -1;
  
 -vector<PARAM_VALUE>::const_iterator pvi;
 +std::vector<PARAM_VALUE>::const_iterator pvi;
  PARAM_VALUE pv;
  pv.param = "RemoveBak";
  pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
@@@ -255,7 -252,7 +255,7 @@@ adminsDir = workDir + "/admins/"
  return 0;
  }
  //-----------------------------------------------------------------------------
 -const string & FILES_STORE_SETTINGS::GetStrError() const
 +const std::string & FILES_STORE_SETTINGS::GetStrError() const
  {
  return errorStr;
  }
@@@ -266,7 -263,7 +266,7 @@@ struct passwd * pw
  pw = getpwnam(user);
  if (!pw)
      {
 -    errorStr = string("User \'") + string(user) + string("\' not found in system.");
 +    errorStr = std::string("User \'") + std::string(user) + std::string("\' not found in system.");
      printfd(__FILE__, "%s\n", errorStr.c_str());
      return -1;
      }
@@@ -281,7 -278,7 +281,7 @@@ struct group * grp
  grp = getgrnam(gr);
  if (!grp)
      {
 -    errorStr = string("Group \'") + string(gr) + string("\' not found in system.");
 +    errorStr = std::string("Group \'") + std::string(gr) + std::string("\' not found in system.");
      printfd(__FILE__, "%s\n", errorStr.c_str());
      return -1;
      }
@@@ -297,7 -294,7 +297,7 @@@ char b
  char c;
  if (strlen(str) > 3)
      {
 -    errorStr = string("Error parsing mode \'") + str + string("\'");
 +    errorStr = std::string("Error parsing mode \'") + str + std::string("\'");
      printfd(__FILE__, "%s\n", errorStr.c_str());
      return -1;
      }
  for (int i = 0; i < 3; i++)
      if (str[i] > '7' || str[i] < '0')
          {
 -        errorStr = string("Error parsing mode \'") + str + string("\'");
 +        errorStr = std::string("Error parsing mode \'") + str + std::string("\'");
          printfd(__FILE__, "%s\n", errorStr.c_str());
          return -1;
          }
@@@ -344,14 -341,13 +344,14 @@@ FILES_STORE::FILES_STORE(
        version("file_store v.1.04"),
        storeSettings(),
        settings(),
 -      mutex()
 +      mutex(),
 +      logger(GetPluginLogger(GetStgLogger(), "store_files"))
  {
  pthread_mutexattr_t attr;
  pthread_mutexattr_init(&attr);
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&mutex, &attr);
 -};
 +}
  //-----------------------------------------------------------------------------
  int FILES_STORE::ParseSettings()
  {
@@@ -364,14 -360,14 +364,14 @@@ if (ret
  return ret;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::GetUsersList(vector<string> * userList) const
 +int FILES_STORE::GetUsersList(std::vector<std::string> * userList) const
  {
 -vector<string> files;
 +std::vector<std::string> files;
  
  if (GetFileList(&files, storeSettings.GetUsersDir(), S_IFDIR, ""))
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = "Failed to open '" + storeSettings.GetUsersDir() + "': " + string(strerror(errno));
 +    errorStr = "Failed to open '" + storeSettings.GetUsersDir() + "': " + std::string(strerror(errno));
      return -1;
      }
  
@@@ -382,14 -378,14 +382,14 @@@ userList->swap(files)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::GetAdminsList(vector<string> * adminList) const
 +int FILES_STORE::GetAdminsList(std::vector<std::string> * adminList) const
  {
 -vector<string> files;
 +std::vector<std::string> files;
  
  if (GetFileList(&files, storeSettings.GetAdminsDir(), S_IFREG, ".adm"))
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = "Failed to open '" + storeSettings.GetAdminsDir() + "': " + string(strerror(errno));
 +    errorStr = "Failed to open '" + storeSettings.GetAdminsDir() + "': " + std::string(strerror(errno));
      return -1;
      }
  
@@@ -400,14 -396,14 +400,14 @@@ adminList->swap(files)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::GetTariffsList(vector<string> * tariffList) const
 +int FILES_STORE::GetTariffsList(std::vector<std::string> * tariffList) const
  {
 -vector<string> files;
 +std::vector<std::string> files;
  
  if (GetFileList(&files, storeSettings.GetTariffsDir(), S_IFREG, ".tf"))
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = "Failed to open '" + storeSettings.GetTariffsDir() + "': " + string(strerror(errno));
 +    errorStr = "Failed to open '" + storeSettings.GetTariffsDir() + "': " + std::string(strerror(errno));
      return -1;
      }
  
@@@ -437,8 -433,8 +437,8 @@@ while ((entry = readdir(d))
      if (!(strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")))
          continue;
  
 -    string str = path;
 -    str += "/" + string(entry->d_name);
 +    std::string str = path;
 +    str += "/" + std::string(entry->d_name);
  
      struct stat st;
      if (stat(str.c_str(), &st))
@@@ -484,16 -480,16 +484,16 @@@ if (rmdir(path)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::AddUser(const string & login) const
 +int FILES_STORE::AddUser(const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  
  strprintf(&fileName, "%s%s", storeSettings.GetUsersDir().c_str(), login.c_str());
  
  if (mkdir(fileName.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = string("mkdir failed. Message: '") + strerror(errno) + "'";
 +    errorStr = std::string("mkdir failed. Message: '") + strerror(errno) + "'";
      printfd(__FILE__, "FILES_STORE::AddUser - mkdir failed. Message: '%s'\n", strerror(errno));
      return -1;
      }
@@@ -518,12 -514,12 +518,12 @@@ if (Touch(fileName)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::DelUser(const string & login) const
 +int FILES_STORE::DelUser(const std::string & login) const
  {
 -string dirName;
 -string dirName1;
 +std::string dirName;
 +std::string dirName1;
  
 -strprintf(&dirName, "%s/"DELETED_USERS_DIR, storeSettings.GetWorkDir().c_str());
 +strprintf(&dirName, "%s/%s", storeSettings.GetWorkDir().c_str(), DELETED_USERS_DIR);
  if (access(dirName.c_str(), F_OK) != 0)
      {
      if (mkdir(dirName.c_str(), 0700) != 0)
  
  if (access(dirName.c_str(), F_OK) == 0)
      {
 -    strprintf(&dirName, "%s/"DELETED_USERS_DIR"/%s.%lu", storeSettings.GetWorkDir().c_str(), login.c_str(), time(NULL));
 +    strprintf(&dirName, "%s/%s/%s.%lu", storeSettings.GetWorkDir().c_str(), DELETED_USERS_DIR, login.c_str(), time(NULL));
      strprintf(&dirName1, "%s/%s", storeSettings.GetUsersDir().c_str(), login.c_str());
      if (rename(dirName1.c_str(), dirName.c_str()))
          {
@@@ -558,9 -554,9 +558,9 @@@ els
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreUserConf(USER_CONF * conf, const string & login) const
 +int FILES_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
  if (RestoreUserConf(conf, login, fileName))
      {
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreUserConf(USER_CONF * conf, const string & login, const string & fileName) const
 +int FILES_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login, const std::string & fileName) const
  {
  CONFIGFILE cf(fileName);
  int e = cf.Error();
 -string str;
 +std::string str;
  
  if (e)
      {
@@@ -617,21 -613,21 +617,21 @@@ if (conf->tariffName.empty()
      return -1;
      }
  
 -string ipStr;
 +std::string ipStr;
  cf.ReadString("IP", &ipStr, "?");
 -USER_IPS i;
 +USER_IPS ips;
  try
      {
 -    i = StrToIPS(ipStr);
 +    ips = StrToIPS(ipStr);
      }
 -catch (const string & s)
 +catch (const std::string & s)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
      errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
      printfd(__FILE__, "FILES_STORE::RestoreUserConf - ip read failed for user '%s'\n", login.c_str());
      return -1;
      }
 -conf->ips = i;
 +conf->ips = ips;
  
  if (cf.ReadInt("alwaysOnline", &conf->alwaysOnline, 0) != 0)
      {
@@@ -685,9 -681,9 +685,9 @@@ if (cf.ReadDouble("Credit", &conf->cred
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreUserStat(USER_STAT * stat, const string & login) const
 +int FILES_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
  
  if (RestoreUserStat(stat, login, fileName))
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreUserStat(USER_STAT * stat, const string & login, const string & fileName) const
 +int FILES_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login, const std::string & fileName) const
  {
  CONFIGFILE cf(fileName);
  
@@@ -724,21 -720,21 +724,21 @@@ for (int i = 0; i < DIR_NUM; i++
      if (cf.ReadULongLongInt(s, &traff, 0) != 0)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = "User \'" + login + "\' stat not read. Parameter " + string(s);
 +        errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
          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)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr =   "User \'" + login + "\' stat not read. Parameter " + string(s);
 +        errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
          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)
@@@ -792,9 -788,9 +792,9 @@@ if (cf.ReadTime("LastActivityTime", &st
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::SaveUserConf(const USER_CONF & conf, const string & login) const
 +int FILES_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
  
  CONFIGFILE cfstat(fileName, true);
@@@ -804,7 -800,7 +804,7 @@@ int e = cfstat.Error()
  if (e)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = string("User \'") + login + "\' conf not written\n";
 +    errorStr = std::string("User \'") + login + "\' conf not written\n";
      printfd(__FILE__, "FILES_STORE::SaveUserConf - conf write failed for user '%s'\n", login.c_str());
      return -1;
      }
@@@ -841,17 -837,17 +841,17 @@@ for (int i = 0; i < USERDATA_NUM; i++
      }
  cfstat.WriteInt("CreditExpire",    conf.creditExpire);
  
 -stringstream ipStr;
 +std::ostringstream ipStr;
  ipStr << conf.ips;
  cfstat.WriteString("IP", ipStr.str());
  
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::SaveUserStat(const USER_STAT & stat, const string & login) const
 +int FILES_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
  {
  char s[22];
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
  
      {
      if (e)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = string("User \'") + login + "\' stat not written\n";
 +        errorStr = std::string("User \'") + login + "\' stat not written\n";
          printfd(__FILE__, "FILES_STORE::SaveUserStat - stat write failed for user '%s'\n", login.c_str());
          return -1;
          }
      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);
@@@ -894,11 -890,11 +894,11 @@@ if (e
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteLogString(const string & str, const string & login) const
 +int FILES_STORE::WriteLogString(const std::string & str, const std::string & login) const
  {
  FILE * f;
  time_t tm = time(NULL);
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/log";
  f = fopen(fileName.c_str(), "at");
  
@@@ -930,11 -926,11 +930,11 @@@ if (e
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteLog2String(const string & str, const string & login) const
 +int FILES_STORE::WriteLog2String(const std::string & str, const std::string & login) const
  {
  FILE * f;
  time_t tm = time(NULL);
 -string fileName;
 +std::string fileName;
  fileName = storeSettings.GetUsersDir() + "/" + login + "/log2";
  f = fopen(fileName.c_str(), "at");
  
@@@ -966,48 -962,48 +966,48 @@@ if (e
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteUserChgLog(const string & login,
 -                                 const string & admLogin,
 +int FILES_STORE::WriteUserChgLog(const std::string & login,
 +                                 const std::string & admLogin,
                                   uint32_t       admIP,
 -                                 const string & paramName,
 -                                 const string & oldValue,
 -                                 const string & newValue,
 -                                 const string & message) const
 +                                 const std::string & paramName,
 +                                 const std::string & oldValue,
 +                                 const std::string & newValue,
 +                                 const std::string & message) const
  {
 -string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
 +std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
      + paramName + "\' parameter changed from \'" + oldValue +
      "\' to \'" + newValue + "\'. " + message;
  
  return WriteLogString(userLogMsg, login);
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteUserConnect(const string & login, uint32_t ip) const
 +int FILES_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
  {
 -string logStr = "Connect, " + inet_ntostring(ip);
 +std::string logStr = "Connect, " + inet_ntostring(ip);
  if (WriteLogString(logStr, login))
      return -1;
  return WriteLog2String(logStr, login);
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteUserDisconnect(const string & login,
 -                                     const DIR_TRAFF & up,
 -                                     const DIR_TRAFF & down,
 +int FILES_STORE::WriteUserDisconnect(const std::string & login,
 +                                     const DIR_TRAFF & monthUp,
 +                                     const DIR_TRAFF & monthDown,
                                       const DIR_TRAFF & sessionUp,
                                       const DIR_TRAFF & sessionDown,
                                       double cash,
                                       double freeMb,
                                       const std::string & reason) const
  {
 -stringstream logStr;
 +std::ostringstream logStr;
  logStr << "Disconnect, "
         << " session upload: \'"
         << sessionUp
         << "\' session download: \'"
         << sessionDown
         << "\' month upload: \'"
 -       << up
 +       << monthUp
         << "\' month download: \'"
 -       << down
 +       << monthDown
         << "\' cash: \'"
         << cash
         << "\'";
@@@ -1025,10 -1021,10 +1025,10 @@@ logStr << " freeMb: \'
  return WriteLog2String(logStr.str(), login);
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const
 +int FILES_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const
  {
  // Classic stats
 -string stat1;
 +std::string stat1;
  strprintf(&stat1,"%s/%s/stat.%d.%02d",
          storeSettings.GetUsersDir().c_str(), login.c_str(), year + 1900, month + 1);
  
@@@ -1043,7 -1039,7 +1043,7 @@@ if (s.Error()
      }
  
  // New stats
 -string stat2;
 +std::string stat2;
  strprintf(&stat2,"%s/%s/stat2.%d.%02d",
          storeSettings.GetUsersDir().c_str(), login.c_str(), year + 1900, month + 1);
  
@@@ -1061,11 -1057,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
@@@ -1082,9 -1078,9 +1082,9 @@@ s2.WriteInt("LastActivityTime", stat.la
  return 0;
  }
  //-----------------------------------------------------------------------------*/
 -int FILES_STORE::AddAdmin(const string & login) const
 +int FILES_STORE::AddAdmin(const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
  
  if (Touch(fileName))
  return 0;
  }
  //-----------------------------------------------------------------------------*/
 -int FILES_STORE::DelAdmin(const string & login) const
 +int FILES_STORE::DelAdmin(const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
  if (unlink(fileName.c_str()))
      {
@@@ -1119,7 -1115,7 +1119,7 @@@ char passwordE[2 * ADM_PASSWD_LEN + 2]
  char pass[ADM_PASSWD_LEN + 1];
  char adminPass[ADM_PASSWD_LEN + 1];
  
 -string fileName;
 +std::string fileName;
  
  strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), ac.login.c_str());
  
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreAdmin(ADMIN_CONF * ac, const string & login) const
 +int FILES_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
  CONFIGFILE cf(fileName);
  char pass[ADM_PASSWD_LEN + 1];
@@@ -1178,7 -1174,7 +1178,7 @@@ char password[ADM_PASSWD_LEN + 1]
  char passwordE[2 * ADM_PASSWD_LEN + 2];
  BLOWFISH_CTX ctx;
  
 -string p;
 +std::string p;
  
  if (cf.Error())
      {
      return -1;
      }
  
 -int a;
 -
  if (cf.ReadString("password", &p, "*"))
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
@@@ -1218,9 -1216,7 +1218,9 @@@ els
  
  ac->password = password;
  
 -if (cf.ReadInt("ChgConf", &a, 0) == 0)
 +uint16_t a;
 +
 +if (cf.ReadUShortInt("ChgConf", &a, 0) == 0)
      ac->priv.userConf = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgPassword", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgPassword", &a, 0) == 0)
      ac->priv.userPasswd = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgStat", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgStat", &a, 0) == 0)
      ac->priv.userStat = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgCash", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgCash", &a, 0) == 0)
      ac->priv.userCash = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("UsrAddDel", &a, 0) == 0)
 +if (cf.ReadUShortInt("UsrAddDel", &a, 0) == 0)
      ac->priv.userAddDel = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgAdmin", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgAdmin", &a, 0) == 0)
      ac->priv.adminChg = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgTariff", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgTariff", &a, 0) == 0)
      ac->priv.tariffChg = a;
  else
      {
      return -1;
      }
  
 -if (cf.ReadInt("ChgService", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgService", &a, 0) == 0)
      ac->priv.serviceChg = a;
  else
      ac->priv.serviceChg = 0;
  
 -if (cf.ReadInt("ChgCorp", &a, 0) == 0)
 +if (cf.ReadUShortInt("ChgCorp", &a, 0) == 0)
      ac->priv.corpChg = a;
  else
      ac->priv.corpChg = 0;
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::AddTariff(const string & name) const
 +int FILES_STORE::AddTariff(const std::string & name) const
  {
 -string fileName;
 +std::string fileName;
  strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
  if (Touch(fileName))
      {
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::DelTariff(const string & name) const
 +int FILES_STORE::DelTariff(const std::string & name) const
  {
 -string fileName;
 +std::string fileName;
  strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
  if (unlink(fileName.c_str()))
      {
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::RestoreTariff(TARIFF_DATA * td, const string & tariffName) const
 +int FILES_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
  {
 -string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
 +std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
  CONFIGFILE conf(fileName);
 -string str;
 +std::string str;
  td->tariffConf.name = tariffName;
  
  if (conf.Error() != 0)
      return -1;
      }
  
 -string param;
 +std::string param;
  for (int i = 0; i<DIR_NUM; i++)
      {
      strprintf(&param, "Time%d", i);
                  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;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::SaveTariff(const TARIFF_DATA & td, const string & tariffName) const
 +int FILES_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
  {
 -string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
 +std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
  
      {
      CONFIGFILE cf(fileName, true);
          return e;
          }
  
 -    string param;
 +    std::string param;
      for (int i = 0; i < DIR_NUM; i++)
          {
          strprintf(&param, "PriceDayA%d", i);
          strprintf(&param, "Threshold%d", i);
          cf.WriteInt(param, td.dirPrice[i].threshold);
  
 -        string s;
 +        std::string s;
          strprintf(&param, "Time%d", i);
  
          strprintf(&s, "%0d:%0d-%0d:%0d",
              cf.WriteString("TraffType", "max");
              break;
          }
+     cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period));
      }
  
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> & statTree,
 +int FILES_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
                                     time_t lastStat,
 -                                   const string & login) const
 +                                   const std::string & login) const
  {
  char fn[FN_STR_LEN];
  char dn[FN_STR_LEN];
@@@ -1581,7 -1584,7 +1588,7 @@@ if (access(dn, F_OK) != 0
      if (mkdir(dn, 0700) != 0)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
 +        errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
          printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
          return -1;
          }
@@@ -1614,7 -1617,7 +1621,7 @@@ if (access(dn, F_OK) != 0
      if (mkdir(dn, 0700) != 0)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
 +        errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
          printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
          return -1;
          }
@@@ -1640,7 -1643,7 +1647,7 @@@ if (access(dn, F_OK) != 0
      if (mkdir(dn, 0700) != 0)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
 +        errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
          printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
          return -1;
          }
@@@ -1662,7 -1665,7 +1669,7 @@@ statFile = fopen (fn, "at")
  if (!statFile)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = "File \'" + string(fn) + "\' cannot be written.";
 +    errorStr = "File \'" + std::string(fn) + "\' cannot be written.";
      printfd(__FILE__, "FILES_STORE::WriteDetailStat - fopen failed. Message: '%s'\n", strerror(errno));
      return -1;
      }
@@@ -1689,18 -1692,18 +1696,18 @@@ if (fprintf(statFile, "-> %02d.%02d.%02
              h1, m1, s1, h2, m2, s2) < 0)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = string("fprint failed. Message: '") + strerror(errno) + "'";
 +    errorStr = std::string("fprint failed. Message: '") + strerror(errno) + "'";
      printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
      fclose(statFile);
      return -1;
      }
  
 -map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
 +std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
  stIter = statTree.begin();
  
  while (stIter != statTree.end())
      {
 -    string u, d;
 +    std::string u, d;
      x2str(stIter->second.up, u);
      x2str(stIter->second.down, d);
      #ifdef TRAFF_STAT_WITH_PORTS
                  stIter->second.cash) < 0)
          {
          STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -        errorStr = string("fprint failed. Message: '");
 +        errorStr = std::string("fprint failed. Message: '");
          errorStr += strerror(errno);
          errorStr += "'";
          printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
@@@ -1755,10 -1758,10 +1762,10 @@@ if (e
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::AddMessage(STG_MSG * msg, const string & login) const
 +int FILES_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
  {
 -string fn;
 -string dn;
 +std::string fn;
 +std::string dn;
  struct timeval tv;
  
  strprintf(&dn, "%s/%s/messages", storeSettings.GetUsersDir().c_str(), login.c_str());
@@@ -1795,16 -1798,16 +1802,16 @@@ if (Touch(fn)
  return EditMessage(*msg, login);
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::EditMessage(const STG_MSG & msg, const string & login) const
 +int FILES_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
  {
 -string fileName;
 +std::string fileName;
  
  FILE * msgFile;
  strprintf(&fileName, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), msg.header.id);
  
  if (access(fileName.c_str(), F_OK) != 0)
      {
 -    string idstr;
 +    std::string idstr;
      x2str(msg.header.id, idstr);
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
      errorStr = "Message for user \'";
@@@ -1837,7 -1840,7 +1844,7 @@@ res &= (fprintf(msgFile, "%s", msg.text
  if (!res)
      {
      STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -    errorStr = string("fprintf failed. Message: '") + strerror(errno) + "'";
 +    errorStr = std::string("fprintf failed. Message: '") + strerror(errno) + "'";
      printfd(__FILE__, "FILES_STORE::EditMessage - fprintf failed. Message: '%s'\n", strerror(errno));
      fclose(msgFile);
      return -1;
@@@ -1851,39 -1854,39 +1858,39 @@@ if (rename((fileName + ".new").c_str()
      {
      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;
      }
  
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::GetMessage(uint64_t id, STG_MSG * msg, const string & login) const
 +int FILES_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
  {
 -string fn;
 +std::string fn;
  strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
  msg->header.id = id;
  return ReadMessage(fn, &msg->header, &msg->text);
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::DelMessage(uint64_t id, const string & login) const
 +int FILES_STORE::DelMessage(uint64_t id, const std::string & login) const
  {
 -string fn;
 +std::string fn;
  strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
  
  return unlink(fn.c_str());
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::GetMessageHdrs(vector<STG_MSG_HDR> * hdrsList, const string & login) const
 +int FILES_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
  {
 -string dn(storeSettings.GetUsersDir() + "/" + login + "/messages/");
 +std::string dn(storeSettings.GetUsersDir() + "/" + login + "/messages/");
  
  if (access(dn.c_str(), F_OK) != 0)
      {
      return 0;
      }
  
 -vector<string> messages;
 +std::vector<std::string> messages;
  GetFileList(&messages, dn, S_IFREG, "");
  
  for (unsigned i = 0; i < messages.size(); i++)
          if (unlink((dn + messages[i]).c_str()))
              {
              STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -            errorStr = string("unlink failed. Message: '") + strerror(errno) + "'";
 +            errorStr = std::string("unlink failed. Message: '") + strerror(errno) + "'";
              printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
              return -1;
              }
          if (unlink((dn + messages[i]).c_str()))
              {
              STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -            errorStr = string("unlink failed. Message: '") + strerror(errno) + "'";
 +            errorStr = std::string("unlink failed. Message: '") + strerror(errno) + "'";
              printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
              return -1;
              }
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FILES_STORE::ReadMessage(const string & fileName,
 +int FILES_STORE::ReadMessage(const std::string & fileName,
                               STG_MSG_HDR * hdr,
 -                             string * text) const
 +                             std::string * text) const
  {
  FILE * msgFile;
  msgFile = fopen(fileName.c_str(), "rt");
@@@ -2027,7 -2030,7 +2034,7 @@@ if (f
  return -1;
  }
  //-----------------------------------------------------------------------------
 -int GetFileList(vector<string> * fileList, const string & directory, mode_t mode, const string & ext)
 +int GetFileList(std::vector<std::string> * fileList, const std::string & directory, mode_t mode, const std::string & ext)
  {
  DIR * d = opendir(directory.c_str());
  
@@@ -2043,7 -2046,7 +2050,7 @@@ while ((entry = readdir(d))
      if (!(strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")))
          continue;
  
 -    string str = directory + "/" + string(entry->d_name);
 +    std::string str = directory + "/" + std::string(entry->d_name);
  
      struct stat st;
      if (stat(str.c_str(), &st))
index 7e57483e24c349a380722fbbe54236797577cfa9,8bddf9ca6c329537f614a02ae44d2c098b5b9468..8e3c9d90f0432bd70c0c716c04a1e37a14677682
   *
   */
  
 -#include <string>
 -#include <vector>
 -#include <algorithm>
 +#include "firebird_store.h"
  
  #include "stg/ibpp.h"
  #include "stg/plugin_creator.h"
 -#include "stg/logger.h"
 -#include "firebird_store.h"
  
 -using namespace std;
 +#include <string>
 +#include <vector>
 +#include <algorithm>
 +
 +#include <cctype>
  
 +namespace
 +{
  PLUGIN_CREATOR<FIREBIRD_STORE> frsc;
 +}
 +
 +extern "C" STORE * GetStore();
  //-----------------------------------------------------------------------------
  STORE * GetStore()
  {
@@@ -63,7 -58,8 +63,7 @@@ FIREBIRD_STORE::FIREBIRD_STORE(
        mutex(),
        til(IBPP::ilConcurrency),
        tlr(IBPP::lrWait),
 -      schemaVersion(0),
 -      WriteServLog(GetStgLogger())
 +      logger(GetPluginLogger(GetStgLogger(), "store_firebird"))
  {
  pthread_mutex_init(&mutex, NULL);
  }
@@@ -75,47 -71,61 +75,47 @@@ db->Disconnect()
  //-----------------------------------------------------------------------------
  int FIREBIRD_STORE::ParseSettings()
  {
 -vector<PARAM_VALUE>::iterator i;
 -string s;
 +std::vector<PARAM_VALUE>::iterator i;
 +std::string s;
  
  for(i = settings.moduleParams.begin(); i != settings.moduleParams.end(); ++i)
      {
      s = i->param;
 -    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;
 -            }
          }
      }
  
@@@ -123,6 -133,7 +123,7 @@@ tr
      {
      db = IBPP::DatabaseFactory(db_server, db_database, db_user, db_password, "", "KOI8U", "");
      db->Connect();
+     return CheckVersion();
      }
  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);
+ 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();
+     WriteServLog("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,a5905fefa8438570e7e2606cf2f9571a0c328a1c..688f0e88651da56258aad827b29d4ff92a21c6d7
  #include <ctime>
  #include <string>
  #include <vector>
 -#include <map>
  
  #include "stg/store.h"
  #include "stg/locker.h"
  #include "stg/ibpp.h"
 +#include "stg/logger.h"
  
  struct ToLower {
 -    char operator() (char c) const  { return std::tolower(c); }
 +    char operator() (char c) const  { return static_cast<char>(std::tolower(c)); }
  };
  
 -extern "C" STORE * GetStore();
 -
 -class STG_LOGGER;
 -
  class FIREBIRD_STORE : public STORE {
  public:
      FIREBIRD_STORE();
@@@ -90,7 -94,7 +90,7 @@@
  
      int GetTariffsList(std::vector<std::string> * tariffsList) const;
      int AddTariff(const std::string & name) const;
 -    int DelTariff(const string & name) const;
 +    int DelTariff(const std::string & name) const;
      int SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const;
      int RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const;
  
      int AddCorp(const std::string & name) const;
      int DelCorp(const std::string & name) const;
  
 -    inline void SetSettings(const MODULE_SETTINGS & s) { settings = s; };
 +    inline void SetSettings(const MODULE_SETTINGS & s) { settings = s; }
      int ParseSettings();
  
 -    inline const string & GetStrError() const { return strError; };
 +    inline const std::string & GetStrError() const { return strError; }
  
 -    inline const string & GetVersion() const { return version; };
 +    inline const std::string & GetVersion() const { return version; }
  
      int GetServicesList(std::vector<std::string> * servicesList) const;
      int SaveService(const SERVICE_CONF & sc) const;
@@@ -119,15 -123,17 +119,17 @@@ private
  
      std::string version;
      mutable std::string strError;
 -    mutable std::string db_server, db_database, db_user, db_password;
 +    std::string db_server, db_database, db_user, db_password;
      MODULE_SETTINGS settings;
      mutable IBPP::Database db;
      mutable pthread_mutex_t mutex;
 -    mutable IBPP::TIL til;
 -    mutable IBPP::TLR tlr;
 +    IBPP::TIL til;
 +    IBPP::TLR tlr;
+     int schemaVersion;
 -    STG_LOGGER & WriteServLog;
 +    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,e6ebd45f54bfe93f815f3e90d84af9b00ed86e2f..325e7d7f10b48c79978a04f52655f65a4f9d653c
   *
   */
  
 +#include <cmath>
 +
  #include "firebird_store.h"
  #include "stg/ibpp.h"
  
  //-----------------------------------------------------------------------------
 -int FIREBIRD_STORE::GetTariffsList(vector<string> * tariffsList) const
 +int FIREBIRD_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
  IBPP::Transaction tr = IBPP::TransactionFactory(db, IBPP::amRead, til, tlr);
  IBPP::Statement st = IBPP::StatementFactory(db, tr);
  
 -string name;
 +std::string name;
  
  try
      {
@@@ -64,7 -62,7 +64,7 @@@ catch (IBPP::Exception & ex
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FIREBIRD_STORE::AddTariff(const string & name) const
 +int FIREBIRD_STORE::AddTariff(const std::string & name) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -92,7 -90,7 +92,7 @@@ catch (IBPP::Exception & ex
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int FIREBIRD_STORE::DelTariff(const string & name) const
 +int FIREBIRD_STORE::DelTariff(const std::string & name) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -120,7 -118,7 +120,7 @@@ return 0
  }
  //-----------------------------------------------------------------------------
  int FIREBIRD_STORE::SaveTariff(const TARIFF_DATA & td,
 -                               const string & tariffName) const
 +                               const std::string & tariffName) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -146,17 -144,36 +146,36 @@@ tr
      }
      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();
  
              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);
@@@ -228,7 -245,7 +247,7 @@@ return 0
  }
  //-----------------------------------------------------------------------------
  int FIREBIRD_STORE::RestoreTariff(TARIFF_DATA * td,
 -                                  const string & tariffName) const
 +                                  const std::string & tariffName) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -246,7 -263,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())
      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);
      st->Get(7, td->dirPrice[dir].priceNightB);
      td->dirPrice[dir].priceNightB /= 1024*1024;
      st->Get(8, td->dirPrice[dir].threshold);
 -    if (td->dirPrice[dir].priceDayA == td->dirPrice[dir].priceNightA &&
 -        td->dirPrice[dir].priceDayB == td->dirPrice[dir].priceNightB)
 +    if (std::fabs(td->dirPrice[dir].priceDayA - td->dirPrice[dir].priceNightA) < 1.0e-3 &&
 +        std::fabs(td->dirPrice[dir].priceDayB - td->dirPrice[dir].priceNightB) < 1.0e-3)
          {
          td->dirPrice[dir].singlePrice = true;
          }
index b4ac87155a762d5510d4700f624decf959956fd2,95ac298d732529891e18de18844a56df3b3518ca..11c2def3b5c1d2ca0dc3b82fb036fa6afcc00e71
@@@ -2,6 -2,7 +2,6 @@@
  #include <cerrno>
  #include <cstdio>
  #include <cstdlib>
 -#include <string>
  #include <algorithm>
  
  #include <mysql.h>
  #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"
 -char qbuf[4096];
  
 -using namespace std;
 +namespace
 +{
 +char qbuf[4096];
  
  const int pt_mega = 1024 * 1024;
 -const string badSyms = "'`";
 +const std::string badSyms = "'`";
  const char repSym = '\"';
  const int RepitTimes = 3;
  
 -int GetInt(const string & str, int * val, int defaultVal)
 +template <typename T>
 +int GetInt(const std::string & str, T * val, T defaultVal = T())
  {
      char *res;
      
 -    *val = strtol(str.c_str(), &res, 10);
 +    *val = static_cast<T>(strtoll(str.c_str(), &res, 10));
      
      if (*res != 0) 
      {
@@@ -41,7 -41,7 +42,7 @@@
      return 0;
  }
  
 -int GetDouble(const string & str, double * val, double defaultVal)
 +int GetDouble(const std::string & str, double * val, double defaultVal)
  {
      char *res;
      
@@@ -56,7 -56,7 +57,7 @@@
      return 0;
  }
  
 -int GetTime(const string & str, time_t * val, time_t defaultVal)
 +int GetTime(const std::string & str, time_t * val, time_t defaultVal)
  {
      char *res;
      
  }
  
  //-----------------------------------------------------------------------------
 -string ReplaceStr(string source, const string symlist, const char chgsym)
 +std::string ReplaceStr(std::string source, const std::string symlist, const char chgsym)
  {
 -    string::size_type pos=0;
 +    std::string::size_type pos=0;
  
 -    while( (pos = source.find_first_of(symlist,pos)) != string::npos)
 +    while( (pos = source.find_first_of(symlist,pos)) != std::string::npos)
          source.replace(pos, 1,1, chgsym);
  
      return source;
  }
  
 -int GetULongLongInt(const string & str, uint64_t * val, uint64_t defaultVal)
 +int GetULongLongInt(const std::string & str, uint64_t * val, uint64_t defaultVal)
  {
      char *res;
      
@@@ -98,9 -98,6 +99,9 @@@
  } 
  
  PLUGIN_CREATOR<MYSQL_STORE> msc;
 +}
 +
 +extern "C" STORE * GetStore();
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
@@@ -119,12 -116,12 +120,12 @@@ MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTI
  {
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE_SETTINGS::ParseParam(const vector<PARAM_VALUE> & moduleParams, 
 -                        const string & name, string & result)
 +int MYSQL_STORE_SETTINGS::ParseParam(const std::vector<PARAM_VALUE> & moduleParams, 
 +                        const std::string & name, std::string & result)
  {
  PARAM_VALUE pv;
  pv.param = name;
 -vector<PARAM_VALUE>::const_iterator pvi;
 +std::vector<PARAM_VALUE>::const_iterator pvi;
  pvi = find(moduleParams.begin(), moduleParams.end(), pv);
  if (pvi == moduleParams.end())
      {
@@@ -162,9 -159,10 +163,9 @@@ MYSQL_STORE::MYSQL_STORE(
        version("mysql_store v.0.67"),
        storeSettings(),
        settings(),
 -      schemaVersion(0),
 -      WriteServLog(GetStgLogger())
 +      logger(GetPluginLogger(GetStgLogger(), "store_mysql"))
  {
 -};
 +}
  //-----------------------------------------------------------------------------
  int    MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
  {
@@@ -215,7 -213,7 +216,7 @@@ els
      {
           if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
           {
 -             string res = "CREATE DATABASE " + storeSettings.GetDBName();
 +             std::string res = "CREATE DATABASE " + storeSettings.GetDBName();
              
              if(MysqlQuery(res.c_str(),sock))
              {
                   }
                   ret = CheckAllTables(sock);
              }
-          }
-          else
-              ret = CheckAllTables(sock);
-          mysql_close(sock);
+         }
+         else
+         {
+             ret = CheckAllTables(sock);
+         }
+         if (!ret)
+         {
+             WriteServLog("MYSQL_STORE: Current DB schema version: %d", schemaVersion);
+             MakeUpdates(sock);
+         }
+         mysql_close(sock);
      }
-     
  }
  return ret;
  }
  //-----------------------------------------------------------------------------
 -bool MYSQL_STORE::IsTablePresent(const string & str,MYSQL * sock)
 +bool MYSQL_STORE::IsTablePresent(const std::string & str,MYSQL * sock)
  {
  MYSQL_RES* result;
  
@@@ -257,16 -261,53 +264,53 @@@ if (!(result=mysql_list_tables(sock,str
      return -1;
  }
  
 -unsigned int num_rows =  mysql_num_rows(result);
 +my_ulonglong num_rows =  mysql_num_rows(result);
  
  if(result)
      mysql_free_result(result);
  
 -return (num_rows == 1);
 +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))
  {
  }
  
  //tariffs-----------------------------------------------------------------------
 -string param, res;
 +std::string param, res;
  if(!IsTablePresent("tariffs",sock))
  {
      res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
          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))
      {
      
      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))
      {
          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,15 -578,38 +581,38 @@@ 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;
+     WriteServLog("MYSQL_STORE: Updated DB schema to version %d", schemaVersion);
+     }
+ return 0;
+ }
  //-----------------------------------------------------------------------------
  
 -int MYSQL_STORE::GetAllParams(vector<string> * ParamList, 
 -                            const string & table, const string & name) const
 +int MYSQL_STORE::GetAllParams(std::vector<std::string> * ParamList, 
 +                            const std::string & table, const std::string & name) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
  MYSQL * sock=NULL;
 -unsigned int num,i;
 +my_ulonglong num, i;
      
  ParamList->clear();
      
@@@ -558,7 -634,7 +637,7 @@@ if (!(res=mysql_store_result(sock))
  
  num = mysql_num_rows(res);
  
 -for(i=0;i<num;i++)
 +for(i = 0; i < num; i++)
  {
      row = mysql_fetch_row(res);    
      ParamList->push_back(row[0]);
@@@ -571,7 -647,7 +650,7 @@@ return 0
  }
  
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::GetUsersList(vector<string> * usersList) const
 +int MYSQL_STORE::GetUsersList(std::vector<std::string> * usersList) const
  {
  if(GetAllParams(usersList, "users", "login"))
      return -1;
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::GetAdminsList(vector<string> * adminsList) const
 +int MYSQL_STORE::GetAdminsList(std::vector<std::string> * adminsList) const
  {
  if(GetAllParams(adminsList, "admins", "login"))
      return -1;
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::GetTariffsList(vector<string> * tariffsList) const
 +int MYSQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
  {
  if(GetAllParams(tariffsList, "tariffs", "name"))
      return -1;
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::AddUser(const string & login) const
 +int MYSQL_STORE::AddUser(const std::string & login) const
  {
  sprintf(qbuf,"INSERT INTO users SET login='%s'", login.c_str());
      
@@@ -609,7 -685,7 +688,7 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::DelUser(const string & login) const
 +int MYSQL_STORE::DelUser(const std::string & login) const
  {
  sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
      
@@@ -623,12 -699,12 +702,12 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const string & login) const
 +int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
  MYSQL * sock;
 -string query;
 +std::string query;
  
  query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
           AlwaysOnline, Tariff, Address, Phone, Email, Note, \
@@@ -670,7 -746,7 +749,7 @@@ if (mysql_num_rows(res) != 1
  
  row = mysql_fetch_row(res);
  
 -string param;
 +std::string param;
  
  conf->password = row[1];
  
@@@ -682,7 -758,7 +761,7 @@@ if (conf->password.empty()
      return -1;
      }
  
 -if (GetInt(row[2],&conf->passive, 0) != 0)
 +if (GetInt(row[2],&conf->passive) != 0)
      {
      mysql_free_result(res);
      errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
      return -1;
      }
  
 -if (GetInt(row[3], &conf->disabled, 0) != 0)
 +if (GetInt(row[3], &conf->disabled) != 0)
      {
      mysql_free_result(res);
      errorStr = "User \'" + login + "\' data not read. Parameter Down.";
      return -1;
      }
  
 -if (GetInt(row[4], &conf->disabledDetailStat, 0) != 0)
 +if (GetInt(row[4], &conf->disabledDetailStat) != 0)
      {
      mysql_free_result(res);
      errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
      return -1;
      }
  
 -if (GetInt(row[5], &conf->alwaysOnline, 0) != 0)
 +if (GetInt(row[5], &conf->alwaysOnline) != 0)
      {
      mysql_free_result(res);
      errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
@@@ -748,13 -824,13 +827,13 @@@ for (int i = 0; i < USERDATA_NUM; i++
  
  GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
      
 -string ipStr = row[16+USERDATA_NUM];
 +std::string ipStr = row[16+USERDATA_NUM];
  USER_IPS i;
  try
      {
      i = StrToIPS(ipStr);
      }
 -catch (const string & s)
 +catch (const std::string & s)
      {
      mysql_free_result(res);
      errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
@@@ -769,13 -845,13 +848,13 @@@ mysql_close(sock)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const string & login) const
 +int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
  MYSQL * sock;
  
 -string query;
 +std::string query;
  
  query = "SELECT ";
  
@@@ -820,7 -896,7 +899,7 @@@ for (int i = 0; i < DIR_NUM; i++
      if (GetULongLongInt(row[startPos+i*2], &traff, 0) != 0)
          {
          mysql_free_result(res);
 -        errorStr = "User \'" + login + "\' stat not read. Parameter " + string(s);
 +        errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
          mysql_close(sock);
          return -1;
          }
      if (GetULongLongInt(row[startPos+i*2+1], &traff, 0) != 0)
          {
          mysql_free_result(res);
 -        errorStr =   "User \'" + login + "\' stat not read. Parameter " + string(s);
 +        errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
          mysql_close(sock);
          return -1;
          }
@@@ -892,10 -968,10 +971,10 @@@ mysql_close(sock)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const string & login) const
 +int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
  {
 -string param;
 -string res;
 +std::string param;
 +std::string res;
  
  strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
      "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
@@@ -926,7 -1002,7 +1005,7 @@@ for (int i = 0; i < USERDATA_NUM; i++
  strprintf(&param, " CreditExpire=%d,", conf.creditExpire);
  res += param;
  
 -stringstream ipStr;
 +std::ostringstream ipStr;
  ipStr << conf.ips;
  
  strprintf(&param, " IP='%s'", ipStr.str().c_str());
@@@ -945,10 -1021,10 +1024,10 @@@ if(MysqlSetQuery(res.c_str())
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const string & login) const
 +int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
  {
 -string param;
 -string res;
 +std::string param;
 +std::string res;
  
  res = "UPDATE users SET";
  
@@@ -985,9 -1061,9 +1064,9 @@@ if(MysqlSetQuery(res.c_str())
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::WriteLogString(const string & str, const string & login) const
 +int MYSQL_STORE::WriteLogString(const std::string & str, const std::string & login) const
  {
 -string res, tempStr;
 +std::string res, tempStr;
  time_t t;
  tm * lt;
  
@@@ -1009,7 -1085,7 +1088,7 @@@ if (!(result=mysql_list_tables(sock,tem
      return -1;
  }
  
 -unsigned int num_rows =  mysql_num_rows(result);
 +my_ulonglong num_rows =  mysql_num_rows(result);
  
  mysql_free_result(result);
  
@@@ -1029,7 -1105,7 +1108,7 @@@ if (num_rows < 1
  
  strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
  
 -string send;
 +std::string send;
  
  strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
          lt->tm_mon+1, lt->tm_year+1900,
@@@ -1047,42 -1123,42 +1126,42 @@@ return 0
  
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::WriteUserChgLog(const string & login,
 -                                 const string & admLogin,
 +int MYSQL_STORE::WriteUserChgLog(const std::string & login,
 +                                 const std::string & admLogin,
                                   uint32_t       admIP,
 -                                 const string & paramName,
 -                                 const string & oldValue,
 -                                 const string & newValue,
 -                                 const string & message) const
 +                                 const std::string & paramName,
 +                                 const std::string & oldValue,
 +                                 const std::string & newValue,
 +                                 const std::string & message) const
  {
 -string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
 +std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
      + paramName + "\' parameter changed from \'" + oldValue +
      "\' to \'" + newValue + "\'. " + message;
  
  return WriteLogString(userLogMsg, login);
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::WriteUserConnect(const string & login, uint32_t ip) const
 +int MYSQL_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
  {
 -string logStr = "Connect, " + inet_ntostring(ip);
 +std::string logStr = "Connect, " + inet_ntostring(ip);
  return WriteLogString(logStr, login);
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::WriteUserDisconnect(const string & login,
 +int MYSQL_STORE::WriteUserDisconnect(const std::string & login,
                                       const DIR_TRAFF & up,
                                       const DIR_TRAFF & down,
                                       const DIR_TRAFF & sessionUp,
                                       const DIR_TRAFF & sessionDown,
                                       double cash,
 -                                     double freeMb,
 -                                     const std::string & reason) const
 +                                     double /*freeMb*/,
 +                                     const std::string & /*reason*/) const
  {
 -string logStr = "Disconnect, ";
 -stringstream sssu;
 -stringstream sssd;
 -stringstream ssmu;
 -stringstream ssmd;
 -stringstream sscash;
 +std::string logStr = "Disconnect, ";
 +std::ostringstream sssu;
 +std::ostringstream sssd;
 +std::ostringstream ssmu;
 +std::ostringstream ssmd;
 +std::ostringstream sscash;
  
  ssmu << up;
  ssmd << down;
@@@ -1108,9 -1184,9 +1187,9 @@@ return WriteLogString(logStr, login)
  }
  //-----------------------------------------------------------------------------
  int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, 
 -                                const string & login) const
 +                                const std::string & login) const
  {
 -string param, res;
 +std::string param, res;
  
  strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,", 
      login.c_str(), month+1, year+1900);
@@@ -1137,7 -1213,7 +1216,7 @@@ if(MysqlSetQuery(res.c_str())
  return 0;
  }
  //-----------------------------------------------------------------------------*/
 -int MYSQL_STORE::AddAdmin(const string & login) const
 +int MYSQL_STORE::AddAdmin(const std::string & login) const
  {
  sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
      
@@@ -1151,7 -1227,7 +1230,7 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------*/
 -int MYSQL_STORE::DelAdmin(const string & login) const
 +int MYSQL_STORE::DelAdmin(const std::string & login) const
  {
  sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
      
@@@ -1212,7 -1288,7 +1291,7 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const string & login) const
 +int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
  {
  char pass[ADM_PASSWD_LEN + 1];
  char password[ADM_PASSWD_LEN + 1];
@@@ -1223,7 -1299,7 +1302,7 @@@ memset(pass, 0, sizeof(pass))
  memset(password, 0, sizeof(password));
  memset(passwordE, 0, sizeof(passwordE));
  
 -string p;
 +std::string p;
  MYSQL_RES *res;
  MYSQL_ROW row;
  MYSQL * sock;
@@@ -1256,6 -1332,7 +1335,6 @@@ if ( mysql_num_rows(res) == 0
  row = mysql_fetch_row(res);
  
  p = row[1];
 -int a;
  
  if(p.length() == 0)
  {
@@@ -1287,9 -1364,7 +1366,9 @@@ els
  
  ac->password = password;
  
 -if (GetInt(row[2], &a, 0) == 0) 
 +uint16_t a;
 +
 +if (GetInt(row[2], &a) == 0) 
      ac->priv.userConf = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[3], &a, 0) == 0) 
 +if (GetInt(row[3], &a) == 0) 
      ac->priv.userPasswd = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[4], &a, 0) == 0) 
 +if (GetInt(row[4], &a) == 0) 
      ac->priv.userStat = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[5], &a, 0) == 0) 
 +if (GetInt(row[5], &a) == 0) 
      ac->priv.userCash = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[6], &a, 0) == 0) 
 +if (GetInt(row[6], &a) == 0) 
      ac->priv.userAddDel = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[7], &a, 0) == 0) 
 +if (GetInt(row[7], &a) == 0) 
      ac->priv.tariffChg = a;
  else
      {
      return -1;
      }
  
 -if (GetInt(row[8], &a, 0) == 0) 
 +if (GetInt(row[8], &a) == 0) 
      ac->priv.adminChg = a;
  else
      {
@@@ -1364,7 -1439,7 +1443,7 @@@ mysql_close(sock)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::AddTariff(const string & name) const
 +int MYSQL_STORE::AddTariff(const std::string & name) const
  {
  sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
      
@@@ -1378,7 -1453,7 +1457,7 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::DelTariff(const string & name) const
 +int MYSQL_STORE::DelTariff(const std::string & name) const
  {
  sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
      
@@@ -1392,7 -1467,7 +1471,7 @@@ if(MysqlSetQuery(qbuf)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const string & tariffName) const
 +int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
@@@ -1415,12 -1490,12 +1494,12 @@@ if (!(res=mysql_store_result(sock))
      return -1;
  }
  
 -string str;
 +std::string str;
  td->tariffConf.name = tariffName;
  
  row = mysql_fetch_row(res);
  
 -string param;
 +std::string param;
  for (int i = 0; i<DIR_NUM; i++)
      {
      strprintf(&param, "Time%d", i);
      td->dirPrice[i].priceNightB /= (1024*1024);
  
      strprintf(&param, "Threshold%d", i);
 -    if (GetInt(row[5+i*8], &td->dirPrice[i].threshold, 0) < 0)
 +    if (GetInt(row[5+i*8], &td->dirPrice[i].threshold) < 0)
          {
          mysql_free_result(res);
          errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
          }
  
      strprintf(&param, "SinglePrice%d", i);
 -    if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice, 0) < 0)
 +    if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice) < 0)
          {
          mysql_free_result(res);
          errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
          }
  
      strprintf(&param, "NoDiscount%d", i);
 -    if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount, 0) < 0)
 +    if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount) < 0)
          {
          mysql_free_result(res);
          errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
                  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;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const string & tariffName) const
 +int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
  {
 -string param;
 +std::string param;
  
 -string res="UPDATE tariffs SET";
 +std::string res="UPDATE tariffs SET";
  
  for (int i = 0; i < DIR_NUM; i++)
      {
          td.dirPrice[i].threshold);
      res += param;
  
 -    string s;
 +    std::string s;
      strprintf(&param, " Time%d", i);
  
      strprintf(&s, "%0d:%0d-%0d:%0d", 
@@@ -1638,12 -1733,16 +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;
  }
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> & statTree, 
 +int MYSQL_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree, 
                                     time_t lastStat, 
 -                                   const string & login) const
 +                                   const std::string & login) const
  {
 -string res, stTime, endTime, tempStr;
 +std::string res, stTime, endTime, tempStr;
  time_t t;
  tm * lt;
  
@@@ -1685,7 -1784,7 +1788,7 @@@ if (!(result=mysql_list_tables(sock,tem
      return -1;
  }
  
 -unsigned int num_rows =  mysql_num_rows(result);
 +my_ulonglong num_rows =  mysql_num_rows(result);
  
  mysql_free_result(result);
  
@@@ -1736,7 -1835,7 +1839,7 @@@ strprintf(&res,"INSERT INTO detailstat_
      endTime.c_str()
      );
  
 -map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
 +std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
  stIter = statTree.begin();
  
  while (stIter != statTree.end())
@@@ -1767,17 -1866,17 +1870,17 @@@ mysql_close(sock)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::AddMessage(STG_MSG * msg, const string & login) const
 +int MYSQL_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
  {
  struct timeval tv;
  
  gettimeofday(&tv, NULL);
  
 -msg->header.id = ((long long)tv.tv_sec) * 1000000 + ((long long)tv.tv_usec);
 +msg->header.id = static_cast<uint64_t>(tv.tv_sec) * 1000000 + static_cast<uint64_t>(tv.tv_usec);
  
  sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld", 
      login.c_str(),
 -    (long long)msg->header.id
 +    static_cast<long long>(msg->header.id)
      );
      
  if(MysqlSetQuery(qbuf))
  return EditMessage(*msg, login);
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::EditMessage(const STG_MSG & msg, const string & login) const
 +int MYSQL_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
  {
 -string res;
 +std::string res;
  
  strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
      "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
      msg.header.repeatPeriod,
      (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
      login.c_str(),
 -    (long long)msg.header.id
 +    msg.header.id
      );
  
  if(MysqlSetQuery(res.c_str()))
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const string & login) const
 +int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
@@@ -1901,10 -2000,10 +2004,10 @@@ mysql_close(sock)
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::DelMessage(uint64_t id, const string & login) const
 +int MYSQL_STORE::DelMessage(uint64_t id, const std::string & login) const
  {
  sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1", 
 -    login.c_str(),(long long)id);
 +        login.c_str(), static_cast<long long>(id));
      
  if(MysqlSetQuery(qbuf))
  {
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int MYSQL_STORE::GetMessageHdrs(vector<STG_MSG_HDR> * hdrsList, const string & login) const
 +int MYSQL_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
  {
  MYSQL_RES *res;
  MYSQL_ROW row;
@@@ -1939,11 -2038,10 +2042,11 @@@ if (!(res=mysql_store_result(sock))
      return -1;
  }
  
 -unsigned int i, num_rows =  mysql_num_rows(res);
 -long long int unsigned id = 0;
 +unsigned int i;
 +my_ulonglong num_rows = mysql_num_rows(res);
 +uint64_t id = 0;
  
 -for (i=0; i<num_rows; i++)
 +for (i = 0; i < num_rows; i++)
  {
      row = mysql_fetch_row(res);
      if (str2x(row[1], id))
index af747c14518662884bbbf27359b22e7b8bff6758,8818f590cb603291aba8a481c1d318f6f910f0f8..4a492b3833694ece04130acf72fc81be96e78034
  #include <mysql/mysql.h>
  
  #include <string>
 +#include <vector>
 +#include <map>
  
  #include "stg/module_settings.h"
  #include "stg/store.h"
  #include "stg/user_traff.h"
 +#include "stg/logger.h"
  
 -using namespace std;
 -//-----------------------------------------------------------------------------
 -extern "C" STORE * GetStore();
 -class STG_LOGGER;
  //-----------------------------------------------------------------------------
  class MYSQL_STORE_SETTINGS
  {
@@@ -25,12 -26,12 +25,12 @@@ public
      MYSQL_STORE_SETTINGS();
      virtual ~MYSQL_STORE_SETTINGS() {}
      virtual int ParseSettings(const MODULE_SETTINGS & s);
 -    virtual const string & GetStrError() const { return errorStr; }
 +    virtual const std::string & GetStrError() const { return errorStr; }
  
 -    const string & GetDBUser() const { return dbUser; }
 -    const string & GetDBPassword() const { return dbPass; }
 -    const string & GetDBHost() const { return dbHost; }
 -    const string & GetDBName() const { return dbName; }
 +    const std::string & GetDBUser() const { return dbUser; }
 +    const std::string & GetDBPassword() const { return dbPass; }
 +    const std::string & GetDBHost() const { return dbHost; }
 +    const std::string & GetDBName() const { return dbName; }
  
  private:
      MYSQL_STORE_SETTINGS(const MYSQL_STORE_SETTINGS & rvalue);
  
      const MODULE_SETTINGS * settings;
  
 -    int     ParseParam(const vector<PARAM_VALUE> & moduleParams, 
 -                       const string & name, string & result);
 +    int     ParseParam(const std::vector<PARAM_VALUE> & moduleParams, 
 +                       const std::string & name, std::string & result);
  
 -    string  errorStr;
 +    std::string  errorStr;
  
 -    string  dbUser;
 -    string  dbPass;
 -    string  dbName;
 -    string  dbHost;
 +    std::string  dbUser;
 +    std::string  dbPass;
 +    std::string  dbName;
 +    std::string  dbHost;
  };
  //-----------------------------------------------------------------------------
  class MYSQL_STORE: public STORE
  public:
      MYSQL_STORE();
      virtual ~MYSQL_STORE() {}
 -    virtual const string & GetStrError() const { return errorStr; }
 +    virtual const std::string & GetStrError() const { return errorStr; }
  
      //User
 -    virtual int GetUsersList(vector<string> * usersList) const;
 -    virtual int AddUser(const string & login) const;
 -    virtual int DelUser(const string & login) const;
 -    virtual int SaveUserStat(const USER_STAT & stat, const string & login) const;
 -    virtual int SaveUserConf(const USER_CONF & conf, const string & login) const;
 -    virtual int RestoreUserStat(USER_STAT * stat, const string & login) const;
 -    virtual int RestoreUserConf(USER_CONF * conf, const string & login) const;
 -    virtual int WriteUserChgLog(const string & login,
 -                                const string & admLogin,
 +    virtual int GetUsersList(std::vector<std::string> * usersList) const;
 +    virtual int AddUser(const std::string & login) const;
 +    virtual int DelUser(const std::string & login) const;
 +    virtual int SaveUserStat(const USER_STAT & stat, const std::string & login) const;
 +    virtual int SaveUserConf(const USER_CONF & conf, const std::string & login) const;
 +    virtual int RestoreUserStat(USER_STAT * stat, const std::string & login) const;
 +    virtual int RestoreUserConf(USER_CONF * conf, const std::string & login) const;
 +    virtual int WriteUserChgLog(const std::string & login,
 +                                const std::string & admLogin,
                                  uint32_t       admIP,
 -                                const string & paramName,
 -                                const string & oldValue,
 -                                const string & newValue,
 -                                const string & message = "") const;
 -    virtual int WriteUserConnect(const string & login, uint32_t ip) const;
 -    virtual int WriteUserDisconnect(const string & login,
 +                                const std::string & paramName,
 +                                const std::string & oldValue,
 +                                const std::string & newValue,
 +                                const std::string & message = "") const;
 +    virtual int WriteUserConnect(const std::string & login, uint32_t ip) const;
 +    virtual int WriteUserDisconnect(const std::string & login,
                                      const DIR_TRAFF & up,
                                      const DIR_TRAFF & down,
                                      const DIR_TRAFF & sessionUp,
                                      double freeMb,
                                      const std::string & reason) const;
  
 -    virtual int WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> & statTree,
 +    virtual int WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
                                    time_t lastStat,
 -                                  const string & login) const;
 +                                  const std::string & login) const;
  
 -    virtual int AddMessage(STG_MSG * msg, const string & login) const;
 -    virtual int EditMessage(const STG_MSG & msg, const string & login) const;
 -    virtual int GetMessage(uint64_t id, STG_MSG * msg, const string & login) const;
 -    virtual int DelMessage(uint64_t id, const string & login) const;
 -    virtual int GetMessageHdrs(vector<STG_MSG_HDR> * hdrsList, const string & login) const;
 +    virtual int AddMessage(STG_MSG * msg, const std::string & login) const;
 +    virtual int EditMessage(const STG_MSG & msg, const std::string & login) const;
 +    virtual int GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const;
 +    virtual int DelMessage(uint64_t id, const std::string & login) const;
 +    virtual int GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const;
  
 -    virtual int SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const;
 +    virtual int SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const;
  
      //Admin
 -    virtual int GetAdminsList(vector<string> * adminsList) const;
 -    virtual int AddAdmin(const string & login) const;
 -    virtual int DelAdmin(const string & login) const;
 -    virtual int RestoreAdmin(ADMIN_CONF * ac, const string & login) const;
 +    virtual int GetAdminsList(std::vector<std::string> * adminsList) const;
 +    virtual int AddAdmin(const std::string & login) const;
 +    virtual int DelAdmin(const std::string & login) const;
 +    virtual int RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const;
      virtual int SaveAdmin(const ADMIN_CONF & ac) const;
  
      //Tariff
 -    virtual int GetTariffsList(vector<string> * tariffsList) const;
 -    virtual int AddTariff(const string & name) const;
 -    virtual int DelTariff(const string & name) const;
 -    virtual int SaveTariff(const TARIFF_DATA & td, const string & tariffName) const;
 -    virtual int RestoreTariff(TARIFF_DATA * td, const string & tariffName) const;
 +    virtual int GetTariffsList(std::vector<std::string> * tariffsList) const;
 +    virtual int AddTariff(const std::string & name) const;
 +    virtual int DelTariff(const std::string & name) const;
 +    virtual int SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const;
 +    virtual int RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const;
  
      //Corparation
 -    virtual int GetCorpsList(vector<string> *) const {return 0;};
 -    virtual int SaveCorp(const CORP_CONF &) const {return 0;};
 -    virtual int RestoreCorp(CORP_CONF *, const string &) const {return 0;};
 -    virtual int AddCorp(const string &) const {return 0;};
 -    virtual int DelCorp(const string &) const {return 0;};
 +    virtual int GetCorpsList(std::vector<std::string> *) const {return 0;}
 +    virtual int SaveCorp(const CORP_CONF &) const {return 0;}
 +    virtual int RestoreCorp(CORP_CONF *, const std::string &) const {return 0;}
 +    virtual int AddCorp(const std::string &) const {return 0;}
 +    virtual int DelCorp(const std::string &) const {return 0;}
  
      // Services
 -    virtual int GetServicesList(vector<string> *) const {return 0;};
 -    virtual int SaveService(const SERVICE_CONF &) const {return 0;};
 -    virtual int RestoreService(SERVICE_CONF *, const string &) const {return 0;};
 -    virtual int AddService(const string &) const {return 0;};
 -    virtual int DelService(const string &) const {return 0;};
 +    virtual int GetServicesList(std::vector<std::string> *) const {return 0;}
 +    virtual int SaveService(const SERVICE_CONF &) const {return 0;}
 +    virtual int RestoreService(SERVICE_CONF *, const std::string &) const {return 0;}
 +    virtual int AddService(const std::string &) const {return 0;}
 +    virtual int DelService(const std::string &) const {return 0;}
  
      virtual void            SetSettings(const MODULE_SETTINGS & s) { settings = s; }
      virtual int             ParseSettings();
 -    virtual const string &  GetVersion() const { return version; }
 +    virtual const std::string &  GetVersion() const { return version; }
  
  private:
      MYSQL_STORE(const MYSQL_STORE & rvalue);
      MYSQL_STORE & operator=(const MYSQL_STORE & rvalue);
  
 -    virtual int WriteLogString(const string & str, const string & login) const;
 -    int GetAllParams(vector<string> * ParamList, const string & table, const string & name) const;
 +    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);
 -    bool IsTablePresent(const string & str,MYSQL * sock);
 -    mutable string          errorStr;
 -    int                     MysqlQuery(const char* sQuery,MYSQL * sock) const;
+     int MakeUpdates(MYSQL * sock);
 +    bool IsTablePresent(const std::string & str,MYSQL * sock);
 +    mutable std::string          errorStr;
 +    int                        MysqlQuery(const char* sQuery,MYSQL * sock) const;
      int                     MysqlGetQuery(const char * Query,MYSQL * & sock) const;
      int                     MysqlSetQuery(const char * Query) const;
      MYSQL  *                MysqlConnect() const ;
 -    string                  version;
 +    std::string                  version;
      MYSQL_STORE_SETTINGS    storeSettings;
      MODULE_SETTINGS         settings;
 -    STG_LOGGER &            WriteServLog;
+     int                     schemaVersion;
 +
 +    PLUGIN_LOGGER           logger;
  };
  //-----------------------------------------------------------------------------
  
index 5e2d8ae6de9e29aa608686d0cc3351f406355c97,51eec8f414626463cb72a99b61873e44d5309283..49f0e8088f8f5dc06370dc947beb4b56067eeaf2
   *
   */
  
 -#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 "stg/logger.h"
 -#include "postgresql_store_utils.h"
 -#include "postgresql_store.h"
  
 -PLUGIN_CREATOR<POSTGRESQL_STORE> pqStoreeCreator;
 +#include <libpq-fe.h>
 +
 +#include <string>
 +#include <vector>
 +
 +namespace
 +{
 +PLUGIN_CREATOR<POSTGRESQL_STORE> pgsc;
 +}
 +
 +extern "C" STORE * GetStore();
  
  //-----------------------------------------------------------------------------
  STORE * GetStore()
  {
 -return pqStoreeCreator.GetPlugin();
 +return pgsc.GetPlugin();
  }
  
  //-----------------------------------------------------------------------------
@@@ -75,7 -72,7 +75,7 @@@ POSTGRESQL_STORE::POSTGRESQL_STORE(
        version(0),
        retries(3),
        connection(NULL),
 -      WriteServLog(GetStgLogger())
 +      logger(GetPluginLogger(GetStgLogger(), "store_postgresql"))
  {
  pthread_mutex_init(&mutex, NULL);
  }
@@@ -92,25 -89,37 +92,25 @@@ pthread_mutex_destroy(&mutex)
  int POSTGRESQL_STORE::ParseSettings()
  {
  std::vector<PARAM_VALUE>::iterator i;
 -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";
@@@ -224,6 -233,8 +224,8 @@@ if (CommitTransaction()
      return -1;
      }
  
+ WriteServLog("POSTGRESQL_STORE: Current DB schema version: %d", version);
  return 0;
  }
  //-----------------------------------------------------------------------------
index fb8caf9dee0b97b9d9a8a76724bd3f4595ae0301,ffce284614452cf9f87a3d5cd77257aaf90daffc..c9cb7ccfe79f19968eb646c81b2f57652f16985d
@@@ -29,7 -29,6 +29,7 @@@
  #include <string>
  #include <vector>
  #include <sstream>
 +#include <cmath>
  
  #include <libpq-fe.h>
  
@@@ -37,7 -36,7 +37,7 @@@
  #include "stg/locker.h"
  
  //-----------------------------------------------------------------------------
 -int POSTGRESQL_STORE::GetTariffsList(vector<string> * tariffsList) const
 +int POSTGRESQL_STORE::GetTariffsList(std::vector<std::string> * tariffsList) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -93,7 -92,7 +93,7 @@@ return 0
  }
  
  //-----------------------------------------------------------------------------
 -int POSTGRESQL_STORE::AddTariff(const string & name) const
 +int POSTGRESQL_STORE::AddTariff(const std::string & name) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -122,13 -121,13 +122,13 @@@ 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;
      }
  
 -std::stringstream query;
 +std::ostringstream query;
  query << "SELECT sp_add_tariff('" << ename << "', " << DIR_NUM << ")";
  
  result = PQexec(connection, query.str().c_str());
@@@ -156,7 -155,7 +156,7 @@@ if (CommitTransaction()
  return 0;
  }
  //-----------------------------------------------------------------------------
 -int POSTGRESQL_STORE::DelTariff(const string & name) const
 +int POSTGRESQL_STORE::DelTariff(const std::string & name) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -185,13 -184,13 +185,13 @@@ 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;
      }
  
 -std::stringstream query;
 +std::ostringstream query;
  query << "DELETE FROM tb_tariffs WHERE name = '" << ename << "'";
  
  result = PQexec(connection, query.str().c_str());
@@@ -220,7 -219,7 +220,7 @@@ return 0
  }
  //-----------------------------------------------------------------------------
  int POSTGRESQL_STORE::SaveTariff(const TARIFF_DATA & td,
 -                                 const string & tariffName) const
 +                                 const std::string & tariffName) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -249,9 -248,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;
      }
  
@@@ -259,12 -258,10 +259,12 @@@ int32_t id, i
  double pda, pdb, pna, pnb;
  int threshold;
  
 -std::stringstream query;
 -query << "SELECT pk_tariff FROM tb_tariffs WHERE name = '" << ename << "'";
 +    {
 +    std::ostringstream query;
 +    query << "SELECT pk_tariff FROM tb_tariffs WHERE name = '" << ename << "'";
  
 -result = PQexec(connection, query.str().c_str());
 +    result = PQexec(connection, query.str().c_str());
 +    }
  
  if (PQresultStatus(result) != PGRES_TUPLES_OK)
      {
@@@ -286,32 -283,32 +286,36 @@@ 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;
      }
  
 -std::stringstream tuple;
 -tuple << PQgetvalue(result, 0, 0);
 +    {
 +    std::stringstream tuple;
 +    tuple << PQgetvalue(result, 0, 0);
  
 -PQclear(result);
 +    PQclear(result);
  
 -tuple >> id;
 +    tuple >> id;
 +    }
  
 -query.str("");
 -query << "UPDATE tb_tariffs SET \
 -              fee = " << td.tariffConf.fee << ", \
 -              free = " << td.tariffConf.free << ", \
 -              passive_cost = " << td.tariffConf.passiveCost << ", \
 -              traff_type = " << td.tariffConf.traffType;
 +    {
 +    std::ostringstream query;
 +    query << "UPDATE tb_tariffs SET \
 +                  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) << "'";
++    if (version > 6)
++        query << ", period = '" << TARIFF::PeriodToString(td.tariffConf.period) << "'";
 -query << " WHERE pk_tariff = " << id;
++    query << " WHERE pk_tariff = " << id;
  
 -result = PQexec(connection, query.str().c_str());
 +    result = PQexec(connection, query.str().c_str());
 +    }
  
  if (PQresultStatus(result) != PGRES_COMMAND_OK)
      {
@@@ -353,24 -350,22 +357,24 @@@ for(i = 0; i < DIR_NUM; i++
          threshold = td.dirPrice[i].threshold;
          }
  
 -    std::stringstream query;
 -    query << "UPDATE tb_tariffs_params SET \
 -                  price_day_a = " << pda << ", \
 -                  price_day_b = " << pdb << ", \
 -                  price_night_a = " << pna << ", \
 -                  price_night_b = " << pnb << ", \
 -                  threshold = " << threshold << ", \
 -                  time_day_begins = CAST('" << td.dirPrice[i].hDay
 -                                            << ":"
 -                                            << td.dirPrice[i].mDay << "' AS TIME), \
 -                  time_day_ends = CAST('" << td.dirPrice[i].hNight
 -                                          << ":"
 -                                          << td.dirPrice[i].mNight << "' AS TIME) \
 -             WHERE fk_tariff = " << id << " AND dir_num = " << i;
 -
 -    result = PQexec(connection, query.str().c_str());
 +        {
 +        std::ostringstream query;
 +        query << "UPDATE tb_tariffs_params SET \
 +                      price_day_a = " << pda << ", \
 +                      price_day_b = " << pdb << ", \
 +                      price_night_a = " << pna << ", \
 +                      price_night_b = " << pnb << ", \
 +                      threshold = " << threshold << ", \
 +                      time_day_begins = CAST('" << td.dirPrice[i].hDay
 +                                                << ":"
 +                                                << td.dirPrice[i].mDay << "' AS TIME), \
 +                      time_day_ends = CAST('" << td.dirPrice[i].hNight
 +                                              << ":"
 +                                              << td.dirPrice[i].mNight << "' AS TIME) \
 +                 WHERE fk_tariff = " << id << " AND dir_num = " << i;
 +
 +        result = PQexec(connection, query.str().c_str());
 +        }
  
      if (PQresultStatus(result) != PGRES_COMMAND_OK)
          {
@@@ -397,7 -392,7 +401,7 @@@ return 0
  }
  //-----------------------------------------------------------------------------
  int POSTGRESQL_STORE::RestoreTariff(TARIFF_DATA * td,
 -                                  const string & tariffName) const
 +                                  const std::string & tariffName) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
@@@ -426,21 -421,25 +430,25 @@@ 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;
      }
  
  td->tariffConf.name = tariffName;
  
 -std::stringstream query;
 +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,44 -463,44 +472,47 @@@ 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;
      }
  
 -std::stringstream tuple;
 -tuple << PQgetvalue(result, 0, 0) << " ";
 -tuple << PQgetvalue(result, 0, 1) << " ";
 -tuple << PQgetvalue(result, 0, 2) << " ";
 -tuple << PQgetvalue(result, 0, 3) << " ";
 -tuple << PQgetvalue(result, 0, 4) << " ";
 -
  int id;
 -tuple >> id;
 -tuple >> td->tariffConf.fee;
 -tuple >> td->tariffConf.free;
 -tuple >> td->tariffConf.passiveCost;
 -tuple >> td->tariffConf.traffType;
 +
 +    {
 +    std::stringstream tuple;
 +    tuple << PQgetvalue(result, 0, 0) << " ";
 +    tuple << PQgetvalue(result, 0, 1) << " ";
 +    tuple << PQgetvalue(result, 0, 2) << " ";
 +    tuple << PQgetvalue(result, 0, 3) << " ";
 +    tuple << PQgetvalue(result, 0, 4) << " ";
 +
 +    tuple >> id;
 +    tuple >> td->tariffConf.fee;
 +    tuple >> td->tariffConf.free;
 +    tuple >> td->tariffConf.passiveCost;
 +    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 -510,9 +522,9 @@@ if (PQresultStatus(result) != PGRES_TUP
      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;
      }
  
@@@ -526,39 -525,37 +537,39 @@@ if (tuples != DIR_NUM
  
  for (int i = 0; i < std::min(tuples, DIR_NUM); ++i)
      {
 -    std::stringstream tuple;
 -    tuple << PQgetvalue(result, i, 0) << " ";
 -    tuple << PQgetvalue(result, i, 1) << " ";
 -    tuple << PQgetvalue(result, i, 2) << " ";
 -    tuple << PQgetvalue(result, i, 3) << " ";
 -    tuple << PQgetvalue(result, i, 4) << " ";
 -    tuple << PQgetvalue(result, i, 5) << " ";
 -    tuple << PQgetvalue(result, i, 6) << " ";
 -    tuple << PQgetvalue(result, i, 7) << " ";
 -    tuple << PQgetvalue(result, i, 8) << " ";
 -    tuple << PQgetvalue(result, i, 9) << " ";
 -
      int dir;
  
 -    tuple >> dir;
 -    tuple >> td->dirPrice[dir].priceDayA;
 -    td->dirPrice[dir].priceDayA /= 1024 * 1024;
 -    tuple >> td->dirPrice[dir].priceDayB;
 -    td->dirPrice[dir].priceDayB /= 1024 * 1024;
 -    tuple >> td->dirPrice[dir].priceNightA;
 -    td->dirPrice[dir].priceNightA /= 1024 * 1024;
 -    tuple >> td->dirPrice[dir].priceNightB;
 -    td->dirPrice[dir].priceNightB /= 1024 * 1024;
 -    tuple >> td->dirPrice[dir].threshold;
 -    tuple >> td->dirPrice[dir].hDay;
 -    tuple >> td->dirPrice[dir].mDay;
 -    tuple >> td->dirPrice[dir].hNight;
 -    tuple >> td->dirPrice[dir].mNight;
 -
 -    if (td->dirPrice[dir].priceDayA == td->dirPrice[dir].priceNightA &&
 -        td->dirPrice[dir].priceDayB == td->dirPrice[dir].priceNightB)
 +        {
 +        std::stringstream tuple;
 +        tuple << PQgetvalue(result, i, 0) << " ";
 +        tuple << PQgetvalue(result, i, 1) << " ";
 +        tuple << PQgetvalue(result, i, 2) << " ";
 +        tuple << PQgetvalue(result, i, 3) << " ";
 +        tuple << PQgetvalue(result, i, 4) << " ";
 +        tuple << PQgetvalue(result, i, 5) << " ";
 +        tuple << PQgetvalue(result, i, 6) << " ";
 +        tuple << PQgetvalue(result, i, 7) << " ";
 +        tuple << PQgetvalue(result, i, 8) << " ";
 +        tuple << PQgetvalue(result, i, 9) << " ";
 +
 +        tuple >> dir;
 +        tuple >> td->dirPrice[dir].priceDayA;
 +        td->dirPrice[dir].priceDayA /= 1024 * 1024;
 +        tuple >> td->dirPrice[dir].priceDayB;
 +        td->dirPrice[dir].priceDayB /= 1024 * 1024;
 +        tuple >> td->dirPrice[dir].priceNightA;
 +        td->dirPrice[dir].priceNightA /= 1024 * 1024;
 +        tuple >> td->dirPrice[dir].priceNightB;
 +        td->dirPrice[dir].priceNightB /= 1024 * 1024;
 +        tuple >> td->dirPrice[dir].threshold;
 +        tuple >> td->dirPrice[dir].hDay;
 +        tuple >> td->dirPrice[dir].mDay;
 +        tuple >> td->dirPrice[dir].hNight;
 +        tuple >> td->dirPrice[dir].mNight;
 +        }
 +
 +    if (std::fabs(td->dirPrice[dir].priceDayA - td->dirPrice[dir].priceNightA) > 1.0e-3 &&
 +        std::fabs(td->dirPrice[dir].priceDayB - td->dirPrice[dir].priceNightB) > 1.0e-3)
          {
          td->dirPrice[dir].singlePrice = true;
          }
index 122dabd044de29178d083c0849c4b4ba857a9fef,b471f0d04014e5c072dc7807c2ca6867c66302bd..f2f84d2630889f73432e9a191459c8174c37adf3
@@@ -48,20 -48,20 +48,20 @@@ public
      TARIFF_IMPL()
          : TARIFF(),
            tariffData()
 -    {};
 +    {}
      TARIFF_IMPL(const std::string & name)
          : TARIFF(),
            tariffData(name)
 -    {};
 +    {}
      TARIFF_IMPL(const TARIFF_DATA & td)
          : TARIFF(),
            tariffData(td)
 -    {};
 +    {}
      TARIFF_IMPL(const TARIFF_IMPL & t)
          : TARIFF(),
            tariffData(t.tariffData)
 -    {};
 -    virtual ~TARIFF_IMPL() {};
 +    {}
 +    virtual ~TARIFF_IMPL() {}
  
      double  GetPriceWithTraffType(uint64_t up,
                                    uint64_t down,
@@@ -71,6 -71,7 +71,7 @@@
      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;
  
@@@ -90,7 -91,7 +91,7 @@@
  private:
      TARIFF_DATA     tariffData;
  
 -    double  GetPriceWithoutFreeMb(int dir, int mb, time_t t) const;
 +    double  GetPriceWithoutFreeMb(int dir, int64_t mb, time_t t) const;
      int     Interval(int dir, time_t t) const;
  };
  
index 7b0348bc57e75928936640cbed90d90bd9b28481,42650effed158034cd7e30569df661bf0763f376..3b2489ad319bc1d660d089f4f5a0b2bf4264e93f
  #define _GNU_SOURCE
  #endif
  
 -#include <pthread.h>
 -#include <unistd.h> // access
 -
 -#include <cassert>
 -#include <cstdlib>
 +#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,
        property(s->GetScriptsDir()),
        WriteServLog(GetStgLogger()),
        lastScanMessages(0),
 -      login(),
        id(0),
        __connected(0),
        connected(__connected),
 -      enabledDirs(),
 -      userIDGenerator(),
        __currIP(0),
        currIP(__currIP),
        lastIPForDisconnect(0),
        store(st),
        tariffs(t),
        tariff(NULL),
 -      traffStat(),
 -      traffStatSaved(),
        settings(s),
 -      authorizedBy(),
 -      messages(),
 +      authorizedModificationTime(0),
        deleted(false),
        lastWriteStat(0),
        lastWriteDetailedStat(0),
        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;
@@@ -127,7 -132,6 +127,7 @@@ lastWriteDetailedStat = stgTime
  
  property.tariffName.AddBeforeNotifier(&tariffNotifier);
  property.passive.AddBeforeNotifier(&passiveNotifier);
 +property.disabled.AddAfterNotifier(&disabledNotifier);
  property.cash.AddBeforeNotifier(&cashNotifier);
  ips.AddAfterNotifier(&ipNotifier);
  
@@@ -147,9 -151,12 +147,9 @@@ USER_IMPL::USER_IMPL(const SETTINGS_IMP
        property(s->GetScriptsDir()),
        WriteServLog(GetStgLogger()),
        lastScanMessages(0),
 -      login(),
        id(0),
        __connected(0),
        connected(__connected),
 -      enabledDirs(),
 -      userIDGenerator(),
        __currIP(0),
        currIP(__currIP),
        lastIPForDisconnect(0),
        store(st),
        tariffs(t),
        tariff(NULL),
 -      traffStat(),
 -      traffStatSaved(),
        settings(s),
 -      authorizedBy(),
 -      messages(),
 +      authorizedModificationTime(0),
        deleted(false),
        lastWriteStat(0),
        lastWriteDetailedStat(0),
        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;
@@@ -211,7 -224,6 +211,7 @@@ lastWriteDetailedStat = stgTime
  
  property.tariffName.AddBeforeNotifier(&tariffNotifier);
  property.passive.AddBeforeNotifier(&passiveNotifier);
 +property.disabled.AddAfterNotifier(&disabledNotifier);
  property.cash.AddBeforeNotifier(&cashNotifier);
  ips.AddAfterNotifier(&ipNotifier);
  
@@@ -232,6 -244,7 +232,6 @@@ USER_IMPL::USER_IMPL(const USER_IMPL & 
        id(u.id),
        __connected(0),
        connected(__connected),
 -      enabledDirs(),
        userIDGenerator(u.userIDGenerator),
        __currIP(u.__currIP),
        currIP(__currIP),
        traffStat(u.traffStat),
        traffStatSaved(u.traffStatSaved),
        settings(u.settings),
 -      authorizedBy(),
 +      authorizedModificationTime(u.authorizedModificationTime),
        messages(u.messages),
        deleted(u.deleted),
        lastWriteStat(u.lastWriteStat),
        sessionUpload(),
        sessionDownload(),
        passiveNotifier(this),
 +      disabledNotifier(this),
        tariffNotifier(this),
        cashNotifier(this),
 -      ipNotifier(this),
 -      mutex(),
 -      errorStr()
 +      ipNotifier(this)
  {
  if (&u == this)
      return;
  
  property.tariffName.AddBeforeNotifier(&tariffNotifier);
  property.passive.AddBeforeNotifier(&passiveNotifier);
 +property.disabled.AddAfterNotifier(&disabledNotifier);
  property.cash.AddBeforeNotifier(&cashNotifier);
  ips.AddAfterNotifier(&ipNotifier);
  
@@@ -310,14 -323,12 +310,14 @@@ pthread_mutex_init(&mutex, &attr)
  //-----------------------------------------------------------------------------
  USER_IMPL::~USER_IMPL()
  {
 -property.passive.DelBeforeNotifier(&passiveNotifier);
  property.tariffName.DelBeforeNotifier(&tariffNotifier);
 +property.passive.DelBeforeNotifier(&passiveNotifier);
 +property.disabled.DelAfterNotifier(&disabledNotifier);
 +property.cash.DelBeforeNotifier(&cashNotifier);
  pthread_mutex_destroy(&mutex);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::SetLogin(string const & l)
 +void USER_IMPL::SetLogin(const std::string & l)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  assert(login.empty() && "Login is already set");
@@@ -516,8 -527,6 +516,8 @@@ els
          }
      }
  
 +if (authorizedBy.empty())
 +    authorizedModificationTime = stgTime;
  authorizedBy.insert(auth);
  
  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__);
  /*
@@@ -536,8 -545,6 +536,8 @@@ if (!authorizedBy.erase(auth)
  
  if (authorizedBy.empty())
      {
 +    authorizedModificationTime = stgTime;
 +    lastDisconnectReason = reason;
      lastIPForDisconnect = currIP;
      currIP = 0; // DelUser in traffcounter
      return;
@@@ -551,13 -558,6 +551,13 @@@ STG_LOCKER lock(&mutex, __FILE__, __LIN
  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)
  {
  /*
@@@ -568,7 -568,7 +568,7 @@@ STG_LOCKER lock(&mutex, __FILE__, __LIN
  
  if (!fakeConnect)
      {
 -    string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect";
 +    std::string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect";
  
      if (access(scriptOnConnect.c_str(), X_OK) == 0)
          {
              dirsStr[i] = enabledDirs[i] ? '1' : '0';
              }
  
 -        string scriptOnConnectParams;
 +        std::string scriptOnConnectParams;
 +
          strprintf(&scriptOnConnectParams,
                  "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
                  scriptOnConnect.c_str(),
                  login.c_str(),
                  inet_ntostring(currIP).c_str(),
 -                (double)cash,
 +                cash.ConstData(),
                  id,
                  dirsStr);
  
 +        std::vector<std::string>::const_iterator it(settings->GetScriptParams().begin());
 +        while (it != settings->GetScriptParams().end())
 +            {
 +            scriptOnConnectParams += " \"" + GetParamValue(it->c_str()) + "\"";
 +            ++it;
 +            }
 +
          ScriptExec(scriptOnConnectParams.c_str());
          }
      else
@@@ -633,8 -625,7 +633,8 @@@ if (!lastIPForDisconnect
  
  if (!fakeDisconnect)
      {
 -    string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect";
 +    lastDisconnectReason = reason;
 +    std::string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect";
  
      if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
          {
              dirsStr[i] = enabledDirs[i] ? '1' : '0';
              }
  
 -        string scriptOnDisonnectParams;
 +        std::string scriptOnDisonnectParams;
          strprintf(&scriptOnDisonnectParams,
                  "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
                  scriptOnDisonnect.c_str(),
                  login.c_str(),
                  inet_ntostring(lastIPForDisconnect).c_str(),
 -                (double)cash,
 +                cash.ConstData(),
                  id,
                  dirsStr);
  
 +        std::vector<std::string>::const_iterator it(settings->GetScriptParams().begin());
 +        while (it != settings->GetScriptParams().end())
 +            {
 +            scriptOnDisonnectParams += " \"" + GetParamValue(it->c_str()) + "\"";
 +            ++it;
 +            }
 +
          ScriptExec(scriptOnDisonnectParams.c_str());
          }
      else
      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());
@@@ -696,37 -675,37 +696,37 @@@ void USER_IMPL::PrintUser() cons
  {
  //return;
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -cout << "============================================================" << endl;
 -cout << "id=" << id << endl;
 -cout << "login=" << login << endl;
 -cout << "password=" << password << endl;
 -cout << "passive=" << passive << endl;
 -cout << "disabled=" << disabled << endl;
 -cout << "disabledDetailStat=" << disabledDetailStat << endl;
 -cout << "alwaysOnline=" << alwaysOnline << endl;
 -cout << "tariffName=" << tariffName << endl;
 -cout << "address=" << address << endl;
 -cout << "phone=" << phone << endl;
 -cout << "email=" << email << endl;
 -cout << "note=" << note << endl;
 -cout << "realName=" <<realName << endl;
 -cout << "group=" << group << endl;
 -cout << "credit=" << credit << endl;
 -cout << "nextTariff=" << nextTariff << endl;
 -cout << "userdata0" << userdata0 << endl;
 -cout << "userdata1" << userdata1 << endl;
 -cout << "creditExpire=" << creditExpire << endl;
 -cout << "ips=" << ips << endl;
 -cout << "------------------------" << endl;
 -cout << "up=" << up << endl;
 -cout << "down=" << down << endl;
 -cout << "cash=" << cash << endl;
 -cout << "freeMb=" << freeMb << endl;
 -cout << "lastCashAdd=" << lastCashAdd << endl;
 -cout << "lastCashAddTime=" << lastCashAddTime << endl;
 -cout << "passiveTime=" << passiveTime << endl;
 -cout << "lastActivityTime=" << lastActivityTime << endl;
 -cout << "============================================================" << endl;
 +std::cout << "============================================================" << std::endl;
 +std::cout << "id=" << id << std::endl;
 +std::cout << "login=" << login << std::endl;
 +std::cout << "password=" << password << std::endl;
 +std::cout << "passive=" << passive << std::endl;
 +std::cout << "disabled=" << disabled << std::endl;
 +std::cout << "disabledDetailStat=" << disabledDetailStat << std::endl;
 +std::cout << "alwaysOnline=" << alwaysOnline << std::endl;
 +std::cout << "tariffName=" << tariffName << std::endl;
 +std::cout << "address=" << address << std::endl;
 +std::cout << "phone=" << phone << std::endl;
 +std::cout << "email=" << email << std::endl;
 +std::cout << "note=" << note << std::endl;
 +std::cout << "realName=" <<realName << std::endl;
 +std::cout << "group=" << group << std::endl;
 +std::cout << "credit=" << credit << std::endl;
 +std::cout << "nextTariff=" << nextTariff << std::endl;
 +std::cout << "userdata0" << userdata0 << std::endl;
 +std::cout << "userdata1" << userdata1 << std::endl;
 +std::cout << "creditExpire=" << creditExpire << std::endl;
 +std::cout << "ips=" << ips << std::endl;
 +std::cout << "------------------------" << std::endl;
 +std::cout << "up=" << up << std::endl;
 +std::cout << "down=" << down << std::endl;
 +std::cout << "cash=" << cash << std::endl;
 +std::cout << "freeMb=" << freeMb << std::endl;
 +std::cout << "lastCashAdd=" << lastCashAdd << std::endl;
 +std::cout << "lastCashAddTime=" << lastCashAddTime << std::endl;
 +std::cout << "passiveTime=" << passiveTime << std::endl;
 +std::cout << "lastActivityTime=" << lastActivityTime << std::endl;
 +std::cout << "============================================================" << std::endl;
  }
  //-----------------------------------------------------------------------------
  void USER_IMPL::Run()
@@@ -821,11 -800,11 +821,11 @@@ if (settings->GetShowFeeInCash() || tar
  return (cash - tariff->GetFee() >= -credit);
  }
  //-----------------------------------------------------------------------------
 -string USER_IMPL::GetEnabledDirs()
 +std::string USER_IMPL::GetEnabledDirs()
  {
  //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -string dirs = "";
 +std::string dirs = "";
  for(int i = 0; i < DIR_NUM; i++)
      dirs += enabledDirs[i] ? "1" : "0";
  return dirs;
@@@ -908,13 -887,13 +908,13 @@@ IP_DIR_PAIR idp(ip, dir, port)
  IP_DIR_PAIR idp(ip, dir);
  #endif
  
 -map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
 +std::map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
  lb = traffStat.lower_bound(idp);
  if (lb == traffStat.end() || lb->first != idp)
      {
      traffStat.insert(lb,
 -                     pair<IP_DIR_PAIR, STAT_NODE>(idp,
 -                                                  STAT_NODE(len, 0, cost)));
 +                     std::make_pair(idp,
 +                                    STAT_NODE(len, 0, cost)));
      }
  else
      {
@@@ -999,13 -978,13 +999,13 @@@ IP_DIR_PAIR idp(ip, dir, port)
  IP_DIR_PAIR idp(ip, dir);
  #endif
  
 -map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
 +std::map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
  lb = traffStat.lower_bound(idp);
  if (lb == traffStat.end() || lb->first != idp)
      {
      traffStat.insert(lb,
 -                     pair<IP_DIR_PAIR, STAT_NODE>(idp,
 -                                                  STAT_NODE(0, len, cost)));
 +                     std::make_pair(idp,
 +                                    STAT_NODE(0, len, cost)));
      }
  else
      {
      }
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
 +void USER_IMPL::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -currIP.AddBeforeNotifier(n);
 +currIP.AddBeforeNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
 +void USER_IMPL::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -currIP.DelBeforeNotifier(n);
 +currIP.DelBeforeNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
 +void USER_IMPL::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -currIP.AddAfterNotifier(n);
 +currIP.AddAfterNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
 +void USER_IMPL::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -currIP.DelAfterNotifier(n);
 +currIP.DelAfterNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::AddConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE<bool> * n)
 +void USER_IMPL::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -connected.AddBeforeNotifier(n);
 +connected.AddBeforeNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::DelConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE<bool> * n)
 +void USER_IMPL::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -connected.DelBeforeNotifier(n);
 +connected.DelBeforeNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::AddConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE<bool> * n)
 +void USER_IMPL::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -connected.AddAfterNotifier(n);
 +connected.AddAfterNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
 -void USER_IMPL::DelConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE<bool> * n)
 +void USER_IMPL::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -connected.DelAfterNotifier(n);
 +connected.DelAfterNotifier(notifier);
  }
  //-----------------------------------------------------------------------------
  void USER_IMPL::OnAdd()
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd";
 +std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd";
  
  if (access(scriptOnAdd.c_str(), X_OK) == 0)
      {
 -    string scriptOnAddParams;
 +    std::string scriptOnAddParams;
      strprintf(&scriptOnAddParams,
              "%s \"%s\"",
              scriptOnAdd.c_str(),
@@@ -1088,11 -1067,11 +1088,11 @@@ void USER_IMPL::OnDelete(
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel";
 +std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel";
  
  if (access(scriptOnDel.c_str(), X_OK) == 0)
      {
 -    string scriptOnDelParams;
 +    std::string scriptOnDelParams;
      strprintf(&scriptOnDelParams,
              "%s \"%s\"",
              scriptOnDel.c_str(),
@@@ -1173,12 -1152,12 +1173,12 @@@ if (tms.tm_year % 4 == 0 && tms.tm_mon 
      secMonth += 24 * 3600;
      }
  
 -int dt = secMonth - passiveTime;
 +time_t dt = secMonth - passiveTime;
  
  if (dt < 0)
      dt = 0;
  
 -return double(dt) / (secMonth);
 +return static_cast<double>(dt) / secMonth;
  }
  //-----------------------------------------------------------------------------
  void USER_IMPL::SetPassiveTimeAsNewUser()
@@@ -1189,10 -1168,9 +1189,10 @@@ time_t t = stgTime
  struct tm tm;
  localtime_r(&t, &tm);
  int daysCurrMon = DaysInCurrentMonth();
 -double pt = (tm.tm_mday - 1) / (double)daysCurrMon;
 +double pt = tm.tm_mday - 1;
 +pt /= daysCurrMon;
  
 -passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
 +passiveTime = static_cast<time_t>(pt * 24 * 3600 * daysCurrMon);
  }
  //-----------------------------------------------------------------------------
  void USER_IMPL::MidnightResetSessionStat()
@@@ -1253,9 -1231,12 +1253,12 @@@ STG_LOCKER lock(&mutex, __FILE__, __LIN
  if (passive.ConstData() || tariff == NULL)
      return;
  
+ if (tariff->GetPeriod() != TARIFF::MONTH)
+     return;
  double fee = tariff->GetFee() / DaysInCurrentMonth();
  
 -if (fee == 0.0)
 +if (std::fabs(fee) < 1.0e-3)
      return;
  
  double c = cash;
@@@ -1272,10 -1253,6 +1275,10 @@@ switch (settings->GetFeeChargeType()
          if (c + credit >= fee)
              property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
          break;
 +    case 3:
 +        if (c >= 0)
 +            property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +        break;
      }
  ResetPassiveTime();
  }
@@@ -1287,6 -1264,9 +1290,9 @@@ STG_LOCKER lock(&mutex, __FILE__, __LIN
  if (tariff == NULL)
      return;
  
+ if (tariff->GetPeriod() != TARIFF::MONTH)
+     return;
  double passiveTimePart = 1.0;
  if (!settings->GetFullFee())
      {
@@@ -1304,7 -1284,7 +1310,7 @@@ double fee = tariff->GetFee() * passive
  
  ResetPassiveTime();
  
 -if (fee == 0.0)
 +if (std::fabs(fee) < 1.0e-3)
      {
      SetPrepaidTraff();
      return;
@@@ -1338,16 -1318,42 +1344,49 @@@ switch (settings->GetFeeChargeType()
              SetPrepaidTraff();
              }
          break;
 +    case 3:
 +        if (c >= 0)
 +            {
 +            property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +            SetPrepaidTraff();
 +            }
 +        break;
      }
  }
  //-----------------------------------------------------------------------------
+ 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)
@@@ -1376,9 -1382,9 +1415,9 @@@ els
          msg->header.repeat--;
          #ifndef DEBUG
          //TODO: gcc v. 4.x generate ICE on x86_64
 -        msg->header.lastSendTime = time(NULL);
 +        msg->header.lastSendTime = static_cast<int>(time(NULL));
          #else
 -        msg->header.lastSendTime = stgTime;
 +        msg->header.lastSendTime = static_cast<int>(stgTime);
          #endif
          if (store->AddMessage(msg, login))
              {
@@@ -1397,7 -1403,7 +1436,7 @@@ int USER_IMPL::SendMessage(STG_MSG & ms
  {
  // No lock `cause we are already locked from caller
  int ret = -1;
 -set<const AUTH*>::iterator it(authorizedBy.begin());
 +std::set<const AUTH*>::iterator it(authorizedBy.begin());
  while (it != authorizedBy.end())
      {
      if (!(*it++)->SendMessage(msg, currIP))
@@@ -1407,9 -1413,9 +1446,9 @@@ if (!ret
      {
  #ifndef DEBUG
      //TODO: gcc v. 4.x generate ICE on x86_64
 -    msg.header.lastSendTime = time(NULL);
 +    msg.header.lastSendTime = static_cast<int>(time(NULL));
  #else
 -    msg.header.lastSendTime = stgTime;
 +    msg.header.lastSendTime = static_cast<int>(stgTime);
  #endif
      msg.header.repeat--;
      }
@@@ -1470,43 -1476,6 +1509,43 @@@ while (it != messages.end()
      }
  }
  //-----------------------------------------------------------------------------
 +std::string USER_IMPL::GetParamValue(const std::string & name) const
 +{
 +if (name == "freeMb")       return property.freeMb.ToString();
 +if (name == "passive")      return property.passive.ToString();
 +if (name == "disabled")     return property.disabled.ToString();
 +if (name == "alwaysOnline") return property.alwaysOnline.ToString();
 +if (name == "tariffName")   return property.tariffName;
 +if (name == "nextTariff")   return property.nextTariff;
 +if (name == "address")      return property.address;
 +if (name == "note")         return property.note;
 +if (name == "group")        return property.group;
 +if (name == "email")        return property.email;
 +if (name == "phone")        return property.phone;
 +if (name == "realName")     return property.realName;
 +if (name == "credit")       return property.credit.ToString();
 +if (name == "userdata0")    return property.userdata0;
 +if (name == "userdata1")    return property.userdata1;
 +if (name == "userdata2")    return property.userdata2;
 +if (name == "userdata3")    return property.userdata3;
 +if (name == "userdata4")    return property.userdata4;
 +if (name == "userdata5")    return property.userdata5;
 +if (name == "userdata6")    return property.userdata6;
 +if (name == "userdata7")    return property.userdata7;
 +if (name == "userdata8")    return property.userdata8;
 +if (name == "userdata9")    return property.userdata9;
 +if (name == "cash")         return property.cash.ToString();
 +if (name == "id")
 +    {
 +    std::stringstream stream;
 +    stream << id;
 +    return stream.str();;
 +    }
 +if (name == "login")        return login;
 +if (name == "ip")           return currIP.ToString();
 +return "";
 +}
 +//-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
@@@ -1519,20 -1488,7 +1558,20 @@@ if (newPassive && !oldPassive && user->
                              "Freeze");
  }
  //-----------------------------------------------------------------------------
 -void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
 +void CHG_DISABLED_NOTIFIER::Notify(const int & oldValue, const int & newValue)
 +{
 +if (oldValue && !newValue && user->GetConnected())
 +    {
 +    user->Disconnect(false, "disabled");
 +    }
 +else if (!oldValue && newValue && user->IsInetable())
 +    {
 +    user->Connect(false);
 +    }
 +
 +}
 +//-----------------------------------------------------------------------------
 +void CHG_TARIFF_NOTIFIER::Notify(const std::string &, const std::string & newTariff)
  {
  if (user->settings->GetReconnectOnTariffChange() && user->connected)
      user->Disconnect(false, "Change tariff");
index 68945d2c65547efc9ef230ce3d9ef9810aaf4bcc,17623294548d208ab31452f19c7db131c5d53c33..90ae01b96669043dfd2a1facf3afa9e0f88668d7
  #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;
@@@ -70,16 -68,9 +70,16 @@@ public
      void Notify(const int & oldPassive, const int & newPassive);
  
  private:
 -    CHG_PASSIVE_NOTIFIER(const CHG_PASSIVE_NOTIFIER & rvalue);
 -    CHG_PASSIVE_NOTIFIER & operator=(const CHG_PASSIVE_NOTIFIER & rvalue);
 +    USER_IMPL * user;
 +};
 +//-----------------------------------------------------------------------------
 +class CHG_DISABLED_NOTIFIER : public PROPERTY_NOTIFIER_BASE<int>,
 +                             private NONCOPYABLE {
 +public:
 +    CHG_DISABLED_NOTIFIER(USER_IMPL * u) : user(u) {}
 +    void Notify(const int & oldValue, const int & newValue);
  
 +private:
      USER_IMPL * user;
  };
  //-----------------------------------------------------------------------------
@@@ -90,6 -81,9 +90,6 @@@ public
      void Notify(const std::string & oldTariff, const std::string & newTariff);
  
  private:
 -    CHG_TARIFF_NOTIFIER(const CHG_TARIFF_NOTIFIER & rvalue);
 -    CHG_TARIFF_NOTIFIER & operator=(const CHG_TARIFF_NOTIFIER & rvalue);
 -
      USER_IMPL * user;
  };
  //-----------------------------------------------------------------------------
@@@ -100,12 -94,18 +100,12 @@@ public
      void Notify(const double & oldCash, const double & newCash);
  
  private:
 -    CHG_CASH_NOTIFIER(const CHG_CASH_NOTIFIER & rvalue);
 -    CHG_CASH_NOTIFIER & operator=(const CHG_CASH_NOTIFIER & rvalue);
 -
      USER_IMPL * user;
  };
  //-----------------------------------------------------------------------------
  class CHG_IPS_NOTIFIER : public PROPERTY_NOTIFIER_BASE<USER_IPS>,
                           private NONCOPYABLE {
  public:
 -    CHG_IPS_NOTIFIER(const CHG_IPS_NOTIFIER & rvalue);
 -    CHG_IPS_NOTIFIER & operator=(const CHG_IPS_NOTIFIER & rvalue);
 -
      CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
      void Notify(const USER_IPS & oldIPs, const USER_IPS & newIPs);
  
@@@ -115,7 -115,6 +115,7 @@@ private
  //-----------------------------------------------------------------------------
  class USER_IMPL : public USER {
  friend class CHG_PASSIVE_NOTIFIER;
 +friend class CHG_DISABLED_NOTIFIER;
  friend class CHG_TARIFF_NOTIFIER;
  friend class CHG_CASH_NOTIFIER;
  friend class CHG_IPS_NOTIFIER;
@@@ -148,17 -147,17 +148,17 @@@ public
      uint32_t        GetCurrIP() const { return currIP; }
      time_t          GetCurrIPModificationTime() const { return currIP.ModificationTime(); }
  
 -    void            AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
 -    void            DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
 +    void            AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier);
 +    void            DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier);
  
 -    void            AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
 -    void            DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
 +    void            AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier);
 +    void            DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier);
  
 -    void            AddConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE<bool> *);
 -    void            DelConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE<bool> *);
 +    void            AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier);
 +    void            DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier);
  
 -    void            AddConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE<bool> *);
 -    void            DelConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE<bool> *);
 +    void            AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier);
 +    void            DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier);
  
      int             GetID() const { return id; }
  
  
      bool            GetConnected() const { return connected; }
      time_t          GetConnectedModificationTime() const { return connected.ModificationTime(); }
 -    int             GetAuthorized() const { return authorizedBy.size(); }
 +    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);
  
  
      const std::string & GetStrError() const { return errorStr; }
  
 -    USER_PROPERTIES & GetProperty() { return property; };
 -    const USER_PROPERTIES & GetProperty() const { return property; };
 +    USER_PROPERTIES & GetProperty() { return property; }
 +    const USER_PROPERTIES & GetProperty() const { return property; }
  
      void            SetDeleted() { deleted = true; }
      bool            GetDeleted() const { return deleted; }
      void            ProcessDayFee();
      void            ProcessDayFeeSpread();
      void            ProcessNewMonth();
+     void            ProcessDailyFee();
  
      bool            IsInetable();
      std::string     GetEnabledDirs();
      void            OnAdd();
      void            OnDelete();
  
 +    virtual std::string GetParamValue(const std::string & name) const;
 +
  private:
      USER_IMPL & operator=(const USER_IMPL & rvalue);
  
      int             id;
      bool            __connected;
      USER_PROPERTY<bool> connected;
 +    std::string     lastDisconnectReason;
  
      bool            enabledDirs[DIR_NUM];
  
      USER_PROPERTY<uint32_t> currIP;
  
      uint32_t        lastIPForDisconnect; // User's ip after unauth but before disconnect
 +    std::string     lastDisconnectReason;
  
      time_t          pingTime;
  
  #endif
  
      std::set<const AUTH *> authorizedBy;
 +    time_t          authorizedModificationTime;
  
      std::list<STG_MSG> messages;
  
      DIR_TRAFF                sessionDownload;
  
      CHG_PASSIVE_NOTIFIER     passiveNotifier;
 +    CHG_DISABLED_NOTIFIER    disabledNotifier;
      CHG_TARIFF_NOTIFIER      tariffNotifier;
      CHG_CASH_NOTIFIER        cashNotifier;
      CHG_IPS_NOTIFIER         ipNotifier;
index 4c4d4ce03e4c0dcb9f9c360ea0676f492f49a357,dfcc556fbf87726ae1e1a20986e7b4d601b68928..f4b4dea0b800420259afb1caef46753936398332
@@@ -46,7 -46,9 +46,7 @@@
  #include "users_impl.h"
  #include "stg_timer.h"
  
 -using namespace std;
 -
 -extern const volatile time_t stgTime;
 +extern volatile time_t stgTime;
  
  //#define USERS_DEBUG 1
  
@@@ -86,50 -88,34 +86,50 @@@ USERS_IMPL::~USERS_IMPL(
  pthread_mutex_destroy(&mutex);
  }
  //-----------------------------------------------------------------------------
 -int USERS_IMPL::FindByNameNonLock(const string & login, user_iter * user)
 +int USERS_IMPL::FindByNameNonLock(const std::string & login, user_iter * user)
  {
 -map<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 string & login, USER_PTR * user)
 +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;
  }
  //-----------------------------------------------------------------------------
 -bool USERS_IMPL::TariffInUse(const string & tariffName) const
 +bool USERS_IMPL::TariffInUse(const std::string & tariffName) const
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 -list<USER_IMPL>::const_iterator iter;
 +std::list<USER_IMPL>::const_iterator iter;
  iter = users.begin();
  while (iter != users.end())
      {
  return false;
  }
  //-----------------------------------------------------------------------------
 -int USERS_IMPL::Add(const string & login, const ADMIN * admin)
 +int USERS_IMPL::Add(const std::string & login, const ADMIN * admin)
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  const PRIV * priv = admin->GetPriv();
@@@ -198,7 -184,7 +198,7 @@@ AddUserIntoIndexes(users.begin())
  
      {
      // Fire all "on add" notifiers
 -    set<NOTIFIER_BASE<USER_PTR> *>::iterator ni = onAddNotifiers.begin();
 +    std::set<NOTIFIER_BASE<USER_PTR> *>::iterator ni = onAddNotifiers.begin();
      while (ni != onAddNotifiers.end())
          {
          (*ni)->Notify(&users.front());
  
      {
      // Fire all "on add" implementation notifiers
 -    set<NOTIFIER_BASE<USER_IMPL_PTR> *>::iterator ni = onAddNotifiersImpl.begin();
 +    std::set<NOTIFIER_BASE<USER_IMPL_PTR> *>::iterator ni = onAddNotifiersImpl.begin();
      while (ni != onAddNotifiersImpl.end())
          {
          (*ni)->Notify(&users.front());
  return 0;
  }
  //-----------------------------------------------------------------------------
 -void USERS_IMPL::Del(const string & login, const ADMIN * admin)
 +void USERS_IMPL::Del(const std::string & login, const ADMIN * admin)
  {
  const PRIV * priv = admin->GetPriv();
  user_iter u;
@@@ -247,7 -233,7 +247,7 @@@ if (!priv->userAddDel
      }
  
      {
 -    set<NOTIFIER_BASE<USER_PTR> *>::iterator ni = onDelNotifiers.begin();
 +    std::set<NOTIFIER_BASE<USER_PTR> *>::iterator ni = onDelNotifiers.begin();
      while (ni != onDelNotifiers.end())
          {
          (*ni)->Notify(&(*u));
      }
  
      {
 -    set<NOTIFIER_BASE<USER_IMPL_PTR> *>::iterator ni = onDelNotifiersImpl.begin();
 +    std::set<NOTIFIER_BASE<USER_IMPL_PTR> *>::iterator ni = onDelNotifiersImpl.begin();
      while (ni != onDelNotifiersImpl.end())
          {
          (*ni)->Notify(&(*u));
@@@ -314,9 -300,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__);
@@@ -328,7 -312,7 +328,7 @@@ if (FindByNameNonLock(login, &iter)
  
  uint32_t ip = iter->GetCurrIP();
  
 -iter->Unauthorize(auth);
 +iter->Unauthorize(auth, reason);
  
  if (!iter->GetAuthorized())
      DelFromIPIdx(ip);
@@@ -338,7 -322,7 +338,7 @@@ return true
  //-----------------------------------------------------------------------------
  int USERS_IMPL::ReadUsers()
  {
 -vector<string> usersList;
 +std::vector<std::string> usersList;
  usersList.clear();
  if (store->GetUsersList(&usersList) < 0)
      {
@@@ -387,7 -371,7 +387,7 @@@ int day = t.tm_mday
  printfd(__FILE__,"Day = %d Min = %d\n", day, min);
  
  time_t touchTime = stgTime - MONITOR_TIME_DELAY_SEC;
 -string monFile = us->settings->GetMonitorDir() + "/users_r";
 +std::string monFile = us->settings->GetMonitorDir() + "/users_r";
  printfd(__FILE__, "Monitor=%d file USERS %s\n", us->settings->GetMonitoring(), monFile.c_str());
  
  us->isRunning = true;
@@@ -396,7 -380,7 +396,7 @@@ while (us->nonstop
      //printfd(__FILE__,"New Minute. old = %02d current = %02d\n", min, t->tm_min);
      //printfd(__FILE__,"New Day.    old = %2d current = %2d\n", day, t->tm_mday);
  
 -    for_each(us->users.begin(), us->users.end(), mem_fun_ref(&USER_IMPL::Run));
 +    for_each(us->users.begin(), us->users.end(), std::mem_fun_ref(&USER_IMPL::Run));
  
      tt = stgTime;
      localtime_r(&tt, &t);
@@@ -435,7 -419,7 +435,7 @@@ while (ui != us->users.end()
      ++ui;
      }
  
 -list<USER_TO_DEL>::iterator iter;
 +std::list<USER_TO_DEL>::iterator iter;
  iter = us->usersToDelete.begin();
  while (iter != us->usersToDelete.end())
      {
@@@ -455,7 -439,7 +455,7 @@@ void USERS_IMPL::NewMinute(const struc
  if (t.tm_hour == 23 && t.tm_min == 59)
      {
      printfd(__FILE__,"MidnightResetSessionStat\n");
 -    for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::MidnightResetSessionStat));
 +    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::MidnightResetSessionStat));
      }
  
  if (TimeToWriteDetailStat(t))
      int usersCnt = 0;
  
      // ðÉÛÅÍ ÀÚÅÒÏ× ÞÁÓÔÑÍÉ. ÷ ÐÅÒÅÒÙ×ÁÈ ×ÙÚÙ×ÁÅÍ USER::Run
 -    list<USER_IMPL>::iterator usr = users.begin();
 +    std::list<USER_IMPL>::iterator usr = users.begin();
      while (usr != users.end())
          {
          usersCnt++;
          usr->WriteDetailStat();
          ++usr;
          if (usersCnt % 10 == 0)
 -            for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::Run));
 +            for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::Run));
          }
      }
  
@@@ -502,17 -486,19 +502,19 @@@ if (!settings->GetDayFeeIsLastDay()
  if (settings->GetSpreadFee())
      {
      printfd(__FILE__, "Spread DayFee\n");
 -    for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::ProcessDayFeeSpread));
 +    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDayFeeSpread));
      }
  else
      {
      if (t.tm_mday == dayFee)
          {
          printfd(__FILE__, "DayFee\n");
 -        for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::ProcessDayFee));
 +        for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDayFee));
          }
      }
  
+ std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee));
  if (settings->GetDayFeeIsLastDay())
      {
      printfd(__FILE__, "DayResetTraff - 2 -\n");
@@@ -528,7 -514,7 +530,7 @@@ if (dayResetTraff == 0
  if (t1.tm_mday == dayResetTraff)
      {
      printfd(__FILE__, "ResetTraff\n");
 -    for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::ProcessNewMonth));
 +    for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessNewMonth));
      //for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::SetPrepaidTraff));
      }
  }
@@@ -587,15 -573,15 +589,15 @@@ if (isRunning
      }
  
  printfd(__FILE__, "Before USERS::Run()\n");
 -for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::Run));
 +for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::Run));
  
  // 'cause bind2st accepts only constant first param
 -for (list<USER_IMPL>::iterator it = users.begin();
 +for (std::list<USER_IMPL>::iterator it = users.begin();
       it != users.end();
       ++it)
      it->WriteDetailStat(true);
  
 -for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::WriteStat));
 +for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::WriteStat));
  //for_each(users.begin(), users.end(), mem_fun_ref(&USER_IMPL::WriteConf));
  
  printfd(__FILE__, "USERS::Stop()\n");
@@@ -608,7 -594,7 +610,7 @@@ STG_LOCKER lock(&mutex, __FILE__, __LIN
  
  printfd(__FILE__, "RealDelUser() users to del: %d\n", usersToDelete.size());
  
 -list<USER_TO_DEL>::iterator iter;
 +std::list<USER_TO_DEL>::iterator iter;
  iter = usersToDelete.begin();
  while (iter != usersToDelete.end())
      {
@@@ -641,7 -627,7 +643,7 @@@ if (!ip
  
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -const map<uint32_t, user_iter>::iterator it(
 +const std::map<uint32_t, user_iter>::iterator it(
          ipIndex.lower_bound(ip)
  );
  
@@@ -657,7 -643,7 +659,7 @@@ assert(ip && "User has non-null ip")
  
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -const map<uint32_t, user_iter>::iterator it(
 +const std::map<uint32_t, user_iter>::iterator it(
          ipIndex.find(ip)
  );
  
@@@ -669,7 -655,7 +671,7 @@@ ipIndex.erase(it)
  //-----------------------------------------------------------------------------
  bool USERS_IMPL::FindByIPIdx(uint32_t ip, user_iter & iter) const
  {
 -map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
 +std::map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
  if (it == ipIndex.end())
      return false;
  iter = it->second;
@@@ -708,31 -694,11 +710,31 @@@ bool USERS_IMPL::IsIPInIndex(uint32_t i
  {
  STG_LOCKER lock(&mutex, __FILE__, __LINE__);
  
 -map<uint32_t, user_iter>::const_iterator it(ipIndex.find(ip));
 +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__);