namespace
  {
  PLUGIN_CREATOR<FILES_STORE> fsc;
 +
 +bool CheckAndCreate(const std::string & dir, mode_t mode)
 +{
 +if (access(dir.c_str(), F_OK) == 0)
 +    return true;
 +if (mkdir(dir.c_str(), mode) == 0)
 +    return true;
 +return false;
 +}
 +
  }
  
  extern "C" STORE * GetStore();
      workDir.resize(workDir.size() - 1);
      }
  usersDir = workDir + "/users/";
 +if (!CheckAndCreate(usersDir, GetConfModeDir()))
 +    {
 +    errorStr = usersDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  tariffsDir = workDir + "/tariffs/";
 +if (!CheckAndCreate(tariffsDir, GetConfModeDir()))
 +    {
 +    errorStr = tariffsDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  adminsDir = workDir + "/admins/";
 +if (!CheckAndCreate(adminsDir, GetConfModeDir()))
 +    {
 +    errorStr = adminsDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
 +servicesDir = workDir + "/services/";
 +if (!CheckAndCreate(servicesDir, GetConfModeDir()))
 +    {
 +    errorStr = servicesDir + " doesn't exist. Failed to create.";
 +    printfd(__FILE__, "%s\n", errorStr.c_str());
 +    return -1;
 +    }
  
  return 0;
  }
  
  tariffList->swap(files);
  
 +return 0;
 +}
 +//-----------------------------------------------------------------------------
 +int FILES_STORE::GetServicesList(std::vector<std::string> * list) const
 +{
 +std::vector<std::string> files;
 +
 +if (GetFileList(&files, storeSettings.GetServicesDir(), S_IFREG, ".serv"))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Failed to open '" + storeSettings.GetServicesDir() + "': " + std::string(strerror(errno));
 +    return -1;
 +    }
 +
 +STG_LOCKER lock(&mutex);
 +
 +list->swap(files);
 +
  return 0;
  }
  //-----------------------------------------------------------------------------
      td->tariffConf.period = TARIFF::MONTH;
  else
      td->tariffConf.period = TARIFF::StringToPeriod(str);
+ 
+ if (conf.ReadString("ChangePolicy", &str, "allow") < 0)
+     td->tariffConf.changePolicy = TARIFF::ALLOW;
+ else
+     td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
+ 
+ if (conf.ReadString("ChangePolicyTimeout", &str, "1970-01-01 00:00:00") < 0)
+     td->tariffConf.changePolicyTimeout = 0;
+ else
+     td->tariffConf.changePolicyTimeout = readTime(str);
  return 0;
  }
  //-----------------------------------------------------------------------------
      cf.WriteDouble("Free", td.tariffConf.free);
      cf.WriteString("TraffType", TARIFF::TraffTypeToString(td.tariffConf.traffType));
      cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period));
+     cf.WriteString("ChangePolicy", TARIFF::ChangePolicyToString(td.tariffConf.changePolicy));
+     cf.WriteTime("ChangePolicyTimeout", td.tariffConf.changePolicyTimeout);
      }
  
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::AddService(const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +
 +if (Touch(fileName))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Cannot create file " + fileName;
 +    printfd(__FILE__, "FILES_STORE::AddService - failed to add service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::DelService(const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +if (unlink(fileName.c_str()))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "unlink failed. Message: '";
 +    errorStr += strerror(errno);
 +    errorStr += "'";
 +    printfd(__FILE__, "FILES_STORE::DelAdmin - unlink failed. Message: '%s'\n", strerror(errno));
 +    }
 +return 0;
 +}
 +//-----------------------------------------------------------------------------*/
 +int FILES_STORE::SaveService(const SERVICE_CONF & conf) const
 +{
 +std::string fileName;
 +
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), conf.name.c_str());
 +
 +    {
 +    CONFIGFILE cf(fileName, true);
 +
 +    int e = cf.Error();
 +
 +    if (e)
 +        {
 +        STG_LOCKER lock(&mutex);
 +        errorStr = "Cannot write service " + conf.name + ". " + fileName;
 +        printfd(__FILE__, "FILES_STORE::SaveService - failed to save service '%s'\n", conf.name.c_str());
 +        return -1;
 +        }
 +
 +    cf.WriteString("name", conf.name);
 +    cf.WriteString("comment", conf.comment);
 +    cf.WriteDouble("cost", conf.cost);
 +    cf.WriteInt("pay_day", conf.payDay);
 +    }
 +
 +return 0;
 +}
 +//-----------------------------------------------------------------------------
 +int FILES_STORE::RestoreService(SERVICE_CONF * conf, const std::string & name) const
 +{
 +std::string fileName;
 +strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
 +CONFIGFILE cf(fileName);
 +
 +if (cf.Error())
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Cannot open " + fileName;
 +    printfd(__FILE__, "FILES_STORE::RestoreService - failed to restore service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadString("name", &conf->name, name))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'name'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - name read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadString("comment", &conf->comment, ""))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'comment'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - comment read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +if (cf.ReadDouble("cost", &conf->cost, 0.0))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'cost'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - cost read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +
 +unsigned short value = 0;
 +if (cf.ReadUShortInt("pay_day", &value, 0))
 +    {
 +    STG_LOCKER lock(&mutex);
 +    errorStr = "Error in parameter 'pay_day'";
 +    printfd(__FILE__, "FILES_STORE::RestoreService - pay day read failed for service '%s'\n", name.c_str());
 +    return -1;
 +    }
 +conf->payDay = value;
 +
  return 0;
  }
  //-----------------------------------------------------------------------------
 
      int32_t id;
      st->Get(1, id);
      st->Close();
+ 
+     std::string query = "update tb_tariffs set \
+                             fee = ?, \
+                             free = ?, \
+                             passive_cost = ?, \
+                             traff_type = ?";
+ 
+     if (schemaVersion > 0)
+         query += ", period = ?";
+     if (schemaVersion > 1)
+         query += ", change_policy = ?, \
+                     change_policy_timeout = ?";
+ 
+     query += " where pk_tariff = ?";
+ 
+     unsigned num = 5;
+     st->Prepare(query);
+     st->Set(1, td.tariffConf.fee);
+     st->Set(2, td.tariffConf.free);
+     st->Set(3, td.tariffConf.passiveCost);
+     st->Set(4, td.tariffConf.traffType);
+ 
      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);
+         ++num;
          }
-     else
+ 
+     if (schemaVersion > 1)
          {
-         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->Set(6, TARIFF::ChangePolicyToString(td.tariffConf.changePolicy));
+         IBPP::Timestamp policyTimeout;
+         time_t2ts(td.tariffConf.changePolicyTimeout, &policyTimeout);
+         st->Set(7, policyTimeout);
+         num += 2;
          }
+ 
+     st->Set(num, id);
      st->Execute();
      st->Close();
  
      st->Get(3, td->tariffConf.fee);
      st->Get(4, td->tariffConf.free);
      st->Get(5, td->tariffConf.passiveCost);
 -    //st->Get(6, td->tariffConf.traffType);
      td->tariffConf.traffType = TARIFF::IntToTraffType(Get<int>(st, 6));
      if (schemaVersion > 0)
          td->tariffConf.period = TARIFF::StringToPeriod(Get<std::string>(st, 7));
+     if (schemaVersion > 1)
+         {
+         td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(Get<std::string>(st, 8));
+         td->tariffConf.changePolicyTimeout = ts2time_t(Get<IBPP::Timestamp>(st, 9));
+         }
      st->Close();
      st->Prepare("select * from tb_tariffs_params where fk_tariff = ?");
      st->Set(1, id);
 
  
  #include <libpq-fe.h>
  
+ #include "stg/common.h"
  #include "stg/const.h"
  #include "stg/locker.h"
  #include "../../../stg_timer.h"
  query << "UPDATE tb_users SET "
              "cash = " << stat.cash << ", "
              "free_mb = " << stat.freeMb << ", "
-             "last_activity_time = CAST('" << Int2TS(stat.lastActivityTime) << "' AS TIMESTAMP), "
+             "last_activity_time = CAST('" << formatTime(stat.lastActivityTime) << "' AS TIMESTAMP), "
              "last_cash_add = " << stat.lastCashAdd << ", "
-             "last_cash_add_time = CAST('" << Int2TS(stat.lastCashAddTime) << "' AS TIMESTAMP), "
+             "last_cash_add_time = CAST('" << formatTime(stat.lastCashAddTime) << "' AS TIMESTAMP), "
              "passive_time = " << stat.passiveTime << " "
           "WHERE name = '" << elogin << "'";
  
               "address = '" << eaddress << "', "
               "always_online = " << (conf.alwaysOnline ? "'t'" : "'f'") << ", "
               "credit = " << conf.credit << ", "
-              "credit_expire = CAST('" << Int2TS(conf.creditExpire) << "' AS TIMESTAMP), "
+              "credit_expire = CAST('" << formatTime(conf.creditExpire) << "' AS TIMESTAMP), "
               "disabled = " << (conf.disabled ? "'t'" : "'f'") << ", "
               "disabled_detail_stat = " << (conf.disabledDetailStat ? "'t'" : "'f'") << ", "
               "email = '" << eemail << "', "
  
  PQclear(result);
  
 -if (SaveUserServices(uid, conf.service))
 +if (SaveUserServices(uid, conf.services))
      {
      printfd(__FILE__, "POSTGRESQL_STORE::SaveUserConf(): 'Failed to save user's services'\n");
      if (RollbackTransaction())
      std::stringstream tuple;
      tuple << PQgetvalue(result, 0, 0) << " ";
      tuple << PQgetvalue(result, 0, 1) << " ";
-     stat->lastActivityTime = TS2Int(PQgetvalue(result, 0, 2));
+     stat->lastActivityTime = readTime(PQgetvalue(result, 0, 2));
      tuple << PQgetvalue(result, 0, 3) << " ";
-     stat->lastCashAddTime = TS2Int(PQgetvalue(result, 0, 4));
+     stat->lastCashAddTime = readTime(PQgetvalue(result, 0, 4));
      tuple << PQgetvalue(result, 0, 5) << " ";
  
      PQclear(result);
      query << "SELECT dir_num, upload, download "
               "FROM tb_stats_traffic "
               "WHERE fk_user IN (SELECT pk_user FROM tb_users WHERE name = '" << elogin << "') AND "
-                    "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP))";
+                    "DATE_TRUNC('month', stats_date) = DATE_TRUNC('month', CAST('" << formatTime(stgTime) << "' AS TIMESTAMP))";
  
      result = PQexec(connection, query.str().c_str());
      }
      conf->address = PQgetvalue(result, 0, 1);               // address
      conf->alwaysOnline = !strncmp(PQgetvalue(result, 0, 2), "t", 1);
      tuple << PQgetvalue(result, 0, 3) << " ";               // credit
-     conf->creditExpire = TS2Int(PQgetvalue(result, 0, 4));  // creditExpire
+     conf->creditExpire = readTime(PQgetvalue(result, 0, 4));  // creditExpire
      conf->disabled = !strncmp(PQgetvalue(result, 0, 5), "t", 1);
      conf->disabledDetailStat = !strncmp(PQgetvalue(result, 0, 6), "t", 1);
      conf->email = PQgetvalue(result, 0, 7);                 // email
  
  for (int i = 0; i < tuples; ++i)
      {
 -    conf->service.push_back(PQgetvalue(result, i, 0));
 +    conf->services.push_back(PQgetvalue(result, i, 0));
      }
  
  PQclear(result);
              "'" << eadminLogin << "', CAST('"
              << inet_ntostring(admIP) << "/32' AS INET), "
              "'" << eparam << "', "
-             "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
+             "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
              "'" << eold << "', "
              "'" << enew << "', "
              "'" << emessage << "')";
      {
      query << "SELECT sp_add_session_log_entry("
                   "'" << elogin << "', "
-                  "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
+                  "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
                   "'c', CAST('"
                   << inet_ntostring(ip) << "/32' AS INET), 0)";
      }
      {
      query << "SELECT sp_add_session_log_entry("
                   "'" << elogin << "', "
-                  "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
+                  "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
                   "'c', CAST('"
                   << inet_ntostring(ip) << "/32' AS INET), 0, 0, '')";
      }
          // Old database version - no freeMb logging support
          query << "SELECT sp_add_session_log_entry("
                      "'" << elogin << "', "
-                     "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
+                     "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
                      "'d', CAST('0.0.0.0/0' AS INET), "
                      << cash << ")";
          }
          {
          query << "SELECT sp_add_session_log_entry("
                      "'" << elogin << "', "
-                     "CAST('" << Int2TS(stgTime) << "' AS TIMESTAMP), "
+                     "CAST('" << formatTime(stgTime) << "' AS TIMESTAMP), "
                      "'d', CAST('0.0.0.0/0' AS INET), "
                      << cash << ", " << freeMb << ", '" << ereason << "')";
          }
                  "(till_time, from_time, fk_user, "
                   "dir_num, ip, download, upload, cost) "
               "VALUES ("
-                 "CAST('" << Int2TS(currTime) << "' AS TIMESTAMP), "
-                 "CAST('" << Int2TS(lastStat) << "' AS TIMESTAMP), "
+                 "CAST('" << formatTime(currTime) << "' AS TIMESTAMP), "
+                 "CAST('" << formatTime(lastStat) << "' AS TIMESTAMP), "
                  "(SELECT pk_user FROM tb_users WHERE name = '" << elogin << "'), "
                  << it->first.dir << ", "
                  << "CAST('" << inet_ntostring(it->first.ip) << "' AS INET), "
 
   *
   */
  
 +#include "postgresql_store.h"
 +
 +#include "stg/common.h"
 +
  #include <string>
  #include <ctime>
  
  #include <libpq-fe.h>
  
 -#include "stg/common.h"
 -#include "postgresql_store.h"
 -
  extern volatile time_t stgTime;
  
  int POSTGRESQL_STORE::StartTransaction() const
  char * buf = new char[(value.length() << 1) + 1];
  
  PQescapeStringConn(connection,
 -                 buf,
 -                 value.c_str(),
 -                 value.length(),
 -                 &error);
 +                   buf,
 +                   value.c_str(),
 +                   value.length(),
 +                   &error);
  
  if (error)
      {
  return 0;
  }
  
- std::string POSTGRESQL_STORE::Int2TS(time_t ts) const
- {
- struct tm brokenTime;
- 
- brokenTime.tm_wday = 0;
- brokenTime.tm_yday = 0;
- brokenTime.tm_isdst = 0;
- 
- gmtime_r(&ts, &brokenTime);
- 
- char buf[32];
- strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &brokenTime);
- 
- return buf;
- }
- 
- time_t POSTGRESQL_STORE::TS2Int(const std::string & ts) const
- {
- struct tm brokenTime;
- 
- brokenTime.tm_wday = 0;
- brokenTime.tm_yday = 0;
- brokenTime.tm_isdst = 0;
- 
- stg_strptime(ts.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime);
- 
- return stg_timegm(&brokenTime);
- }
- 
  void POSTGRESQL_STORE::MakeDate(std::string & date, int year, int month) const
  {
  struct tm brokenTime;
  else
      {
      time_t curTime = stgTime;
 -    /*time(&curTime);*/
 -
      localtime_r(&curTime, &brokenTime);
      }
  
  
  date = buf;
  }
 -
 
      {
      const TARIFF * nt = tariffs->FindByName(nextTariff);
      if (nt == NULL)
+         {
          WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
                       login.c_str(), property.tariffName.Get().c_str());
+         }
      else
-         property.tariffName.Set(nextTariff, sysAdmin, login, store);
+         {
+         std::string message = tariff->TariffChangeIsAllowed(*nt, stgTime);
+         if (message.empty())
+             {
+             property.tariffName.Set(nextTariff, sysAdmin, login, store);
+             }
+         else
+             {
+             WriteServLog("Tariff change is prohibited for user %s. %s",
+                          login.c_str(),
+                          message.c_str());
+             }
+         }
      ResetNextTariff();
      WriteConf();
      }
  ResetPassiveTime();
  }
  //-----------------------------------------------------------------------------
 +void USER_IMPL::ProcessServices()
 +{
 +struct tm tms;
 +time_t t = stgTime;
 +localtime_r(&t, &tms);
 +
 +double passiveTimePart = 1.0;
 +if (!settings->GetFullFee())
 +    {
 +    passiveTimePart = GetPassiveTimePart();
 +    }
 +else
 +    {
 +    if (passive.ConstData())
 +        {
 +        printfd(__FILE__, "Don't charge fee `cause we are passive\n");
 +        return;
 +        }
 +    }
 +
 +for (size_t i = 0; i < property.Conf().services.size(); ++i)
 +    {
 +    SERVICE_CONF conf;
 +    if (m_services.Find(property.Conf().services[i], &conf))
 +        continue;
 +    if (conf.payDay == tms.tm_mday ||
 +        (conf.payDay == 0 && tms.tm_mday == DaysInCurrentMonth()))
 +        {
 +        double c = cash;
 +        double fee = conf.cost * passiveTimePart;
 +        printfd(__FILE__, "Service fee. login: %8s Cash=%f Credit=%f  Fee=%f PassiveTimePart=%f fee=%f\n",
 +                login.c_str(),
 +                cash.ConstData(),
 +                credit.ConstData(),
 +                tariff->GetFee(),
 +                passiveTimePart,
 +                fee);
 +        switch (settings->GetFeeChargeType())
 +            {
 +            case 0:
 +                property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                SetPrepaidTraff();
 +                break;
 +            case 1:
 +                if (c + credit >= 0)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            case 2:
 +                if (c + credit >= fee)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            case 3:
 +                if (c >= 0)
 +                    {
 +                    property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
 +                    SetPrepaidTraff();
 +                    }
 +                break;
 +            }
 +        }
 +    }
 +}
 +//-----------------------------------------------------------------------------
  void USER_IMPL::SetPrepaidTraff()
  {
  if (tariff != NULL)
 
      return result;
  }
  //-----------------------------------------------------------------------------
 +std::string TimeToString(time_t time)
 +{
 +struct tm brokenTime;
 +
 +brokenTime.tm_wday = 0;
 +brokenTime.tm_yday = 0;
 +brokenTime.tm_isdst = 0;
 +
 +gmtime_r(&time, &brokenTime);
 +
 +char buf[32];
 +strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &brokenTime);
 +
 +return buf;
 +}
 +//-----------------------------------------------------------------------------
  int ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2)
  {
  char hs1[10], ms1[10], hs2[10], ms2[10];
      value = temp;
  }
  //---------------------------------------------------------------------------
+ std::string formatTime(time_t ts)
+ {
+ char buf[32];
+ struct tm brokenTime;
+ 
+ brokenTime.tm_wday = 0;
+ brokenTime.tm_yday = 0;
+ brokenTime.tm_isdst = 0;
+ 
+ gmtime_r(&ts, &brokenTime);
+ 
+ strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &brokenTime);
+ 
+ return buf;
+ }
+ //---------------------------------------------------------------------------
+ time_t readTime(const std::string & ts)
+ {
+ if (ts == "0000-00-00 00:00:00")
+     return 0;
+ 
+ struct tm brokenTime;
+ 
+ brokenTime.tm_wday = 0;
+ brokenTime.tm_yday = 0;
+ brokenTime.tm_isdst = 0;
+ 
+ stg_strptime(ts.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime);
+ 
+ return stg_timegm(&brokenTime);
+ }
+ //---------------------------------------------------------------------------
  int str2x(const std::string & str, int32_t & x)
  {
  x = static_cast<int32_t>(strtol(str.c_str(), NULL, 10));
  
  return 0;
  }
 -//---------------------------------------------------------------------------
 -int str2x(const std::string & str, double & x)
 -{
 -return strtodouble2(str.c_str(), x);
 -}
  #ifndef WIN32
  //---------------------------------------------------------------------------
  int str2x(const std::string & str, int64_t & x)
  return TrimR(TrimL(val));
  }
  //---------------------------------------------------------------------------
 +std::string Trim(const std::string & val)
 +{
 +std::string res(val);
 +return TrimR(TrimL(res));
 +}
 +//---------------------------------------------------------------------------
  std::string ToLower(std::string value)
  {
      std::transform(value.begin(), value.end(), value.begin(), ::tolower);
 
  #include <time.h>
  #else
  #include <ctime>
+ #include <climits> // NAME_MAX
  #endif
  #include <string>
  #include <sstream>
  const char    * LogDate(time_t t);
  int             ParesTimeStat(const char * str);
  int             IsTimeStat(struct tm * t, int statTime);
 -/*bool            IsDigit(char c);
 -bool            IsAlpha(char c);*/
 -int             strtodouble2(const char * s, double &a);
 +int             strtodouble2(const char * str, double & value);
 +inline int      strtodouble2(const std::string & str, double & value) { return strtodouble2(str.c_str(), value); }
  int             printfd(const char * __file__, const char * fmt, ...);
  void            Encode12(char * dst, const char * src, size_t srcLen);
  void            Decode21(char * dst, const char * src);
  int             DaysInMonth(unsigned year, unsigned mon);
  int             DaysInCurrentMonth();
  int             Min8(int a);
 -//char          * inet_ntostr(unsigned long);
  std::string     inet_ntostring(uint32_t);
  uint32_t        inet_strington(const std::string & value);
 +std::string     TimeToString(time_t time);
  int             strprintf(std::string * str, const char * fmt, ...);
  int             ParseTariffTimeStr(const char * str, int &h1, int &m1, int &h2, int &m2);
  uint32_t        CalcMask(uint32_t msk);
  std::string &   TrimL(std::string & val);
  std::string &   TrimR(std::string & val);
  std::string &   Trim(std::string & val);
 +std::string     Trim(const std::string & val);
  
 -std::string ToLower(std::string value);
 -std::string ToUpper(std::string value);
 +std::string     ToLower(std::string value);
 +std::string     ToUpper(std::string value);
  
  template <typename C, typename F>
 +inline
  C Split(const std::string & value, char delim, F conv)
  {
  C res;
  }
  
  template <typename T>
 +inline
  T FromString(const std::string & value)
  {
  T res;
  return res;
  }
  
 +template <>
 +inline
 +std::string FromString<std::string>(const std::string & value)
 +{
 +return value;
 +}
 +
  template <typename C>
 +inline
  C Split(const std::string & value, char delim)
  {
 -    return Split<C>(value, delim, FromString);
 +    return Split<C>(value, delim, FromString<typename C::value_type>);
  }
  
  std::string IconvString(const std::string & source, const std::string & from, const std::string & to);
  
  std::string ToPrintable(const std::string & src);
  
+ std::string formatTime(time_t value);
+ time_t readTime(const std::string & value);
  //-----------------------------------------------------------------------------
  int str2x(const std::string & str, int32_t & x);
  int str2x(const std::string & str, uint32_t & x);
 -int str2x(const std::string & str, double & x);
 +inline
 +int str2x(const std::string & str, double & x) { return strtodouble2(str.c_str(), x); }
  #ifndef WIN32
  int str2x(const std::string & str, int64_t & x);
  int str2x(const std::string & str, uint64_t & x);
          x += str[i] - '0';
      }
  
 -    x*= minus;
 +    x *= minus;
  
      return 0;
  }