2  *    This program is free software; you can redistribute it and/or modify
 
   3  *    it under the terms of the GNU General Public License as published by
 
   4  *    the Free Software Foundation; either version 2 of the License, or
 
   5  *    (at your option) any later version.
 
   7  *    This program is distributed in the hope that it will be useful,
 
   8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
   9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  10  *    GNU General Public License for more details.
 
  12  *    You should have received a copy of the GNU General Public License
 
  13  *    along with this program; if not, write to the Free Software
 
  14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
  18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
 
  23  $Date: 2010/10/07 19:53:11 $
 
  46 #include "stg/common.h"
 
  47 #include "stg/user_ips.h"
 
  48 #include "stg/user_conf.h"
 
  49 #include "stg/user_stat.h"
 
  50 #include "stg/const.h"
 
  51 #include "stg/blowfish.h"
 
  52 #include "stg/logger.h"
 
  53 #include "stg/locker.h"
 
  54 #include "stg/plugin_creator.h"
 
  55 #include "file_store.h"
 
  57 #define DELETED_USERS_DIR   "deleted_users"
 
  59 #define adm_enc_passwd "cjeifY8m3"
 
  61 int GetFileList(std::vector<std::string> * fileList, const std::string & directory, mode_t mode, const std::string & ext);
 
  63 const int pt_mega = 1024 * 1024;
 
  64 //-----------------------------------------------------------------------------
 
  65 //-----------------------------------------------------------------------------
 
  66 //-----------------------------------------------------------------------------
 
  69 PLUGIN_CREATOR<FILES_STORE> fsc;
 
  72 extern "C" STORE * GetStore();
 
  73 //-----------------------------------------------------------------------------
 
  74 //-----------------------------------------------------------------------------
 
  75 //-----------------------------------------------------------------------------
 
  78 return fsc.GetPlugin();
 
  80 //-----------------------------------------------------------------------------
 
  81 FILES_STORE_SETTINGS::FILES_STORE_SETTINGS()
 
 101 //-----------------------------------------------------------------------------
 
 102 int FILES_STORE_SETTINGS::ParseOwner(const std::vector<PARAM_VALUE> & moduleParams, const std::string & owner, uid_t * uid)
 
 106 std::vector<PARAM_VALUE>::const_iterator pvi;
 
 107 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
 
 108 if (pvi == moduleParams.end())
 
 110     errorStr = "Parameter \'" + owner + "\' not found.";
 
 111     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 114 if (User2UID(pvi->value[0].c_str(), uid) < 0)
 
 116     errorStr = "Parameter \'" + owner + "\': Unknown user \'" + pvi->value[0] + "\'";
 
 117     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 122 //-----------------------------------------------------------------------------
 
 123 int FILES_STORE_SETTINGS::ParseGroup(const std::vector<PARAM_VALUE> & moduleParams, const std::string & group, gid_t * gid)
 
 127 std::vector<PARAM_VALUE>::const_iterator pvi;
 
 128 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
 
 129 if (pvi == moduleParams.end())
 
 131     errorStr = "Parameter \'" + group + "\' not found.";
 
 132     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 135 if (Group2GID(pvi->value[0].c_str(), gid) < 0)
 
 137     errorStr = "Parameter \'" + group + "\': Unknown group \'" + pvi->value[0] + "\'";
 
 138     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 143 //-----------------------------------------------------------------------------
 
 144 int FILES_STORE_SETTINGS::ParseYesNo(const std::string & value, bool * val)
 
 146 if (0 == strcasecmp(value.c_str(), "yes"))
 
 151 if (0 == strcasecmp(value.c_str(), "no"))
 
 157 errorStr = "Incorrect value \'" + value + "\'.";
 
 160 //-----------------------------------------------------------------------------
 
 161 int FILES_STORE_SETTINGS::ParseMode(const std::vector<PARAM_VALUE> & moduleParams, const std::string & modeStr, mode_t * mode)
 
 165 std::vector<PARAM_VALUE>::const_iterator pvi;
 
 166 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
 
 167 if (pvi == moduleParams.end())
 
 169     errorStr = "Parameter \'" + modeStr + "\' not found.";
 
 170     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 173 if (Str2Mode(pvi->value[0].c_str(), mode) < 0)
 
 175     errorStr = "Parameter \'" + modeStr + "\': Incorrect mode \'" + pvi->value[0] + "\'";
 
 176     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 181 //-----------------------------------------------------------------------------
 
 182 int FILES_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
 
 184 if (ParseOwner(s.moduleParams, "StatOwner", &statUID) < 0)
 
 186 if (ParseGroup(s.moduleParams, "StatGroup", &statGID) < 0)
 
 188 if (ParseMode(s.moduleParams, "StatMode", &statMode) < 0)
 
 191 if (ParseOwner(s.moduleParams, "ConfOwner", &confUID) < 0)
 
 193 if (ParseGroup(s.moduleParams, "ConfGroup", &confGID) < 0)
 
 195 if (ParseMode(s.moduleParams, "ConfMode", &confMode) < 0)
 
 198 if (ParseOwner(s.moduleParams, "UserLogOwner", &userLogUID) < 0)
 
 200 if (ParseGroup(s.moduleParams, "UserLogGroup", &userLogGID) < 0)
 
 202 if (ParseMode(s.moduleParams, "UserLogMode", &userLogMode) < 0)
 
 205 std::vector<PARAM_VALUE>::const_iterator pvi;
 
 207 pv.param = "RemoveBak";
 
 208 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 209 if (pvi == s.moduleParams.end())
 
 215     if (ParseYesNo(pvi->value[0], &removeBak))
 
 217         printfd(__FILE__, "Cannot parse parameter 'RemoveBak'\n");
 
 222 pv.param = "ReadBak";
 
 223 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 224 if (pvi == s.moduleParams.end())
 
 230     if (ParseYesNo(pvi->value[0], &readBak))
 
 232         printfd(__FILE__, "Cannot parse parameter 'ReadBak'\n");
 
 237 pv.param = "WorkDir";
 
 238 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
 
 239 if (pvi == s.moduleParams.end())
 
 241     errorStr = "Parameter \'WorkDir\' not found.";
 
 242     printfd(__FILE__, "Parameter 'WorkDir' not found\n");
 
 246 workDir = pvi->value[0];
 
 247 if (workDir.size() && workDir[workDir.size() - 1] == '/')
 
 249     workDir.resize(workDir.size() - 1);
 
 251 usersDir = workDir + "/users/";
 
 252 tariffsDir = workDir + "/tariffs/";
 
 253 adminsDir = workDir + "/admins/";
 
 257 //-----------------------------------------------------------------------------
 
 258 const std::string & FILES_STORE_SETTINGS::GetStrError() const
 
 262 //-----------------------------------------------------------------------------
 
 263 int FILES_STORE_SETTINGS::User2UID(const char * user, uid_t * uid)
 
 269     errorStr = std::string("User \'") + std::string(user) + std::string("\' not found in system.");
 
 270     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 277 //-----------------------------------------------------------------------------
 
 278 int FILES_STORE_SETTINGS::Group2GID(const char * gr, gid_t * gid)
 
 284     errorStr = std::string("Group \'") + std::string(gr) + std::string("\' not found in system.");
 
 285     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 292 //-----------------------------------------------------------------------------
 
 293 int FILES_STORE_SETTINGS::Str2Mode(const char * str, mode_t * mode)
 
 300     errorStr = std::string("Error parsing mode \'") + str + std::string("\'");
 
 301     printfd(__FILE__, "%s\n", errorStr.c_str());
 
 305 for (int i = 0; i < 3; i++)
 
 306     if (str[i] > '7' || str[i] < '0')
 
 308         errorStr = std::string("Error parsing mode \'") + str + std::string("\'");
 
 309         printfd(__FILE__, "%s\n", errorStr.c_str());
 
 317 *mode = ((mode_t)c) + ((mode_t)b << 3) + ((mode_t)a << 6);
 
 321 //-----------------------------------------------------------------------------
 
 322 mode_t FILES_STORE_SETTINGS::GetStatModeDir() const
 
 324 mode_t mode = statMode;
 
 325 if (statMode & S_IRUSR) mode |= S_IXUSR;
 
 326 if (statMode & S_IRGRP) mode |= S_IXGRP;
 
 327 if (statMode & S_IROTH) mode |= S_IXOTH;
 
 330 //-----------------------------------------------------------------------------
 
 331 mode_t FILES_STORE_SETTINGS::GetConfModeDir() const
 
 333 mode_t mode = confMode;
 
 334 if (confMode & S_IRUSR) mode |= S_IXUSR;
 
 335 if (confMode & S_IRGRP) mode |= S_IXGRP;
 
 336 if (confMode & S_IROTH) mode |= S_IXOTH;
 
 339 //-----------------------------------------------------------------------------
 
 340 //-----------------------------------------------------------------------------
 
 341 //-----------------------------------------------------------------------------
 
 342 FILES_STORE::FILES_STORE()
 
 344       version("file_store v.1.04"),
 
 348       logger(GetPluginLogger(GetStgLogger(), "store_files"))
 
 350 pthread_mutexattr_t attr;
 
 351 pthread_mutexattr_init(&attr);
 
 352 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 
 353 pthread_mutex_init(&mutex, &attr);
 
 355 //-----------------------------------------------------------------------------
 
 356 int FILES_STORE::ParseSettings()
 
 358 int ret = storeSettings.ParseSettings(settings);
 
 361     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 362     errorStr = storeSettings.GetStrError();
 
 366 //-----------------------------------------------------------------------------
 
 367 int FILES_STORE::GetUsersList(std::vector<std::string> * userList) const
 
 369 std::vector<std::string> files;
 
 371 if (GetFileList(&files, storeSettings.GetUsersDir(), S_IFDIR, ""))
 
 373     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 374     errorStr = "Failed to open '" + storeSettings.GetUsersDir() + "': " + std::string(strerror(errno));
 
 378 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 380 userList->swap(files);
 
 384 //-----------------------------------------------------------------------------
 
 385 int FILES_STORE::GetAdminsList(std::vector<std::string> * adminList) const
 
 387 std::vector<std::string> files;
 
 389 if (GetFileList(&files, storeSettings.GetAdminsDir(), S_IFREG, ".adm"))
 
 391     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 392     errorStr = "Failed to open '" + storeSettings.GetAdminsDir() + "': " + std::string(strerror(errno));
 
 396 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 398 adminList->swap(files);
 
 402 //-----------------------------------------------------------------------------
 
 403 int FILES_STORE::GetTariffsList(std::vector<std::string> * tariffList) const
 
 405 std::vector<std::string> files;
 
 407 if (GetFileList(&files, storeSettings.GetTariffsDir(), S_IFREG, ".tf"))
 
 409     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 410     errorStr = "Failed to open '" + storeSettings.GetTariffsDir() + "': " + std::string(strerror(errno));
 
 414 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 416 tariffList->swap(files);
 
 420 //-----------------------------------------------------------------------------
 
 421 int FILES_STORE::RemoveDir(const char * path) const
 
 423 DIR * d = opendir(path);
 
 427     errorStr = "failed to open dir. Message: '";
 
 428     errorStr += strerror(errno);
 
 430     printfd(__FILE__, "FILE_STORE::RemoveDir() - Failed to open dir '%s': '%s'\n", path, strerror(errno));
 
 435 while ((entry = readdir(d)))
 
 437     if (!(strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")))
 
 440     std::string str = path;
 
 441     str += "/" + std::string(entry->d_name);
 
 444     if (stat(str.c_str(), &st))
 
 447     if ((st.st_mode & S_IFREG))
 
 449         if (unlink(str.c_str()))
 
 451             STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 452             errorStr = "unlink failed. Message: '";
 
 453             errorStr += strerror(errno);
 
 455             printfd(__FILE__, "FILES_STORE::RemoveDir() - unlink failed. Message: '%s'\n", strerror(errno));
 
 461     if (!(st.st_mode & S_IFDIR))
 
 463         if (RemoveDir(str.c_str()))
 
 476     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 477     errorStr = "rmdir failed. Message: '";
 
 478     errorStr += strerror(errno);
 
 480     printfd(__FILE__, "FILES_STORE::RemoveDir() - rmdir failed. Message: '%s'\n", strerror(errno));
 
 486 //-----------------------------------------------------------------------------
 
 487 int FILES_STORE::AddUser(const std::string & login) const
 
 489 std::string fileName;
 
 491 strprintf(&fileName, "%s%s", storeSettings.GetUsersDir().c_str(), login.c_str());
 
 493 if (mkdir(fileName.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
 
 495     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 496     errorStr = std::string("mkdir failed. Message: '") + strerror(errno) + "'";
 
 497     printfd(__FILE__, "FILES_STORE::AddUser - mkdir failed. Message: '%s'\n", strerror(errno));
 
 501 strprintf(&fileName, "%s%s/conf", storeSettings.GetUsersDir().c_str(), login.c_str());
 
 504     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 505     errorStr = "Cannot create file \"" + fileName + "\'";
 
 506     printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
 
 510 strprintf(&fileName, "%s%s/stat", storeSettings.GetUsersDir().c_str(), login.c_str());
 
 513     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 514     errorStr = "Cannot create file \"" + fileName + "\'";
 
 515     printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
 
 520 //-----------------------------------------------------------------------------
 
 521 int FILES_STORE::DelUser(const std::string & login) const
 
 524 std::string dirName1;
 
 526 strprintf(&dirName, "%s/%s", storeSettings.GetWorkDir().c_str(), DELETED_USERS_DIR);
 
 527 if (access(dirName.c_str(), F_OK) != 0)
 
 529     if (mkdir(dirName.c_str(), 0700) != 0)
 
 531         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 532         errorStr = "Directory '" + dirName + "' cannot be created.";
 
 533         printfd(__FILE__, "FILES_STORE::DelUser - mkdir failed. Message: '%s'\n", strerror(errno));
 
 538 if (access(dirName.c_str(), F_OK) == 0)
 
 540     strprintf(&dirName, "%s/%s/%s.%lu", storeSettings.GetWorkDir().c_str(), DELETED_USERS_DIR, login.c_str(), time(NULL));
 
 541     strprintf(&dirName1, "%s/%s", storeSettings.GetUsersDir().c_str(), login.c_str());
 
 542     if (rename(dirName1.c_str(), dirName.c_str()))
 
 544         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 545         errorStr = "Error moving dir from " + dirName1 + " to " + dirName;
 
 546         printfd(__FILE__, "FILES_STORE::DelUser - rename failed. Message: '%s'\n", strerror(errno));
 
 552     strprintf(&dirName, "%s/%s", storeSettings.GetUsersDir().c_str(), login.c_str());
 
 553     if (RemoveDir(dirName.c_str()))
 
 560 //-----------------------------------------------------------------------------
 
 561 int FILES_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login) const
 
 563 std::string fileName;
 
 564 fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
 
 565 if (RestoreUserConf(conf, login, fileName))
 
 567     if (!storeSettings.GetReadBak())
 
 571     return RestoreUserConf(conf, login, fileName + ".bak");
 
 575 //-----------------------------------------------------------------------------
 
 576 int FILES_STORE::RestoreUserConf(USER_CONF * conf, const std::string & login, const std::string & fileName) const
 
 578 CONFIGFILE cf(fileName);
 
 583     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 584     errorStr = "User \'" + login + "\' data not read.";
 
 585     printfd(__FILE__, "FILES_STORE::RestoreUserConf - conf read failed for user '%s'\n", login.c_str());
 
 589 if (cf.ReadString("Password", &conf->password, "") < 0)
 
 591     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 592     errorStr = "User \'" + login + "\' data not read. Parameter Password.";
 
 593     printfd(__FILE__, "FILES_STORE::RestoreUserConf - password read failed for user '%s'\n", login.c_str());
 
 596 if (conf->password.empty())
 
 598     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 599     errorStr = "User \'" + login + "\' password is blank.";
 
 600     printfd(__FILE__, "FILES_STORE::RestoreUserConf - password is blank for user '%s'\n", login.c_str());
 
 604 if (cf.ReadString("tariff", &conf->tariffName, "") < 0)
 
 606     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 607     errorStr = "User \'" + login + "\' data not read. Parameter Tariff.";
 
 608     printfd(__FILE__, "FILES_STORE::RestoreUserConf - tariff read failed for user '%s'\n", login.c_str());
 
 611 if (conf->tariffName.empty())
 
 613     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 614     errorStr = "User \'" + login + "\' tariff is blank.";
 
 615     printfd(__FILE__, "FILES_STORE::RestoreUserConf - tariff is blank for user '%s'\n", login.c_str());
 
 620 cf.ReadString("IP", &ipStr, "?");
 
 624     ips = StrToIPS(ipStr);
 
 626 catch (const std::string & s)
 
 628     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 629     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
 
 630     printfd(__FILE__, "FILES_STORE::RestoreUserConf - ip read failed for user '%s'\n", login.c_str());
 
 635 if (cf.ReadInt("alwaysOnline", &conf->alwaysOnline, 0) != 0)
 
 637     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 638     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
 
 639     printfd(__FILE__, "FILES_STORE::RestoreUserConf - alwaysonline read failed for user '%s'\n", login.c_str());
 
 643 if (cf.ReadInt("down", &conf->disabled, 0) != 0)
 
 645     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 646     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
 
 647     printfd(__FILE__, "FILES_STORE::RestoreUserConf - down read failed for user '%s'\n", login.c_str());
 
 651 if (cf.ReadInt("passive", &conf->passive, 0) != 0)
 
 653     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 654     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
 
 655     printfd(__FILE__, "FILES_STORE::RestoreUserConf - passive read failed for user '%s'\n", login.c_str());
 
 659 cf.ReadInt("DisabledDetailStat", &conf->disabledDetailStat, 0);
 
 660 cf.ReadTime("CreditExpire", &conf->creditExpire, 0);
 
 661 cf.ReadString("TariffChange", &conf->nextTariff, "");
 
 662 cf.ReadString("Group", &conf->group, "");
 
 663 cf.ReadString("RealName", &conf->realName, "");
 
 664 cf.ReadString("Address", &conf->address, "");
 
 665 cf.ReadString("Phone", &conf->phone, "");
 
 666 cf.ReadString("Note", &conf->note, "");
 
 667 cf.ReadString("email", &conf->email, "");
 
 669 char userdataName[12];
 
 670 for (int i = 0; i < USERDATA_NUM; i++)
 
 672     snprintf(userdataName, 12, "Userdata%d", i);
 
 673     cf.ReadString(userdataName, &conf->userdata[i], "");
 
 676 if (cf.ReadDouble("Credit", &conf->credit, 0) != 0)
 
 678     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 679     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
 
 680     printfd(__FILE__, "FILES_STORE::RestoreUserConf - credit read failed for user '%s'\n", login.c_str());
 
 686 //-----------------------------------------------------------------------------
 
 687 int FILES_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login) const
 
 689 std::string fileName;
 
 690 fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
 
 692 if (RestoreUserStat(stat, login, fileName))
 
 694     if (!storeSettings.GetReadBak())
 
 698     return RestoreUserStat(stat, login, fileName + ".bak");
 
 702 //-----------------------------------------------------------------------------
 
 703 int FILES_STORE::RestoreUserStat(USER_STAT * stat, const std::string & login, const std::string & fileName) const
 
 705 CONFIGFILE cf(fileName);
 
 711     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 712     errorStr = "User \'" + login + "\' stat not read. Cannot open file " + fileName + ".";
 
 713     printfd(__FILE__, "FILES_STORE::RestoreUserStat - stat read failed for user '%s'\n", login.c_str());
 
 719 for (int i = 0; i < DIR_NUM; i++)
 
 722     snprintf(s, 22, "D%d", i);
 
 723     if (cf.ReadULongLongInt(s, &traff, 0) != 0)
 
 725         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 726         errorStr = "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 727         printfd(__FILE__, "FILES_STORE::RestoreUserStat - download stat read failed for user '%s'\n", login.c_str());
 
 730     stat->monthDown[i] = traff;
 
 732     snprintf(s, 22, "U%d", i);
 
 733     if (cf.ReadULongLongInt(s, &traff, 0) != 0)
 
 735         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 736         errorStr =   "User \'" + login + "\' stat not read. Parameter " + std::string(s);
 
 737         printfd(__FILE__, "FILES_STORE::RestoreUserStat - upload stat read failed for user '%s'\n", login.c_str());
 
 740     stat->monthUp[i] = traff;
 
 743 if (cf.ReadDouble("Cash", &stat->cash, 0) != 0)
 
 745     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 746     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
 
 747     printfd(__FILE__, "FILES_STORE::RestoreUserStat - cash read failed for user '%s'\n", login.c_str());
 
 751 if (cf.ReadDouble("FreeMb", &stat->freeMb, 0) != 0)
 
 753     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 754     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
 
 755     printfd(__FILE__, "FILES_STORE::RestoreUserStat - freemb read failed for user '%s'\n", login.c_str());
 
 759 if (cf.ReadTime("LastCashAddTime", &stat->lastCashAddTime, 0) != 0)
 
 761     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 762     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
 
 763     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastcashaddtime read failed for user '%s'\n", login.c_str());
 
 767 if (cf.ReadTime("PassiveTime", &stat->passiveTime, 0) != 0)
 
 769     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 770     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
 
 771     printfd(__FILE__, "FILES_STORE::RestoreUserStat - passivetime read failed for user '%s'\n", login.c_str());
 
 775 if (cf.ReadDouble("LastCashAdd", &stat->lastCashAdd, 0) != 0)
 
 777     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 778     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
 
 779     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastcashadd read failed for user '%s'\n", login.c_str());
 
 783 if (cf.ReadTime("LastActivityTime", &stat->lastActivityTime, 0) != 0)
 
 785     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 786     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
 
 787     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastactivitytime read failed for user '%s'\n", login.c_str());
 
 793 //-----------------------------------------------------------------------------
 
 794 int FILES_STORE::SaveUserConf(const USER_CONF & conf, const std::string & login) const
 
 796 std::string fileName;
 
 797 fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
 
 799 CONFIGFILE cfstat(fileName, true);
 
 801 int e = cfstat.Error();
 
 805     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 806     errorStr = std::string("User \'") + login + "\' conf not written\n";
 
 807     printfd(__FILE__, "FILES_STORE::SaveUserConf - conf write failed for user '%s'\n", login.c_str());
 
 811 e = chmod(fileName.c_str(), storeSettings.GetConfMode());
 
 812 e += chown(fileName.c_str(), storeSettings.GetConfUID(), storeSettings.GetConfGID());
 
 816     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 817     printfd(__FILE__, "FILES_STORE::SaveUserConf - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
 820 cfstat.WriteString("Password",     conf.password);
 
 821 cfstat.WriteInt   ("Passive",      conf.passive);
 
 822 cfstat.WriteInt   ("Down",         conf.disabled);
 
 823 cfstat.WriteInt("DisabledDetailStat", conf.disabledDetailStat);
 
 824 cfstat.WriteInt   ("AlwaysOnline", conf.alwaysOnline);
 
 825 cfstat.WriteString("Tariff",       conf.tariffName);
 
 826 cfstat.WriteString("Address",      conf.address);
 
 827 cfstat.WriteString("Phone",        conf.phone);
 
 828 cfstat.WriteString("Email",        conf.email);
 
 829 cfstat.WriteString("Note",         conf.note);
 
 830 cfstat.WriteString("RealName",     conf.realName);
 
 831 cfstat.WriteString("Group",        conf.group);
 
 832 cfstat.WriteDouble("Credit",       conf.credit);
 
 833 cfstat.WriteString("TariffChange", conf.nextTariff);
 
 835 char userdataName[12];
 
 836 for (int i = 0; i < USERDATA_NUM; i++)
 
 838     snprintf(userdataName, 12, "Userdata%d", i);
 
 839     cfstat.WriteString(userdataName, conf.userdata[i]);
 
 841 cfstat.WriteInt("CreditExpire",    conf.creditExpire);
 
 843 std::ostringstream ipStr;
 
 845 cfstat.WriteString("IP", ipStr.str());
 
 849 //-----------------------------------------------------------------------------
 
 850 int FILES_STORE::SaveUserStat(const USER_STAT & stat, const std::string & login) const
 
 852 std::string fileName;
 
 853 fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
 
 856     CONFIGFILE cfstat(fileName, true);
 
 857     int e = cfstat.Error();
 
 861         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 862         errorStr = std::string("User \'") + login + "\' stat not written\n";
 
 863         printfd(__FILE__, "FILES_STORE::SaveUserStat - stat write failed for user '%s'\n", login.c_str());
 
 867     for (int i = 0; i < DIR_NUM; i++)
 
 870         snprintf(s, 22, "D%d", i);
 
 871         cfstat.WriteInt(s, stat.monthDown[i]);
 
 872         snprintf(s, 22, "U%d", i);
 
 873         cfstat.WriteInt(s, stat.monthUp[i]);
 
 876     cfstat.WriteDouble("Cash", stat.cash);
 
 877     cfstat.WriteDouble("FreeMb", stat.freeMb);
 
 878     cfstat.WriteDouble("LastCashAdd", stat.lastCashAdd);
 
 879     cfstat.WriteInt("LastCashAddTime", stat.lastCashAddTime);
 
 880     cfstat.WriteInt("PassiveTime", stat.passiveTime);
 
 881     cfstat.WriteInt("LastActivityTime", stat.lastActivityTime);
 
 884 int e = chmod(fileName.c_str(), storeSettings.GetStatMode());
 
 885 e += chown(fileName.c_str(), storeSettings.GetStatUID(), storeSettings.GetStatGID());
 
 889     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 890     printfd(__FILE__, "FILES_STORE::SaveUserStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
 895 //-----------------------------------------------------------------------------
 
 896 int FILES_STORE::WriteLogString(const std::string & str, const std::string & login) const
 
 899 time_t tm = time(NULL);
 
 900 std::string fileName;
 
 901 fileName = storeSettings.GetUsersDir() + "/" + login + "/log";
 
 902 f = fopen(fileName.c_str(), "at");
 
 906     fprintf(f, "%s", LogDate(tm));
 
 908     fprintf(f, "%s", str.c_str());
 
 914     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 915     errorStr = "Cannot open \'" + fileName + "\'";
 
 916     printfd(__FILE__, "FILES_STORE::WriteLogString - log write failed for user '%s'\n", login.c_str());
 
 920 int e = chmod(fileName.c_str(), storeSettings.GetLogMode());
 
 921 e += chown(fileName.c_str(), storeSettings.GetLogUID(), storeSettings.GetLogGID());
 
 925     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 926     printfd(__FILE__, "FILES_STORE::WriteLogString - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
 931 //-----------------------------------------------------------------------------
 
 932 int FILES_STORE::WriteLog2String(const std::string & str, const std::string & login) const
 
 935 time_t tm = time(NULL);
 
 936 std::string fileName;
 
 937 fileName = storeSettings.GetUsersDir() + "/" + login + "/log2";
 
 938 f = fopen(fileName.c_str(), "at");
 
 942     fprintf(f, "%s", LogDate(tm));
 
 944     fprintf(f, "%s", str.c_str());
 
 950     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 951     errorStr = "Cannot open \'" + fileName + "\'";
 
 952     printfd(__FILE__, "FILES_STORE::WriteLogString - log write failed for user '%s'\n", login.c_str());
 
 956 int e = chmod(fileName.c_str(), storeSettings.GetLogMode());
 
 957 e += chown(fileName.c_str(), storeSettings.GetLogUID(), storeSettings.GetLogGID());
 
 961     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
 962     printfd(__FILE__, "FILES_STORE::WriteLogString - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
 967 //-----------------------------------------------------------------------------
 
 968 int FILES_STORE::WriteUserChgLog(const std::string & login,
 
 969                                  const std::string & admLogin,
 
 971                                  const std::string & paramName,
 
 972                                  const std::string & oldValue,
 
 973                                  const std::string & newValue,
 
 974                                  const std::string & message) const
 
 976 std::string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
 
 977     + paramName + "\' parameter changed from \'" + oldValue +
 
 978     "\' to \'" + newValue + "\'. " + message;
 
 980 return WriteLogString(userLogMsg, login);
 
 982 //-----------------------------------------------------------------------------
 
 983 int FILES_STORE::WriteUserConnect(const std::string & login, uint32_t ip) const
 
 985 std::string logStr = "Connect, " + inet_ntostring(ip);
 
 986 if (WriteLogString(logStr, login))
 
 988 return WriteLog2String(logStr, login);
 
 990 //-----------------------------------------------------------------------------
 
 991 int FILES_STORE::WriteUserDisconnect(const std::string & login,
 
 992                                      const DIR_TRAFF & monthUp,
 
 993                                      const DIR_TRAFF & monthDown,
 
 994                                      const DIR_TRAFF & sessionUp,
 
 995                                      const DIR_TRAFF & sessionDown,
 
 998                                      const std::string & reason) const
 
1000 std::ostringstream logStr;
 
1001 logStr << "Disconnect, "
 
1002        << " session upload: \'"
 
1004        << "\' session download: \'"
 
1006        << "\' month upload: \'"
 
1008        << "\' month download: \'"
 
1014 if (WriteLogString(logStr.str(), login))
 
1017 logStr << " freeMb: \'"
 
1024 return WriteLog2String(logStr.str(), login);
 
1026 //-----------------------------------------------------------------------------
 
1027 int FILES_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const std::string & login) const
 
1031 strprintf(&stat1,"%s/%s/stat.%d.%02d",
 
1032         storeSettings.GetUsersDir().c_str(), login.c_str(), year + 1900, month + 1);
 
1034 CONFIGFILE s(stat1, true);
 
1038     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1039     errorStr = "Cannot create file '" + stat1 + "'";
 
1040     printfd(__FILE__, "FILES_STORE::SaveMonthStat - month stat write failed for user '%s'\n", login.c_str());
 
1046 strprintf(&stat2,"%s/%s/stat2.%d.%02d",
 
1047         storeSettings.GetUsersDir().c_str(), login.c_str(), year + 1900, month + 1);
 
1049 CONFIGFILE s2(stat2, true);
 
1053     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1054     errorStr = "Cannot create file '" + stat2 + "'";
 
1055     printfd(__FILE__, "FILES_STORE::SaveMonthStat - month stat write failed for user '%s'\n", login.c_str());
 
1059 for (size_t i = 0; i < DIR_NUM; i++)
 
1062     snprintf(dirName, 3, "U%llu", (unsigned long long)i);
 
1063     s.WriteInt(dirName, stat.monthUp[i]); // Classic
 
1064     s2.WriteInt(dirName, stat.monthUp[i]); // New
 
1065     snprintf(dirName, 3, "D%llu", (unsigned long long)i);
 
1066     s.WriteInt(dirName, stat.monthDown[i]); // Classic
 
1067     s2.WriteInt(dirName, stat.monthDown[i]); // New
 
1071 s.WriteDouble("cash", stat.cash);
 
1074 s2.WriteDouble("Cash", stat.cash);
 
1075 s2.WriteDouble("FreeMb", stat.freeMb);
 
1076 s2.WriteDouble("LastCashAdd", stat.lastCashAdd);
 
1077 s2.WriteInt("LastCashAddTime", stat.lastCashAddTime);
 
1078 s2.WriteInt("PassiveTime", stat.passiveTime);
 
1079 s2.WriteInt("LastActivityTime", stat.lastActivityTime);
 
1083 //-----------------------------------------------------------------------------*/
 
1084 int FILES_STORE::AddAdmin(const std::string & login) const
 
1086 std::string fileName;
 
1087 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
 
1089 if (Touch(fileName))
 
1091     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1092     errorStr = "Cannot create file " + fileName;
 
1093     printfd(__FILE__, "FILES_STORE::AddAdmin - failed to add admin '%s'\n", login.c_str());
 
1099 //-----------------------------------------------------------------------------*/
 
1100 int FILES_STORE::DelAdmin(const std::string & login) const
 
1102 std::string fileName;
 
1103 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
 
1104 if (unlink(fileName.c_str()))
 
1106     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1107     errorStr = "unlink failed. Message: '";
 
1108     errorStr += strerror(errno);
 
1110     printfd(__FILE__, "FILES_STORE::DelAdmin - unlink failed. Message: '%s'\n", strerror(errno));
 
1114 //-----------------------------------------------------------------------------*/
 
1115 int FILES_STORE::SaveAdmin(const ADMIN_CONF & ac) const
 
1117 std::string fileName;
 
1119 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), ac.login.c_str());
 
1122     CONFIGFILE cf(fileName, true);
 
1128         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1129         errorStr = "Cannot write admin " + ac.login + ". " + fileName;
 
1130         printfd(__FILE__, "FILES_STORE::SaveAdmin - failed to save admin '%s'\n", ac.login.c_str());
 
1134     char pass[ADM_PASSWD_LEN + 1];
 
1135     memset(pass, 0, sizeof(pass));
 
1137     char adminPass[ADM_PASSWD_LEN + 1];
 
1138     memset(adminPass, 0, sizeof(adminPass));
 
1141     EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1143     strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
 
1144     adminPass[ADM_PASSWD_LEN - 1] = 0;
 
1146     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1148         EncodeString(pass + 8*i, adminPass + 8*i, &ctx);
 
1151     pass[ADM_PASSWD_LEN - 1] = 0;
 
1152     char passwordE[2 * ADM_PASSWD_LEN + 2];
 
1153     Encode12(passwordE, pass, ADM_PASSWD_LEN);
 
1155     cf.WriteString("password", passwordE);
 
1156     cf.WriteInt("ChgConf",     ac.priv.userConf);
 
1157     cf.WriteInt("ChgPassword", ac.priv.userPasswd);
 
1158     cf.WriteInt("ChgStat",     ac.priv.userStat);
 
1159     cf.WriteInt("ChgCash",     ac.priv.userCash);
 
1160     cf.WriteInt("UsrAddDel",   ac.priv.userAddDel);
 
1161     cf.WriteInt("ChgTariff",   ac.priv.tariffChg);
 
1162     cf.WriteInt("ChgAdmin",    ac.priv.adminChg);
 
1163     cf.WriteInt("ChgService",  ac.priv.serviceChg);
 
1164     cf.WriteInt("ChgCorp",     ac.priv.corpChg);
 
1169 //-----------------------------------------------------------------------------
 
1170 int FILES_STORE::RestoreAdmin(ADMIN_CONF * ac, const std::string & login) const
 
1172 std::string fileName;
 
1173 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
 
1174 CONFIGFILE cf(fileName);
 
1175 char pass[ADM_PASSWD_LEN + 1];
 
1176 char password[ADM_PASSWD_LEN + 1];
 
1177 char passwordE[2 * ADM_PASSWD_LEN + 2];
 
1184     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1185     errorStr = "Cannot open " + fileName;
 
1186     printfd(__FILE__, "FILES_STORE::RestoreAdmin - failed to restore admin '%s'\n", ac->login.c_str());
 
1190 if (cf.ReadString("password", &p, "*"))
 
1192     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1193     errorStr = "Error in parameter password";
 
1194     printfd(__FILE__, "FILES_STORE::RestoreAdmin - password read failed for admin '%s'\n", ac->login.c_str());
 
1198 memset(passwordE, 0, sizeof(passwordE));
 
1199 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
 
1201 memset(pass, 0, sizeof(pass));
 
1203 if (passwordE[0] != 0)
 
1205     Decode21(pass, passwordE);
 
1206     EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
 
1208     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
 
1210         DecodeString(password + 8*i, pass + 8*i, &ctx);
 
1218 ac->password = password;
 
1222 if (cf.ReadUShortInt("ChgConf", &a, 0) == 0)
 
1223     ac->priv.userConf = a;
 
1226     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1227     errorStr = "Error in parameter ChgConf";
 
1228     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgconf read failed for admin '%s'\n", ac->login.c_str());
 
1232 if (cf.ReadUShortInt("ChgPassword", &a, 0) == 0)
 
1233     ac->priv.userPasswd = a;
 
1236     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1237     errorStr = "Error in parameter ChgPassword";
 
1238     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgpassword read failed for admin '%s'\n", ac->login.c_str());
 
1242 if (cf.ReadUShortInt("ChgStat", &a, 0) == 0)
 
1243     ac->priv.userStat = a;
 
1246     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1247     errorStr = "Error in parameter ChgStat";
 
1248     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgstat read failed for admin '%s'\n", ac->login.c_str());
 
1252 if (cf.ReadUShortInt("ChgCash", &a, 0) == 0)
 
1253     ac->priv.userCash = a;
 
1256     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1257     errorStr = "Error in parameter ChgCash";
 
1258     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgcash read failed for admin '%s'\n", ac->login.c_str());
 
1262 if (cf.ReadUShortInt("UsrAddDel", &a, 0) == 0)
 
1263     ac->priv.userAddDel = a;
 
1266     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1267     errorStr = "Error in parameter UsrAddDel";
 
1268     printfd(__FILE__, "FILES_STORE::RestoreAdmin - usradddel read failed for admin '%s'\n", ac->login.c_str());
 
1272 if (cf.ReadUShortInt("ChgAdmin", &a, 0) == 0)
 
1273     ac->priv.adminChg = a;
 
1276     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1277     errorStr = "Error in parameter ChgAdmin";
 
1278     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgadmin read failed for admin '%s'\n", ac->login.c_str());
 
1282 if (cf.ReadUShortInt("ChgTariff", &a, 0) == 0)
 
1283     ac->priv.tariffChg = a;
 
1286     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1287     errorStr = "Error in parameter ChgTariff";
 
1288     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgtariff read failed for admin '%s'\n", ac->login.c_str());
 
1292 if (cf.ReadUShortInt("ChgService", &a, 0) == 0)
 
1293     ac->priv.serviceChg = a;
 
1295     ac->priv.serviceChg = 0;
 
1297 if (cf.ReadUShortInt("ChgCorp", &a, 0) == 0)
 
1298     ac->priv.corpChg = a;
 
1300     ac->priv.corpChg = 0;
 
1304 //-----------------------------------------------------------------------------
 
1305 int FILES_STORE::AddTariff(const std::string & name) const
 
1307 std::string fileName;
 
1308 strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
 
1309 if (Touch(fileName))
 
1311     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1312     errorStr = "Cannot create file " + fileName;
 
1313     printfd(__FILE__, "FILES_STORE::AddTariff - failed to add tariff '%s'\n", name.c_str());
 
1318 //-----------------------------------------------------------------------------
 
1319 int FILES_STORE::DelTariff(const std::string & name) const
 
1321 std::string fileName;
 
1322 strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
 
1323 if (unlink(fileName.c_str()))
 
1325     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1326     errorStr = "unlink failed. Message: '";
 
1327     errorStr += strerror(errno);
 
1329     printfd(__FILE__, "FILES_STORE::DelTariff - unlink failed. Message: '%s'\n", strerror(errno));
 
1333 //-----------------------------------------------------------------------------
 
1334 int FILES_STORE::RestoreTariff(TARIFF_DATA * td, const std::string & tariffName) const
 
1336 std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
 
1337 CONFIGFILE conf(fileName);
 
1339 td->tariffConf.name = tariffName;
 
1341 if (conf.Error() != 0)
 
1343     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1344     errorStr = "Cannot read file " + fileName;
 
1345     printfd(__FILE__, "FILES_STORE::RestoreTariff - failed to read tariff '%s'\n", tariffName.c_str());
 
1350 for (int i = 0; i<DIR_NUM; i++)
 
1352     strprintf(¶m, "Time%d", i);
 
1353     if (conf.ReadString(param, &str, "00:00-00:00") < 0)
 
1355         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1356         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1357         printfd(__FILE__, "FILES_STORE::RestoreTariff - time%d read failed for tariff '%s'\n", i, tariffName.c_str());
 
1361     ParseTariffTimeStr(str.c_str(),
 
1362                        td->dirPrice[i].hDay,
 
1363                        td->dirPrice[i].mDay,
 
1364                        td->dirPrice[i].hNight,
 
1365                        td->dirPrice[i].mNight);
 
1367     strprintf(¶m, "PriceDayA%d", i);
 
1368     if (conf.ReadDouble(param, &td->dirPrice[i].priceDayA, 0.0) < 0)
 
1370         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1371         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1372         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricedaya read failed for tariff '%s'\n", tariffName.c_str());
 
1375     td->dirPrice[i].priceDayA /= (1024*1024);
 
1377     strprintf(¶m, "PriceDayB%d", i);
 
1378     if (conf.ReadDouble(param, &td->dirPrice[i].priceDayB, 0.0) < 0)
 
1380         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1381         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1382         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricedayb read failed for tariff '%s'\n", tariffName.c_str());
 
1385     td->dirPrice[i].priceDayB /= (1024*1024);
 
1387     strprintf(¶m, "PriceNightA%d", i);
 
1388     if (conf.ReadDouble(param, &td->dirPrice[i].priceNightA, 0.0) < 0)
 
1390         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1391         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1392         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricenighta read failed for tariff '%s'\n", tariffName.c_str());
 
1395     td->dirPrice[i].priceNightA /= (1024*1024);
 
1397     strprintf(¶m, "PriceNightB%d", i);
 
1398     if (conf.ReadDouble(param, &td->dirPrice[i].priceNightB, 0.0) < 0)
 
1400         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1401         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1402         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricenightb read failed for tariff '%s'\n", tariffName.c_str());
 
1405     td->dirPrice[i].priceNightB /= (1024*1024);
 
1407     strprintf(¶m, "Threshold%d", i);
 
1408     if (conf.ReadInt(param, &td->dirPrice[i].threshold, 0) < 0)
 
1410         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1411         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1412         printfd(__FILE__, "FILES_STORE::RestoreTariff - threshold read failed for tariff '%s'\n", tariffName.c_str());
 
1416     strprintf(¶m, "SinglePrice%d", i);
 
1417     if (conf.ReadInt(param, &td->dirPrice[i].singlePrice, 0) < 0)
 
1419         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1420         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1421         printfd(__FILE__, "FILES_STORE::RestoreTariff - singleprice read failed for tariff '%s'\n", tariffName.c_str());
 
1425     strprintf(¶m, "NoDiscount%d", i);
 
1426     if (conf.ReadInt(param, &td->dirPrice[i].noDiscount, 0) < 0)
 
1428         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1429         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
 
1430         printfd(__FILE__, "FILES_STORE::RestoreTariff - nodiscount read failed for tariff '%s'\n", tariffName.c_str());
 
1435 if (conf.ReadDouble("Fee", &td->tariffConf.fee, 0) < 0)
 
1437     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1438     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
 
1439     printfd(__FILE__, "FILES_STORE::RestoreTariff - fee read failed for tariff '%s'\n", tariffName.c_str());
 
1443 if (conf.ReadDouble("Free", &td->tariffConf.free, 0) < 0)
 
1445     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1446     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
 
1447     printfd(__FILE__, "FILES_STORE::RestoreTariff - free read failed for tariff '%s'\n", tariffName.c_str());
 
1451 if (conf.ReadDouble("PassiveCost", &td->tariffConf.passiveCost, 0) < 0)
 
1453     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1454     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
 
1455     printfd(__FILE__, "FILES_STORE::RestoreTariff - passivecost read failed for tariff '%s'\n", tariffName.c_str());
 
1459 if (conf.ReadString("TraffType", &str, "") < 0)
 
1461     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1462     errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType";
 
1463     printfd(__FILE__, "FILES_STORE::RestoreTariff - trafftype read failed for tariff '%s'\n", tariffName.c_str());
 
1467 if (!strcasecmp(str.c_str(), "up"))
 
1468     td->tariffConf.traffType = TRAFF_UP;
 
1470     if (!strcasecmp(str.c_str(), "down"))
 
1471         td->tariffConf.traffType = TRAFF_DOWN;
 
1473         if (!strcasecmp(str.c_str(), "up+down"))
 
1474             td->tariffConf.traffType = TRAFF_UP_DOWN;
 
1476             if (!strcasecmp(str.c_str(), "max"))
 
1477                 td->tariffConf.traffType = TRAFF_MAX;
 
1480                 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1481                 errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType incorrect";
 
1482                 printfd(__FILE__, "FILES_STORE::RestoreTariff - invalid trafftype for tariff '%s'\n", tariffName.c_str());
 
1486 if (conf.ReadString("Period", &str, "month") < 0)
 
1487     td->tariffConf.period = TARIFF::MONTH;
 
1489     td->tariffConf.period = TARIFF::StringToPeriod(str);
 
1492 //-----------------------------------------------------------------------------
 
1493 int FILES_STORE::SaveTariff(const TARIFF_DATA & td, const std::string & tariffName) const
 
1495 std::string fileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
 
1498     CONFIGFILE cf(fileName, true);
 
1504         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1505         errorStr = "Error writing tariff " + tariffName;
 
1506         printfd(__FILE__, "FILES_STORE::RestoreTariff - failed to save tariff '%s'\n", tariffName.c_str());
 
1511     for (int i = 0; i < DIR_NUM; i++)
 
1513         strprintf(¶m, "PriceDayA%d", i);
 
1514         cf.WriteDouble(param, td.dirPrice[i].priceDayA * pt_mega);
 
1516         strprintf(¶m, "PriceDayB%d", i);
 
1517         cf.WriteDouble(param, td.dirPrice[i].priceDayB * pt_mega);
 
1519         strprintf(¶m, "PriceNightA%d", i);
 
1520         cf.WriteDouble(param, td.dirPrice[i].priceNightA * pt_mega);
 
1522         strprintf(¶m, "PriceNightB%d", i);
 
1523         cf.WriteDouble(param, td.dirPrice[i].priceNightB * pt_mega);
 
1525         strprintf(¶m, "Threshold%d", i);
 
1526         cf.WriteInt(param, td.dirPrice[i].threshold);
 
1529         strprintf(¶m, "Time%d", i);
 
1531         strprintf(&s, "%0d:%0d-%0d:%0d",
 
1532                 td.dirPrice[i].hDay,
 
1533                 td.dirPrice[i].mDay,
 
1534                 td.dirPrice[i].hNight,
 
1535                 td.dirPrice[i].mNight);
 
1537         cf.WriteString(param, s);
 
1539         strprintf(¶m, "NoDiscount%d", i);
 
1540         cf.WriteInt(param, td.dirPrice[i].noDiscount);
 
1542         strprintf(¶m, "SinglePrice%d", i);
 
1543         cf.WriteInt(param, td.dirPrice[i].singlePrice);
 
1546     cf.WriteDouble("PassiveCost", td.tariffConf.passiveCost);
 
1547     cf.WriteDouble("Fee", td.tariffConf.fee);
 
1548     cf.WriteDouble("Free", td.tariffConf.free);
 
1550     switch (td.tariffConf.traffType)
 
1553             cf.WriteString("TraffType", "up");
 
1556             cf.WriteString("TraffType", "down");
 
1559             cf.WriteString("TraffType", "up+down");
 
1562             cf.WriteString("TraffType", "max");
 
1566     cf.WriteString("Period", TARIFF::PeriodToString(td.tariffConf.period));
 
1571 //-----------------------------------------------------------------------------
 
1572 int FILES_STORE::WriteDetailedStat(const std::map<IP_DIR_PAIR, STAT_NODE> & statTree,
 
1574                                    const std::string & login) const
 
1576 char fn[FN_STR_LEN];
 
1577 char dn[FN_STR_LEN];
 
1584 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat", storeSettings.GetUsersDir().c_str(), login.c_str());
 
1585 if (access(dn, F_OK) != 0)
 
1587     if (mkdir(dn, 0700) != 0)
 
1589         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1590         errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
 
1591         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
 
1596 int e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
 
1597 e += chmod(dn, storeSettings.GetStatModeDir());
 
1601     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1602     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
1607 if (lt->tm_hour == 0 && lt->tm_min <= 5)
 
1613 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat/%d",
 
1614          storeSettings.GetUsersDir().c_str(),
 
1618 if (access(dn, F_OK) != 0)
 
1620     if (mkdir(dn, 0700) != 0)
 
1622         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1623         errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
 
1624         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
 
1629 e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
 
1630 e += chmod(dn, storeSettings.GetStatModeDir());
 
1634     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1635     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
1638 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat/%d/%s%d", 
 
1639          storeSettings.GetUsersDir().c_str(),
 
1642          lt->tm_mon+1 < 10 ? "0" : "",
 
1644 if (access(dn, F_OK) != 0)
 
1646     if (mkdir(dn, 0700) != 0)
 
1648         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1649         errorStr = "Directory \'" + std::string(dn) + "\' cannot be created.";
 
1650         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
 
1655 e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
 
1656 e += chmod(dn, storeSettings.GetStatModeDir());
 
1660     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1661     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
1664 snprintf(fn, FN_STR_LEN, "%s/%s%d", dn, lt->tm_mday < 10 ? "0" : "", lt->tm_mday);
 
1666 statFile = fopen (fn, "at");
 
1670     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1671     errorStr = "File \'" + std::string(fn) + "\' cannot be written.";
 
1672     printfd(__FILE__, "FILES_STORE::WriteDetailStat - fopen failed. Message: '%s'\n", strerror(errno));
 
1679 lt1 = localtime(&lastStat);
 
1688 lt2 = localtime(&t);
 
1694 if (fprintf(statFile, "-> %02d.%02d.%02d - %02d.%02d.%02d\n",
 
1695             h1, m1, s1, h2, m2, s2) < 0)
 
1697     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1698     errorStr = std::string("fprint failed. Message: '") + strerror(errno) + "'";
 
1699     printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
 
1704 std::map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
 
1705 stIter = statTree.begin();
 
1707 while (stIter != statTree.end())
 
1710     x2str(stIter->second.up, u);
 
1711     x2str(stIter->second.down, d);
 
1712     #ifdef TRAFF_STAT_WITH_PORTS
 
1713     if (fprintf(statFile, "%17s:%hu\t%15d\t%15s\t%15s\t%f\n",
 
1714                 inet_ntostring(stIter->first.ip).c_str(),
 
1719                 stIter->second.cash) < 0)
 
1721         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1722         errorStr = "fprint failed. Message: '";
 
1723         errorStr += strerror(errno);
 
1725         printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
 
1730     if (fprintf(statFile, "%17s\t%15d\t%15s\t%15s\t%f\n",
 
1731                 inet_ntostring(stIter->first.ip).c_str(),
 
1735                 stIter->second.cash) < 0)
 
1737         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1738         errorStr = std::string("fprint failed. Message: '");
 
1739         errorStr += strerror(errno);
 
1741         printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
 
1752 e = chown(fn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
 
1753 e += chmod(fn, storeSettings.GetStatMode());
 
1757     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1758     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
 
1763 //-----------------------------------------------------------------------------
 
1764 int FILES_STORE::AddMessage(STG_MSG * msg, const std::string & login) const
 
1770 strprintf(&dn, "%s/%s/messages", storeSettings.GetUsersDir().c_str(), login.c_str());
 
1771 if (access(dn.c_str(), F_OK) != 0)
 
1773     if (mkdir(dn.c_str(), 0700) != 0)
 
1775         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1776         errorStr = "Directory \'";
 
1778         errorStr += "\' cannot be created.";
 
1779         printfd(__FILE__, "FILES_STORE::AddMessage - mkdir failed. Message: '%s'\n", strerror(errno));
 
1784 chmod(dn.c_str(), storeSettings.GetConfModeDir());
 
1786 gettimeofday(&tv, NULL);
 
1788 msg->header.id = ((long long)tv.tv_sec) * 1000000 + ((long long)tv.tv_usec);
 
1789 strprintf(&fn, "%s/%lld", dn.c_str(), msg->header.id);
 
1793     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1794     errorStr = "File \'";
 
1796     errorStr += "\' cannot be writen.";
 
1797     printfd(__FILE__, "FILES_STORE::AddMessage - fopen failed. Message: '%s'\n", strerror(errno));
 
1801 return EditMessage(*msg, login);
 
1803 //-----------------------------------------------------------------------------
 
1804 int FILES_STORE::EditMessage(const STG_MSG & msg, const std::string & login) const
 
1806 std::string fileName;
 
1809 strprintf(&fileName, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), msg.header.id);
 
1811 if (access(fileName.c_str(), F_OK) != 0)
 
1814     x2str(msg.header.id, idstr);
 
1815     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1816     errorStr = "Message for user \'";
 
1817     errorStr += login + "\' with ID \'";
 
1818     errorStr += idstr + "\' does not exist.";
 
1819     printfd(__FILE__, "FILES_STORE::EditMessage - %s\n", errorStr.c_str());
 
1823 Touch(fileName + ".new");
 
1825 msgFile = fopen((fileName + ".new").c_str(), "wt");
 
1828     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1829     errorStr = "File \'" + fileName + "\' cannot be writen.";
 
1830     printfd(__FILE__, "FILES_STORE::EditMessage - fopen failed. Message: '%s'\n", strerror(errno));
 
1835 res &= (fprintf(msgFile, "%u\n", msg.header.type) >= 0);
 
1836 res &= (fprintf(msgFile, "%u\n", msg.header.lastSendTime) >= 0);
 
1837 res &= (fprintf(msgFile, "%u\n", msg.header.creationTime) >= 0);
 
1838 res &= (fprintf(msgFile, "%u\n", msg.header.showTime) >= 0);
 
1839 res &= (fprintf(msgFile, "%d\n", msg.header.repeat) >= 0);
 
1840 res &= (fprintf(msgFile, "%u\n", msg.header.repeatPeriod) >= 0);
 
1841 res &= (fprintf(msgFile, "%s", msg.text.c_str()) >= 0);
 
1845     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1846     errorStr = std::string("fprintf failed. Message: '") + strerror(errno) + "'";
 
1847     printfd(__FILE__, "FILES_STORE::EditMessage - fprintf failed. Message: '%s'\n", strerror(errno));
 
1854 chmod((fileName + ".new").c_str(), storeSettings.GetConfMode());
 
1856 if (rename((fileName + ".new").c_str(), fileName.c_str()) < 0)
 
1858     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1859     errorStr = "Error moving dir from " + fileName + ".new to " + fileName;
 
1860     printfd(__FILE__, "FILES_STORE::EditMessage - rename failed. Message: '%s'\n", strerror(errno));
 
1866 //-----------------------------------------------------------------------------
 
1867 int FILES_STORE::GetMessage(uint64_t id, STG_MSG * msg, const std::string & login) const
 
1870 strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
 
1871 msg->header.id = id;
 
1872 return ReadMessage(fn, &msg->header, &msg->text);
 
1874 //-----------------------------------------------------------------------------
 
1875 int FILES_STORE::DelMessage(uint64_t id, const std::string & login) const
 
1878 strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
 
1880 return unlink(fn.c_str());
 
1882 //-----------------------------------------------------------------------------
 
1883 int FILES_STORE::GetMessageHdrs(std::vector<STG_MSG_HDR> * hdrsList, const std::string & login) const
 
1885 std::string dn(storeSettings.GetUsersDir() + "/" + login + "/messages/");
 
1887 if (access(dn.c_str(), F_OK) != 0)
 
1892 std::vector<std::string> messages;
 
1893 GetFileList(&messages, dn, S_IFREG, "");
 
1895 for (unsigned i = 0; i < messages.size(); i++)
 
1897     unsigned long long id = 0;
 
1899     if (str2x(messages[i].c_str(), id))
 
1901         if (unlink((dn + messages[i]).c_str()))
 
1903             STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1904             errorStr = std::string("unlink failed. Message: '") + strerror(errno) + "'";
 
1905             printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
 
1912     if (ReadMessage(dn + messages[i], &hdr, NULL))
 
1919         if (unlink((dn + messages[i]).c_str()))
 
1921             STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1922             errorStr = std::string("unlink failed. Message: '") + strerror(errno) + "'";
 
1923             printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
 
1930     hdrsList->push_back(hdr);
 
1934 //-----------------------------------------------------------------------------
 
1935 int FILES_STORE::ReadMessage(const std::string & fileName,
 
1937                              std::string * text) const
 
1940 msgFile = fopen(fileName.c_str(), "rt");
 
1943     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1944     errorStr = "File \'";
 
1945     errorStr += fileName;
 
1946     errorStr += "\' cannot be openned.";
 
1947     printfd(__FILE__, "FILES_STORE::ReadMessage - fopen failed. Message: '%s'\n", strerror(errno));
 
1953 d[1] = &hdr->lastSendTime;
 
1954 d[2] = &hdr->creationTime;
 
1955 d[3] = &hdr->showTime;
 
1956 d[4] = (unsigned*)(&hdr->repeat);
 
1957 d[5] = &hdr->repeatPeriod;
 
1959 memset(p, 0, sizeof(p));
 
1961 for (int pos = 0; pos < 6; pos++)
 
1963     if (fgets(p, sizeof(p) - 1, msgFile) == NULL) {
 
1964         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1965         errorStr = "Cannot read file \'";
 
1966         errorStr += fileName;
 
1967         errorStr += "\'. Missing data.";
 
1968         printfd(__FILE__, "FILES_STORE::ReadMessage - cannot read file (missing data)\n");
 
1969         printfd(__FILE__, "FILES_STORE::ReadMessage - position: %d\n", pos);
 
1975     ep = strrchr(p, '\r');
 
1977     ep = strrchr(p, '\n');
 
1982         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1983         errorStr = "Cannot read file \'";
 
1984         errorStr += fileName;
 
1985         errorStr += "\'. Missing data.";
 
1986         printfd(__FILE__, "FILES_STORE::ReadMessage - cannot read file (feof)\n");
 
1987         printfd(__FILE__, "FILES_STORE::ReadMessage - position: %d\n", pos);
 
1992     if (str2x(p, *(d[pos])))
 
1994         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
 
1995         errorStr = "Cannot read file \'";
 
1996         errorStr += fileName;
 
1997         errorStr += "\'. Incorrect value. \'";
 
2000         printfd(__FILE__, "FILES_STORE::ReadMessage - incorrect value\n");
 
2007 memset(txt, 0, sizeof(txt));
 
2010     text->erase(text->begin(), text->end());
 
2011     while (!feof(msgFile))
 
2014         if (fgets(txt, sizeof(txt) - 1, msgFile) == NULL) {
 
2024 //-----------------------------------------------------------------------------
 
2025 int FILES_STORE::Touch(const std::string & path) const
 
2027 FILE * f = fopen(path.c_str(), "wb");
 
2035 //-----------------------------------------------------------------------------
 
2036 int GetFileList(std::vector<std::string> * fileList, const std::string & directory, mode_t mode, const std::string & ext)
 
2038 DIR * d = opendir(directory.c_str());
 
2042     printfd(__FILE__, "GetFileList - Failed to open dir '%s': '%s'\n", directory.c_str(), strerror(errno));
 
2047 while ((entry = readdir(d)))
 
2049     if (!(strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")))
 
2052     std::string str = directory + "/" + std::string(entry->d_name);
 
2055     if (stat(str.c_str(), &st))
 
2058     if (!(st.st_mode & mode)) // Filter by mode
 
2064         size_t d_nameLen = strlen(entry->d_name);
 
2065         if (d_nameLen <= ext.size())
 
2068         if (ext == entry->d_name + (d_nameLen - ext.size()))
 
2070             entry->d_name[d_nameLen - ext.size()] = 0;
 
2071             fileList->push_back(entry->d_name);
 
2076         fileList->push_back(entry->d_name);
 
2084 //-----------------------------------------------------------------------------