]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/store/files/file_store.cpp
Переход к новой схеме работы с детальной статистикой
[stg.git] / projects / stargazer / plugins / store / files / file_store.cpp
1 /*
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.
6  *
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.
11  *
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
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21 /*
22  $Revision: 1.67 $
23  $Date: 2010/10/07 19:53:11 $
24  $Author: faust $
25  */
26
27 #ifndef _GNU_SOURCE
28 #define _GNU_SOURCE
29 #endif
30
31 #include <pwd.h>
32 #include <grp.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <sys/time.h>
37 #include <fcntl.h>
38 #include <dirent.h>
39
40 #include <cstdio>
41 #include <ctime>
42 #include <cerrno>
43 #include <cstring>
44 #include <sstream>
45 #include <algorithm>
46
47 #include "common.h"
48 #include "user_ips.h"
49 #include "user_conf.h"
50 #include "user_stat.h"
51 #include "stg_const.h"
52 #include "file_store.h"
53 #include "blowfish.h"
54 #include "stg_logger.h"
55 #include "stg_locker.h"
56
57 #define DELETED_USERS_DIR   "deleted_users"
58
59 #define adm_enc_passwd "cjeifY8m3"
60
61 using namespace std;
62
63 const int pt_mega = 1024 * 1024;
64 //-----------------------------------------------------------------------------
65 class BAK_FILE
66 {
67 public:
68
69     //-------------------------------------------------------------------------
70     BAK_FILE(const string & fileName, bool removeBak)
71             : f(NULL),
72               removeBak(false)
73         {
74         bakSuccessed = false;
75         BAK_FILE::removeBak = removeBak;
76         fileNameBak = fileName + ".bak";
77         /*struct stat fileStat;
78         if (stat(fileName.c_str(), &fileStat) == 0)
79             {
80             char * buff = new char[fileStat.st_size];
81             f = fopen(fileName.c_str(), "rb");
82             if(f)
83                 {
84                 fread(buff, 1, fileStat.st_size, f);
85                 fclose(f);
86
87                 fileNameBak = fileName + ".bak";
88                 f = fopen(fileNameBak.c_str(), "wb");
89                 if(f)
90                     {
91                     fwrite(buff, 1, fileStat.st_size, f);
92                     fclose(f);
93                     }
94                 }
95
96             delete[] buff;
97
98             bakSuccessed = true;
99             }*/
100         if (rename(fileName.c_str(), fileNameBak.c_str()))
101             {
102             printfd(__FILE__, "BAK_FILE::BAK_FILE - rename failed. Message: '%s'\n", strerror(errno));
103             }
104         else
105             {
106             bakSuccessed = true;
107             }
108
109         }
110     //-------------------------------------------------------------------------
111     ~BAK_FILE()
112         {
113         if(bakSuccessed && removeBak)
114             {
115             if (unlink(fileNameBak.c_str()))
116                 {
117                 printfd(__FILE__, "BAK_FILE::~BAK_FILE - unlink failed. Message: '%s'\n", strerror(errno));
118                 }
119             }
120         }
121     //-------------------------------------------------------------------------
122
123 private:
124     FILE * f;
125     bool bakSuccessed;
126     string fileNameBak;
127     bool removeBak;
128 };
129 //-----------------------------------------------------------------------------
130 class FILES_STORE_CREATOR
131 {
132 private:
133     FILES_STORE * fs;
134
135 public:
136     FILES_STORE_CREATOR()
137         : fs(new FILES_STORE())
138         {
139         };
140     ~FILES_STORE_CREATOR()
141         {
142         delete fs;
143         };
144
145     FILES_STORE * GetStore()
146     {
147         return fs;
148     };
149 };
150 //-----------------------------------------------------------------------------
151 //-----------------------------------------------------------------------------
152 //-----------------------------------------------------------------------------
153 FILES_STORE_CREATOR fsc;
154 //-----------------------------------------------------------------------------
155 //-----------------------------------------------------------------------------
156 //-----------------------------------------------------------------------------
157 BASE_STORE * GetStore()
158 {
159 return fsc.GetStore();
160 }
161 //-----------------------------------------------------------------------------
162 FILES_STORE_SETTINGS::FILES_STORE_SETTINGS()
163     : settings(NULL),
164       removeBak(true),
165       readBak(true)
166 {
167 }
168 //-----------------------------------------------------------------------------
169 FILES_STORE_SETTINGS::~FILES_STORE_SETTINGS()
170 {
171 }
172 //-----------------------------------------------------------------------------
173 int FILES_STORE_SETTINGS::ParseOwner(const vector<PARAM_VALUE> & moduleParams, const string & owner, uid_t * uid)
174 {
175 PARAM_VALUE pv;
176 pv.param = owner;
177 vector<PARAM_VALUE>::const_iterator pvi;
178 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
179 if (pvi == moduleParams.end())
180     {
181     errorStr = "Parameter \'" + owner + "\' not found.";
182     printfd(__FILE__, "%s\n", errorStr.c_str());
183     return -1;
184     }
185 if (User2UID(pvi->value[0].c_str(), uid) < 0)
186     {
187     errorStr = "Parameter \'" + owner + "\': Unknown user \'" + pvi->value[0] + "\'";
188     printfd(__FILE__, "%s\n", errorStr.c_str());
189     return -1;
190     }
191 return 0;
192 }
193 //-----------------------------------------------------------------------------
194 int FILES_STORE_SETTINGS::ParseGroup(const vector<PARAM_VALUE> & moduleParams, const string & group, gid_t * gid)
195 {
196 PARAM_VALUE pv;
197 pv.param = group;
198 vector<PARAM_VALUE>::const_iterator pvi;
199 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
200 if (pvi == moduleParams.end())
201     {
202     errorStr = "Parameter \'" + group + "\' not found.";
203     printfd(__FILE__, "%s\n", errorStr.c_str());
204     return -1;
205     }
206 if (Group2GID(pvi->value[0].c_str(), gid) < 0)
207     {
208     errorStr = "Parameter \'" + group + "\': Unknown group \'" + pvi->value[0] + "\'";
209     printfd(__FILE__, "%s\n", errorStr.c_str());
210     return -1;
211     }
212 return 0;
213 }
214 //-----------------------------------------------------------------------------
215 int FILES_STORE_SETTINGS::ParseYesNo(const string & value, bool * val)
216 {
217 if (0 == strcasecmp(value.c_str(), "yes"))
218     {
219     *val = true;
220     return 0;
221     }
222 if (0 == strcasecmp(value.c_str(), "no"))
223     {
224     *val = false;
225     return 0;
226     }
227
228 errorStr = "Incorrect value \'" + value + "\'.";
229 return -1;
230 }
231 //-----------------------------------------------------------------------------
232 int FILES_STORE_SETTINGS::ParseMode(const vector<PARAM_VALUE> & moduleParams, const string & modeStr, mode_t * mode)
233 {
234 PARAM_VALUE pv;
235 pv.param = modeStr;
236 vector<PARAM_VALUE>::const_iterator pvi;
237 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
238 if (pvi == moduleParams.end())
239     {
240     errorStr = "Parameter \'" + modeStr + "\' not found.";
241     printfd(__FILE__, "%s\n", errorStr.c_str());
242     return -1;
243     }
244 if (Str2Mode(pvi->value[0].c_str(), mode) < 0)
245     {
246     errorStr = "Parameter \'" + modeStr + "\': Incorrect mode \'" + pvi->value[0] + "\'";
247     printfd(__FILE__, "%s\n", errorStr.c_str());
248     return -1;
249     }
250 return 0;
251 }
252 //-----------------------------------------------------------------------------
253 int FILES_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
254 {
255 if (ParseOwner(s.moduleParams, "StatOwner", &statUID) < 0)
256     return -1;
257 if (ParseGroup(s.moduleParams, "StatGroup", &statGID) < 0)
258     return -1;
259 if (ParseMode(s.moduleParams, "StatMode", &statMode) < 0)
260     return -1;
261
262 if (ParseOwner(s.moduleParams, "ConfOwner", &confUID) < 0)
263     return -1;
264 if (ParseGroup(s.moduleParams, "ConfGroup", &confGID) < 0)
265     return -1;
266 if (ParseMode(s.moduleParams, "ConfMode", &confMode) < 0)
267     return -1;
268
269 if (ParseOwner(s.moduleParams, "UserLogOwner", &userLogUID) < 0)
270     return -1;
271 if (ParseGroup(s.moduleParams, "UserLogGroup", &userLogGID) < 0)
272     return -1;
273 if (ParseMode(s.moduleParams, "UserLogMode", &userLogMode) < 0)
274     return -1;
275
276 vector<PARAM_VALUE>::const_iterator pvi;
277 PARAM_VALUE pv;
278 pv.param = "RemoveBak";
279 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
280 if (pvi == s.moduleParams.end())
281     {
282     removeBak = true;
283     }
284 else
285     {
286     if (ParseYesNo(pvi->value[0], &removeBak))
287         {
288         printfd(__FILE__, "Cannot parse parameter 'RemoveBak'\n");
289         return -1;
290         }
291     }
292
293 pv.param = "ReadBak";
294 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
295 if (pvi == s.moduleParams.end())
296     {
297     readBak = false;
298     }
299 else
300     {
301     if (ParseYesNo(pvi->value[0], &readBak))
302         {
303         printfd(__FILE__, "Cannot parse parameter 'ReadBak'\n");
304         return -1;
305         }
306     }
307
308 pv.param = "WorkDir";
309 pvi = find(s.moduleParams.begin(), s.moduleParams.end(), pv);
310 if (pvi == s.moduleParams.end())
311     {
312     errorStr = "Parameter \'WorkDir\' not found.";
313     printfd(__FILE__, "Parameter 'WorkDir' not found\n");
314     return -1;
315     }
316
317 workDir = pvi->value[0];
318 if (workDir.size() && workDir[workDir.size() - 1] == '/')
319     {
320     workDir.resize(workDir.size() - 1);
321     }
322 usersDir = workDir + "/users/";
323 tariffsDir = workDir + "/tariffs/";
324 adminsDir = workDir + "/admins/";
325
326 return 0;
327 }
328 //-----------------------------------------------------------------------------
329 const string & FILES_STORE_SETTINGS::GetStrError() const
330 {
331 return errorStr;
332 }
333 //-----------------------------------------------------------------------------
334 int FILES_STORE_SETTINGS::User2UID(const char * user, uid_t * uid)
335 {
336 struct passwd * pw;
337 pw = getpwnam(user);
338 if (!pw)
339     {
340     errorStr = string("User \'") + string(user) + string("\' not found in system.");
341     printfd(__FILE__, "%s\n", errorStr.c_str());
342     return -1;
343     }
344
345 *uid = pw->pw_uid;
346 return 0;
347 }
348 //-----------------------------------------------------------------------------
349 int FILES_STORE_SETTINGS::Group2GID(const char * gr, gid_t * gid)
350 {
351 struct group * grp;
352 grp = getgrnam(gr);
353 if (!grp)
354     {
355     errorStr = string("Group \'") + string(gr) + string("\' not found in system.");
356     printfd(__FILE__, "%s\n", errorStr.c_str());
357     return -1;
358     }
359
360 *gid = grp->gr_gid;
361 return 0;
362 }
363 //-----------------------------------------------------------------------------
364 int FILES_STORE_SETTINGS::Str2Mode(const char * str, mode_t * mode)
365 {
366 char a;
367 char b;
368 char c;
369 if (strlen(str) > 3)
370     {
371     errorStr = string("Error parsing mode \'") + str + string("\'");
372     printfd(__FILE__, "%s\n", errorStr.c_str());
373     return -1;
374     }
375
376 for (int i = 0; i < 3; i++)
377     if (str[i] > '7' || str[i] < '0')
378         {
379         errorStr = string("Error parsing mode \'") + str + string("\'");
380         printfd(__FILE__, "%s\n", errorStr.c_str());
381         return -1;
382         }
383
384 a = str[0] - '0';
385 b = str[1] - '0';
386 c = str[2] - '0';
387
388 *mode = ((mode_t)c) + ((mode_t)b << 3) + ((mode_t)a << 6);
389
390 return 0;
391 }
392 //-----------------------------------------------------------------------------
393 string FILES_STORE_SETTINGS::GetWorkDir() const
394 {
395 return workDir;
396 }
397 //-----------------------------------------------------------------------------
398 string FILES_STORE_SETTINGS::GetUsersDir() const
399 {
400 return usersDir;
401 }
402 //-----------------------------------------------------------------------------
403 string FILES_STORE_SETTINGS::GetAdminsDir() const
404 {
405 return adminsDir;
406 }
407 //-----------------------------------------------------------------------------
408 string FILES_STORE_SETTINGS::GetTariffsDir() const
409 {
410 return tariffsDir;
411 }
412 //-----------------------------------------------------------------------------
413 mode_t FILES_STORE_SETTINGS::GetStatMode() const
414 {
415 return statMode;
416 }
417 //-----------------------------------------------------------------------------
418 mode_t FILES_STORE_SETTINGS::GetStatModeDir() const
419 {
420 mode_t mode = statMode;
421 if (statMode & S_IRUSR) mode |= S_IXUSR;
422 if (statMode & S_IRGRP) mode |= S_IXGRP;
423 if (statMode & S_IROTH) mode |= S_IXOTH;
424 return mode;
425 }
426 //-----------------------------------------------------------------------------
427 uid_t  FILES_STORE_SETTINGS::GetStatUID() const
428 {
429 return statUID;
430 }
431 //-----------------------------------------------------------------------------
432 gid_t  FILES_STORE_SETTINGS::GetStatGID() const
433 {
434 return statGID;
435 }
436 //-----------------------------------------------------------------------------
437 mode_t FILES_STORE_SETTINGS::GetConfMode() const
438 {
439 return confMode;
440 }
441 //-----------------------------------------------------------------------------
442 mode_t FILES_STORE_SETTINGS::GetConfModeDir() const
443 {
444 mode_t mode = confMode;
445 if (statMode & S_IRUSR) mode |= S_IXUSR;
446 if (statMode & S_IRGRP) mode |= S_IXGRP;
447 if (statMode & S_IROTH) mode |= S_IXOTH;
448 return mode;
449 }
450 //-----------------------------------------------------------------------------
451 uid_t  FILES_STORE_SETTINGS::GetConfUID() const
452 {
453 return confUID;
454 }
455 //-----------------------------------------------------------------------------
456 gid_t  FILES_STORE_SETTINGS::GetConfGID() const
457 {
458 return confGID;
459 }
460 //-----------------------------------------------------------------------------
461 mode_t FILES_STORE_SETTINGS::GetLogMode() const
462 {
463 return userLogMode;
464 }
465 //-----------------------------------------------------------------------------
466 uid_t  FILES_STORE_SETTINGS::GetLogUID() const
467 {
468 return userLogUID;
469 }
470 //-----------------------------------------------------------------------------
471 gid_t FILES_STORE_SETTINGS::GetLogGID() const
472 {
473 return userLogGID;
474 }
475 //-----------------------------------------------------------------------------
476 bool FILES_STORE_SETTINGS::GetRemoveBak() const
477 {
478 return removeBak;
479 }
480 //-----------------------------------------------------------------------------
481 bool FILES_STORE_SETTINGS::GetReadBak() const
482 {
483 return readBak;
484 }
485 //-----------------------------------------------------------------------------
486 //-----------------------------------------------------------------------------
487 //-----------------------------------------------------------------------------
488 //-----------------------------------------------------------------------------
489 //-----------------------------------------------------------------------------
490 /*BASE_SETTINGS * FILES_STORE::GetStoreSettings()
491 {
492 return &storeSettings;
493 }*/
494 //-----------------------------------------------------------------------------
495 FILES_STORE::FILES_STORE()
496 {
497 version = "file_store v.1.04";
498
499 pthread_mutexattr_t attr;
500 pthread_mutexattr_init(&attr);
501 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
502 pthread_mutex_init(&mutex, &attr);
503 };
504 //-----------------------------------------------------------------------------
505 FILES_STORE::~FILES_STORE()
506 {
507
508 };
509 //-----------------------------------------------------------------------------
510 void FILES_STORE::SetSettings(const MODULE_SETTINGS & s)
511 {
512 settings = s;
513 }
514 //-----------------------------------------------------------------------------
515 int FILES_STORE::ParseSettings()
516 {
517 int ret = storeSettings.ParseSettings(settings);
518 if (ret)
519     {
520     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
521     errorStr = storeSettings.GetStrError();
522     }
523 return ret;
524 }
525 //-----------------------------------------------------------------------------
526 const string & FILES_STORE::GetStrError() const
527 {
528 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
529 return errorStr;
530 }
531 //-----------------------------------------------------------------------------
532 const string & FILES_STORE::GetVersion() const
533 {
534 return version;
535 }
536 //-----------------------------------------------------------------------------
537 int FILES_STORE::GetFilesList(vector<string> * filesList, const string & directory, mode_t mode, const string & ext) const
538 {
539 // æÕÎËÃÉÑ ÐÒÏÓÍÁÔÒÉ×ÁÅÔ ÓÏÄÅÒÖÉÍÏÅ ÄÉÒÅËÔÏÒÉÉ
540 DIR * d;
541 string str;
542 struct stat st;
543 dirent * dir;
544
545 filesList->clear();
546
547 d = opendir(directory.c_str());
548
549 if (!d)
550     {
551     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
552     errorStr = "Directory \'" + directory + "\' cannot be opened.";
553     //printfd(__FILE__, "%s\n", errorStr.c_str());
554     return -1;
555     }
556
557 int d_nameLen;
558 int extLen = ext.size() ;
559 while ((dir = readdir(d)))
560     {
561     if (strcmp(dir->d_name, ".") && strcmp(dir->d_name, ".."))
562         {
563         str = directory + "/" + string(dir->d_name);
564         if (!stat(str.c_str(), &st))
565             {
566             if (st.st_mode & mode) // ïÔÓÅ× ÆÁÊÌÏ× or directories
567                 {
568                 d_nameLen = strlen(dir->d_name);
569                 if (d_nameLen > extLen)
570                     {
571                     if (strcmp(dir->d_name + (d_nameLen - extLen), ext.c_str()) == 0)
572                         {
573                         dir->d_name[d_nameLen - extLen] = 0;
574                         filesList->push_back(dir->d_name);
575                         }
576                     }
577                 }
578             }
579         }
580     }
581
582 closedir(d);
583 return 0;
584 }
585 //-----------------------------------------------------------------------------
586 int FILES_STORE::GetUsersList(vector<string> * usersList) const
587 {
588 return GetFilesList(usersList, storeSettings.GetUsersDir(), S_IFDIR, "");
589 }
590 //-----------------------------------------------------------------------------
591 int FILES_STORE::GetAdminsList(vector<string> * adminsList) const
592 {
593 return GetFilesList(adminsList, storeSettings.GetAdminsDir(), S_IFREG, ".adm");
594 }
595 //-----------------------------------------------------------------------------
596 int FILES_STORE::GetTariffsList(vector<string> * tariffsList) const
597 {
598 return GetFilesList(tariffsList, storeSettings.GetTariffsDir(), S_IFREG, ".tf");
599 }
600 //-----------------------------------------------------------------------------
601 int FILES_STORE::RemoveDir(const char * path) const
602 {
603 vector<string> filesList;
604
605 GetFilesList(&filesList, path, S_IFREG, "");
606
607 for (unsigned i = 0; i < filesList.size(); i++)
608     {
609     string file = path + string("/") + filesList[i];
610     if (unlink(file.c_str()))
611         {
612         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
613         errorStr = "unlink failed. Message: '";
614         errorStr += strerror(errno);
615         errorStr += "'";
616         printfd(__FILE__, "FILES_STORE::RemoveDir - unlink failed. Message: '%s'\n", strerror(errno));
617         return -1;
618         }
619     }
620
621 GetFilesList(&filesList, path, S_IFDIR, "");
622
623 for (unsigned i = 0; i < filesList.size(); i++)
624     {
625     string dir = string(path) + "/" + filesList[i];
626     RemoveDir(dir.c_str());
627     }
628
629 if (rmdir(path))
630     {
631     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
632     errorStr = "rmdir failed. Message: '";
633     errorStr += strerror(errno);
634     errorStr += "'";
635     printfd(__FILE__, "FILES_STORE::RemoveDir - rmdir failed. Message: '%s'\n", strerror(errno));
636     return -1;
637     }
638
639 return 0;
640 }
641 //-----------------------------------------------------------------------------
642 int FILES_STORE::AddUser(const string & login) const
643 {
644 FILE * f;
645 string fileName;
646
647 strprintf(&fileName, "%s%s", storeSettings.GetUsersDir().c_str(), login.c_str());
648
649 if (mkdir(fileName.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
650     {
651     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
652     errorStr = string("mkdir failed. Message: '") + strerror(errno) + "'";
653     printfd(__FILE__, "FILES_STORE::AddUser - mkdir failed. Message: '%s'\n", strerror(errno));
654     return -1;
655     }
656
657 strprintf(&fileName, "%s%s/conf", storeSettings.GetUsersDir().c_str(), login.c_str());
658 f = fopen(fileName.c_str(), "wt");
659 if (f)
660     {
661     if (fprintf(f, "\n") < 0)
662         {
663         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
664         errorStr = "fprintf failed. Message: '";
665         errorStr += strerror(errno);
666         errorStr += "'";
667         printfd(__FILE__, "FILES_STORE::AddUser - fprintf failed. Message: '%s'\n", strerror(errno));
668         return -1;
669         }
670     fclose(f);
671     }
672 else
673     {
674     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
675     errorStr = "Cannot create file \"" + fileName + "\'";
676     printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
677     return -1;
678     }
679
680 strprintf(&fileName, "%s%s/stat", storeSettings.GetUsersDir().c_str(), login.c_str());
681 f = fopen(fileName.c_str(), "wt");
682 if (f)
683     {
684     if (fprintf(f, "\n") < 0)
685         {
686         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
687         errorStr = "fprintf failed. Message: '";
688         errorStr += strerror(errno);
689         errorStr += "'";
690         printfd(__FILE__, "FILES_STORE::AddUser - fprintf failed. Message: '%s'\n", strerror(errno));
691         return -1;
692         }
693     fclose(f);
694     }
695 else
696     {
697     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
698     errorStr = "Cannot create file \"" + fileName + "\'";
699     printfd(__FILE__, "FILES_STORE::AddUser - fopen failed. Message: '%s'\n", strerror(errno));
700     return -1;
701     }
702 return 0;
703 }
704 //-----------------------------------------------------------------------------
705 int FILES_STORE::DelUser(const string & login) const
706 {
707 string dirName;
708 string dirName1;
709
710 strprintf(&dirName, "%s/"DELETED_USERS_DIR, storeSettings.GetWorkDir().c_str());
711 if (access(dirName.c_str(), F_OK) != 0)
712     {
713     if (mkdir(dirName.c_str(), 0700) != 0)
714         {
715         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
716         errorStr = "Directory '" + dirName + "' cannot be created.";
717         printfd(__FILE__, "FILES_STORE::DelUser - mkdir failed. Message: '%s'\n", strerror(errno));
718         return -1;
719         }
720     }
721
722 if (access(dirName.c_str(), F_OK) == 0)
723     {
724     strprintf(&dirName, "%s/"DELETED_USERS_DIR"/%s.%lu", storeSettings.GetWorkDir().c_str(), login.c_str(), time(NULL));
725     strprintf(&dirName1, "%s/%s", storeSettings.GetUsersDir().c_str(), login.c_str());
726     if (rename(dirName1.c_str(), dirName.c_str()))
727         {
728         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
729         errorStr = "Error moving dir from " + dirName1 + " to " + dirName;
730         printfd(__FILE__, "FILES_STORE::DelUser - rename failed. Message: '%s'\n", strerror(errno));
731         return -1;
732         }
733     }
734 else
735     {
736     strprintf(&dirName, "%s/%s", storeSettings.GetUsersDir().c_str(), login.c_str());
737     if (RemoveDir(dirName.c_str()))
738         {
739         return -1;
740         }
741     }
742 return 0;
743 }
744 //-----------------------------------------------------------------------------
745 int FILES_STORE::RestoreUserConf(USER_CONF * conf, const string & login) const
746 {
747 string fileName;
748 fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
749 if (RestoreUserConf(conf, login, fileName))
750     {
751     if (!storeSettings.GetReadBak())
752         {
753         return -1;
754         }
755     return RestoreUserConf(conf, login, fileName + ".bak");
756     }
757 return 0;
758 }
759 //-----------------------------------------------------------------------------
760 int FILES_STORE::RestoreUserConf(USER_CONF * conf, const string & login, const string & fileName) const
761 {
762 CONFIGFILE cf(fileName);
763 int e = cf.Error();
764 string str;
765
766 if (e)
767     {
768     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
769     errorStr = "User \'" + login + "\' data not read.";
770     printfd(__FILE__, "FILES_STORE::RestoreUserConf - conf read failed for user '%s'\n", login.c_str());
771     return -1;
772     }
773
774 if (cf.ReadString("Password", &conf->password, "") < 0)
775     {
776     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
777     errorStr = "User \'" + login + "\' data not read. Parameter Password.";
778     printfd(__FILE__, "FILES_STORE::RestoreUserConf - password read failed for user '%s'\n", login.c_str());
779     return -1;
780     }
781 if (conf->password.empty())
782     {
783     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
784     errorStr = "User \'" + login + "\' password is blank.";
785     printfd(__FILE__, "FILES_STORE::RestoreUserConf - password is blank for user '%s'\n", login.c_str());
786     return -1;
787     }
788
789 if (cf.ReadString("tariff", &conf->tariffName, "") < 0)
790     {
791     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
792     errorStr = "User \'" + login + "\' data not read. Parameter Tariff.";
793     printfd(__FILE__, "FILES_STORE::RestoreUserConf - tariff read failed for user '%s'\n", login.c_str());
794     return -1;
795     }
796 if (conf->tariffName.empty())
797     {
798     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
799     errorStr = "User \'" + login + "\' tariff is blank.";
800     printfd(__FILE__, "FILES_STORE::RestoreUserConf - tariff is blank for user '%s'\n", login.c_str());
801     return -1;
802     }
803
804 string ipStr;
805 cf.ReadString("IP", &ipStr, "?");
806 USER_IPS i;
807 try
808     {
809     i = StrToIPS(ipStr);
810     }
811 catch (string s)
812     {
813     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
814     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
815     printfd(__FILE__, "FILES_STORE::RestoreUserConf - ip read failed for user '%s'\n", login.c_str());
816     return -1;
817     }
818 conf->ips = i;
819
820 if (cf.ReadInt("alwaysOnline", &conf->alwaysOnline, 0) != 0)
821     {
822     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
823     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
824     printfd(__FILE__, "FILES_STORE::RestoreUserConf - alwaysonline read failed for user '%s'\n", login.c_str());
825     return -1;
826     }
827
828 if (cf.ReadInt("down", &conf->disabled, 0) != 0)
829     {
830     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
831     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
832     printfd(__FILE__, "FILES_STORE::RestoreUserConf - down read failed for user '%s'\n", login.c_str());
833     return -1;
834     }
835
836 if (cf.ReadInt("passive", &conf->passive, 0) != 0)
837     {
838     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
839     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
840     printfd(__FILE__, "FILES_STORE::RestoreUserConf - passive read failed for user '%s'\n", login.c_str());
841     return -1;
842     }
843
844 cf.ReadInt("DisabledDetailStat", &conf->disabledDetailStat, 0);
845 cf.ReadTime("CreditExpire", &conf->creditExpire, 0);
846 cf.ReadString("TariffChange", &conf->nextTariff, "");
847 cf.ReadString("Group", &conf->group, "");
848 cf.ReadString("RealName", &conf->realName, "");
849 cf.ReadString("Address", &conf->address, "");
850 cf.ReadString("Phone", &conf->phone, "");
851 cf.ReadString("Note", &conf->note, "");
852 cf.ReadString("email", &conf->email, "");
853
854 char userdataName[12];
855 for (int i = 0; i < USERDATA_NUM; i++)
856     {
857     snprintf(userdataName, 12, "Userdata%d", i);
858     cf.ReadString(userdataName, &conf->userdata[i], "");
859     }
860
861 if (cf.ReadDouble("Credit", &conf->credit, 0) != 0)
862     {
863     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
864     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
865     printfd(__FILE__, "FILES_STORE::RestoreUserConf - credit read failed for user '%s'\n", login.c_str());
866     return -1;
867     }
868
869 return 0;
870 }
871 //-----------------------------------------------------------------------------
872 int FILES_STORE::RestoreUserStat(USER_STAT * stat, const string & login) const
873 {
874 string fileName;
875 fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
876
877 if (RestoreUserStat(stat, login, fileName))
878     {
879     if (!storeSettings.GetReadBak())
880         {
881         return -1;
882         }
883     return RestoreUserStat(stat, login, fileName + ".bak");
884     }
885 return 0;
886 }
887 //-----------------------------------------------------------------------------
888 int FILES_STORE::RestoreUserStat(USER_STAT * stat, const string & login, const string & fileName) const
889 {
890 CONFIGFILE cf(fileName);
891
892 int e = cf.Error();
893
894 if (e)
895     {
896     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
897     errorStr = "User \'" + login + "\' stat not read. Cannot open file " + fileName + ".";
898     printfd(__FILE__, "FILES_STORE::RestoreUserStat - stat read failed for user '%s'\n", login.c_str());
899     return -1;
900     }
901
902 char s[22];
903
904 for (int i = 0; i < DIR_NUM; i++)
905     {
906     uint64_t traff;
907     snprintf(s, 22, "D%d", i);
908     if (cf.ReadULongLongInt(s, &traff, 0) != 0)
909         {
910         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
911         errorStr = "User \'" + login + "\' stat not read. Parameter " + string(s);
912         printfd(__FILE__, "FILES_STORE::RestoreUserStat - download stat read failed for user '%s'\n", login.c_str());
913         return -1;
914         }
915     stat->down[i] = traff;
916
917     snprintf(s, 22, "U%d", i);
918     if (cf.ReadULongLongInt(s, &traff, 0) != 0)
919         {
920         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
921         errorStr =   "User \'" + login + "\' stat not read. Parameter " + string(s);
922         printfd(__FILE__, "FILES_STORE::RestoreUserStat - upload stat read failed for user '%s'\n", login.c_str());
923         return -1;
924         }
925     stat->up[i] = traff;
926     }
927
928 if (cf.ReadDouble("Cash", &stat->cash, 0) != 0)
929     {
930     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
931     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
932     printfd(__FILE__, "FILES_STORE::RestoreUserStat - cash read failed for user '%s'\n", login.c_str());
933     return -1;
934     }
935
936 if (cf.ReadDouble("FreeMb", &stat->freeMb, 0) != 0)
937     {
938     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
939     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
940     printfd(__FILE__, "FILES_STORE::RestoreUserStat - freemb read failed for user '%s'\n", login.c_str());
941     return -1;
942     }
943
944 if (cf.ReadTime("LastCashAddTime", &stat->lastCashAddTime, 0) != 0)
945     {
946     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
947     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
948     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastcashaddtime read failed for user '%s'\n", login.c_str());
949     return -1;
950     }
951
952 if (cf.ReadTime("PassiveTime", &stat->passiveTime, 0) != 0)
953     {
954     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
955     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
956     printfd(__FILE__, "FILES_STORE::RestoreUserStat - passivetime read failed for user '%s'\n", login.c_str());
957     return -1;
958     }
959
960 if (cf.ReadDouble("LastCashAdd", &stat->lastCashAdd, 0) != 0)
961     {
962     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
963     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
964     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastcashadd read failed for user '%s'\n", login.c_str());
965     return -1;
966     }
967
968 if (cf.ReadTime("LastActivityTime", &stat->lastActivityTime, 0) != 0)
969     {
970     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
971     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
972     printfd(__FILE__, "FILES_STORE::RestoreUserStat - lastactivitytime read failed for user '%s'\n", login.c_str());
973     return -1;
974     }
975
976 return 0;
977 }
978 //-----------------------------------------------------------------------------
979 int FILES_STORE::SaveUserConf(const USER_CONF & conf, const string & login) const
980 {
981 string fileName;
982 fileName = storeSettings.GetUsersDir() + "/" + login + "/conf";
983
984 BAK_FILE bakFile(fileName, storeSettings.GetRemoveBak());
985
986 if (access(fileName.c_str(), W_OK) != 0)
987     {
988     FILE * f;
989     f = fopen(fileName.c_str(), "wb");
990     if (f)
991         fclose(f);
992     }
993
994 CONFIGFILE cfstat(fileName);
995
996 int e = cfstat.Error();
997
998 if (e)
999     {
1000     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1001     errorStr = string("User \'") + login + "\' conf not written\n";
1002     printfd(__FILE__, "FILES_STORE::SaveUserConf - conf write failed for user '%s'\n", login.c_str());
1003     return -1;
1004     }
1005
1006 e = chmod(fileName.c_str(), storeSettings.GetConfMode());
1007 e += chown(fileName.c_str(), storeSettings.GetConfUID(), storeSettings.GetConfGID());
1008
1009 if (e)
1010     {
1011     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1012     printfd(__FILE__, "FILES_STORE::SaveUserConf - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1013     }
1014
1015 cfstat.WriteString("Password",     conf.password);
1016 cfstat.WriteInt   ("Passive",      conf.passive);
1017 cfstat.WriteInt   ("Down",         conf.disabled);
1018 cfstat.WriteInt("DisabledDetailStat", conf.disabledDetailStat);
1019 cfstat.WriteInt   ("AlwaysOnline", conf.alwaysOnline);
1020 cfstat.WriteString("Tariff",       conf.tariffName);
1021 cfstat.WriteString("Address",      conf.address);
1022 cfstat.WriteString("Phone",        conf.phone);
1023 cfstat.WriteString("Email",        conf.email);
1024 cfstat.WriteString("Note",         conf.note);
1025 cfstat.WriteString("RealName",     conf.realName);
1026 cfstat.WriteString("Group",        conf.group);
1027 cfstat.WriteDouble("Credit",       conf.credit);
1028 cfstat.WriteString("TariffChange", conf.nextTariff);
1029
1030 char userdataName[12];
1031 for (int i = 0; i < USERDATA_NUM; i++)
1032     {
1033     snprintf(userdataName, 12, "Userdata%d", i);
1034     cfstat.WriteString(userdataName, conf.userdata[i]);
1035     }
1036 cfstat.WriteInt("CreditExpire",    conf.creditExpire);
1037
1038 stringstream ipStr;
1039 ipStr << conf.ips;
1040 cfstat.WriteString("IP", ipStr.str());
1041
1042 return 0;
1043 }
1044 //-----------------------------------------------------------------------------
1045 int FILES_STORE::SaveUserStat(const USER_STAT & stat, const string & login) const
1046 {
1047 char s[22];
1048 string fileName;
1049 fileName = storeSettings.GetUsersDir() + "/" + login + "/stat";
1050
1051 BAK_FILE bakFile(fileName, storeSettings.GetRemoveBak());
1052
1053 if (access(fileName.c_str(), W_OK) != 0)
1054     {
1055     FILE * f;
1056     f = fopen(fileName.c_str(), "wb");
1057     if (f)
1058         fclose(f);
1059     }
1060
1061 CONFIGFILE cfstat(fileName);
1062 int e = cfstat.Error();
1063
1064 if (e)
1065     {
1066     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1067     errorStr = string("User \'") + login + "\' stat not written\n";
1068     printfd(__FILE__, "FILES_STORE::SaveUserStat - stat write failed for user '%s'\n", login.c_str());
1069     return -1;
1070     }
1071
1072 for (int i = 0; i < DIR_NUM; i++)
1073     {
1074     snprintf(s, 22, "D%d", i);
1075     cfstat.WriteInt(s, stat.down[i]);
1076     snprintf(s, 22, "U%d", i);
1077     cfstat.WriteInt(s, stat.up[i]);
1078     }
1079
1080 cfstat.WriteDouble("Cash", stat.cash);
1081 cfstat.WriteDouble("FreeMb", stat.freeMb);
1082 cfstat.WriteDouble("LastCashAdd", stat.lastCashAdd);
1083 cfstat.WriteInt("LastCashAddTime", stat.lastCashAddTime);
1084 cfstat.WriteInt("PassiveTime", stat.passiveTime);
1085 cfstat.WriteInt("LastActivityTime", stat.lastActivityTime);
1086
1087 e = chmod(fileName.c_str(), storeSettings.GetStatMode());
1088 e += chown(fileName.c_str(), storeSettings.GetStatUID(), storeSettings.GetStatGID());
1089
1090 if (e)
1091     {
1092     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1093     printfd(__FILE__, "FILES_STORE::SaveUserStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1094     }
1095
1096 return 0;
1097 }
1098 //-----------------------------------------------------------------------------
1099 int FILES_STORE::WriteLogString(const string & str, const string & login) const
1100 {
1101 FILE * f;
1102 time_t tm = time(NULL);
1103 string fileName;
1104 fileName = storeSettings.GetUsersDir() + "/" + login + "/log";
1105 f = fopen(fileName.c_str(), "at");
1106
1107 if (f)
1108     {
1109     fprintf(f, "%s", LogDate(tm));
1110     fprintf(f, " -- ");
1111     fprintf(f, "%s", str.c_str());
1112     fprintf(f, "\n");
1113     fclose(f);
1114     }
1115 else
1116     {
1117     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1118     errorStr = "Cannot open \'" + fileName + "\'";
1119     printfd(__FILE__, "FILES_STORE::WriteLogString - log write failed for user '%s'\n", login.c_str());
1120     return -1;
1121     }
1122
1123 int e = chmod(fileName.c_str(), storeSettings.GetLogMode());
1124 e += chown(fileName.c_str(), storeSettings.GetLogUID(), storeSettings.GetLogGID());
1125
1126 if (e)
1127     {
1128     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1129     printfd(__FILE__, "FILES_STORE::WriteLogString - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1130     }
1131
1132 return 0;
1133 }
1134 //-----------------------------------------------------------------------------
1135 int FILES_STORE::WriteLog2String(const string & str, const string & login) const
1136 {
1137 FILE * f;
1138 time_t tm = time(NULL);
1139 string fileName;
1140 fileName = storeSettings.GetUsersDir() + "/" + login + "/log2";
1141 f = fopen(fileName.c_str(), "at");
1142
1143 if (f)
1144     {
1145     fprintf(f, "%s", LogDate(tm));
1146     fprintf(f, " -- ");
1147     fprintf(f, "%s", str.c_str());
1148     fprintf(f, "\n");
1149     fclose(f);
1150     }
1151 else
1152     {
1153     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1154     errorStr = "Cannot open \'" + fileName + "\'";
1155     printfd(__FILE__, "FILES_STORE::WriteLogString - log write failed for user '%s'\n", login.c_str());
1156     return -1;
1157     }
1158
1159 int e = chmod(fileName.c_str(), storeSettings.GetLogMode());
1160 e += chown(fileName.c_str(), storeSettings.GetLogUID(), storeSettings.GetLogGID());
1161
1162 if (e)
1163     {
1164     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1165     printfd(__FILE__, "FILES_STORE::WriteLogString - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1166     }
1167
1168 return 0;
1169 }
1170 //-----------------------------------------------------------------------------
1171 int FILES_STORE::WriteUserChgLog(const string & login,
1172                                  const string & admLogin,
1173                                  uint32_t       admIP,
1174                                  const string & paramName,
1175                                  const string & oldValue,
1176                                  const string & newValue,
1177                                  const string & message) const
1178 {
1179 string userLogMsg = "Admin \'" + admLogin + "\', " + inet_ntostring(admIP) + ": \'"
1180     + paramName + "\' parameter changed from \'" + oldValue +
1181     "\' to \'" + newValue + "\'. " + message;
1182
1183 return WriteLogString(userLogMsg, login);
1184 }
1185 //-----------------------------------------------------------------------------
1186 int FILES_STORE::WriteUserConnect(const string & login, uint32_t ip) const
1187 {
1188 string logStr = "Connect, " + inet_ntostring(ip);
1189 if (WriteLogString(logStr, login))
1190     return -1;
1191 return WriteLog2String(logStr, login);
1192 }
1193 //-----------------------------------------------------------------------------
1194 int FILES_STORE::WriteUserDisconnect(const string & login,
1195                                      const DIR_TRAFF & up,
1196                                      const DIR_TRAFF & down,
1197                                      const DIR_TRAFF & sessionUp,
1198                                      const DIR_TRAFF & sessionDown,
1199                                      double cash,
1200                                      double freeMb,
1201                                      const std::string & reason) const
1202 {
1203 stringstream logStr;
1204 logStr << "Disconnect, ";
1205 /*stringstream sssu;
1206 stringstream sssd;
1207 stringstream ssmu;
1208 stringstream ssmd;
1209 stringstream sscash;
1210
1211 ssmu << up;
1212 ssmd << down;
1213
1214 sssu << sessionUp;
1215 sssd << sessionDown;
1216
1217 sscash << cash;*/
1218
1219 logStr << " session upload: \'"
1220        << sessionUp
1221        << "\' session download: \'"
1222        << sessionDown
1223        << "\' month upload: \'"
1224        << up
1225        << "\' month download: \'"
1226        << down
1227        << "\' cash: \'"
1228        << cash
1229        << "\'";
1230
1231 if (WriteLogString(logStr.str(), login))
1232     return -1;
1233
1234 logStr << " freeMb: \'"
1235        << freeMb
1236        << "\'"
1237        << " reason: \'"
1238        << reason
1239        << "\'";
1240
1241 return WriteLog2String(logStr.str(), login);
1242 }
1243 //-----------------------------------------------------------------------------
1244 int FILES_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, const string & login) const
1245 {
1246 string str;
1247 CONFIGFILE * s;
1248 int e;
1249 FILE *f;
1250
1251 strprintf(&str,"%s/%s/stat.%d.%02d",
1252         storeSettings.GetUsersDir().c_str(), login.c_str(), year + 1900, month + 1);
1253
1254 if ((f = fopen(str.c_str(), "w")))
1255     {
1256     fprintf(f, "\n");
1257     fclose(f);
1258     }
1259
1260 s = new CONFIGFILE(str);
1261 e = s->Error();
1262
1263 if (e)
1264     {
1265     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1266     errorStr = "Cannot create file " + str;
1267     printfd(__FILE__, "FILES_STORE::SaveMonthStat - month stat write failed for user '%s'\n", login.c_str());
1268     return -1;
1269     }
1270
1271 char dirName[3];
1272
1273 for (int i = 0; i < DIR_NUM; i++)
1274     {
1275     snprintf(dirName, 3, "U%d", i);
1276     s->WriteInt(dirName, stat.up[i]);
1277     snprintf(dirName, 3, "D%d", i);
1278     s->WriteInt(dirName, stat.down[i]);
1279     }
1280
1281 s->WriteDouble("cash", stat.cash);
1282
1283 delete s;
1284
1285 return 0;
1286 }
1287 //-----------------------------------------------------------------------------*/
1288 int FILES_STORE::AddAdmin(const string & login) const
1289 {
1290 string fileName;
1291 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
1292 FILE * f;
1293 f = fopen(fileName.c_str(), "wt");
1294 if (f)
1295     {
1296     fprintf(f, "\n");
1297     fclose(f);
1298     return 0;
1299     }
1300
1301 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1302 errorStr = "Cannot create file " + fileName;
1303 printfd(__FILE__, "FILES_STORE::AddAdmin - failed to add admin '%s'\n", login.c_str());
1304 return -1;
1305 }
1306 //-----------------------------------------------------------------------------*/
1307 int FILES_STORE::DelAdmin(const string & login) const
1308 {
1309 string fileName;
1310 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
1311 if (unlink(fileName.c_str()))
1312     {
1313     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1314     errorStr = "unlink failed. Message: '";
1315     errorStr += strerror(errno);
1316     errorStr += "'";
1317     printfd(__FILE__, "FILES_STORE::DelAdmin - unlink failed. Message: '%s'\n", strerror(errno));
1318     }
1319 return 0;
1320 }
1321 //-----------------------------------------------------------------------------*/
1322 int FILES_STORE::SaveAdmin(const ADMIN_CONF & ac) const
1323 {
1324 char passwordE[2 * ADM_PASSWD_LEN + 2];
1325 char pass[ADM_PASSWD_LEN + 1];
1326 char adminPass[ADM_PASSWD_LEN + 1];
1327
1328 string fileName;
1329
1330 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), ac.login.c_str());
1331
1332 CONFIGFILE cf(fileName);
1333
1334 int e = cf.Error();
1335
1336 if (e)
1337     {
1338     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1339     errorStr = "Cannot write admin " + ac.login + ". " + fileName;
1340     printfd(__FILE__, "FILES_STORE::SaveAdmin - failed to save admin '%s'\n", ac.login.c_str());
1341     return -1;
1342     }
1343
1344 memset(pass, 0, sizeof(pass));
1345 memset(adminPass, 0, sizeof(adminPass));
1346
1347 BLOWFISH_CTX ctx;
1348 EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1349
1350 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1351 adminPass[ADM_PASSWD_LEN - 1] = 0;
1352
1353 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1354     {
1355     EncodeString(pass + 8*i, adminPass + 8*i, &ctx);
1356     }
1357
1358 pass[ADM_PASSWD_LEN - 1] = 0;
1359 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1360 //printfd(__FILE__, "passwordE %s\n", passwordE);
1361
1362 cf.WriteString("password", passwordE);
1363 cf.WriteInt("ChgConf",     ac.priv.userConf);
1364 cf.WriteInt("ChgPassword", ac.priv.userPasswd);
1365 cf.WriteInt("ChgStat",     ac.priv.userStat);
1366 cf.WriteInt("ChgCash",     ac.priv.userCash);
1367 cf.WriteInt("UsrAddDel",   ac.priv.userAddDel);
1368 cf.WriteInt("ChgTariff",   ac.priv.tariffChg);
1369 cf.WriteInt("ChgAdmin",    ac.priv.adminChg);
1370
1371 return 0;
1372 }
1373 //-----------------------------------------------------------------------------
1374 int FILES_STORE::RestoreAdmin(ADMIN_CONF * ac, const string & login) const
1375 {
1376 string fileName;
1377 strprintf(&fileName, "%s/%s.adm", storeSettings.GetAdminsDir().c_str(), login.c_str());
1378 CONFIGFILE cf(fileName);
1379 char pass[ADM_PASSWD_LEN + 1];
1380 char password[ADM_PASSWD_LEN + 1];
1381 char passwordE[2*ADM_PASSWD_LEN + 2];
1382 BLOWFISH_CTX ctx;
1383
1384 string p;
1385
1386 if (cf.Error())
1387     {
1388     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1389     errorStr = "Cannot open " + fileName;
1390     printfd(__FILE__, "FILES_STORE::RestoreAdmin - failed to restore admin '%s'\n", ac->login.c_str());
1391     return -1;
1392     }
1393
1394 int a;
1395
1396 if (cf.ReadString("password", &p, "*"))
1397     {
1398     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1399     errorStr = "Error in parameter password";
1400     printfd(__FILE__, "FILES_STORE::RestoreAdmin - password read failed for admin '%s'\n", ac->login.c_str());
1401     return -1;
1402     }
1403
1404 memset(passwordE, 0, sizeof(passwordE));
1405 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1406
1407 //printfd(__FILE__, "passwordE %s\n", passwordE);
1408
1409 memset(pass, 0, sizeof(pass));
1410
1411 if (passwordE[0] != 0)
1412     {
1413     Decode21(pass, passwordE);
1414     EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1415
1416     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1417         {
1418         DecodeString(password + 8*i, pass + 8*i, &ctx);
1419         }
1420     }
1421 else
1422     {
1423     password[0] = 0;
1424     }
1425
1426 ac->password = password;
1427
1428 if (cf.ReadInt("ChgConf", &a, 0) == 0)
1429     ac->priv.userConf = a;
1430 else
1431     {
1432     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1433     errorStr = "Error in parameter ChgConf";
1434     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgconf read failed for admin '%s'\n", ac->login.c_str());
1435     return -1;
1436     }
1437
1438 if (cf.ReadInt("ChgPassword", &a, 0) == 0)
1439     ac->priv.userPasswd = a;
1440 else
1441     {
1442     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1443     errorStr = "Error in parameter ChgPassword";
1444     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgpassword read failed for admin '%s'\n", ac->login.c_str());
1445     return -1;
1446     }
1447
1448 if (cf.ReadInt("ChgStat", &a, 0) == 0)
1449     ac->priv.userStat = a;
1450 else
1451     {
1452     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1453     errorStr = "Error in parameter ChgStat";
1454     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgstat read failed for admin '%s'\n", ac->login.c_str());
1455     return -1;
1456     }
1457
1458 if (cf.ReadInt("ChgCash", &a, 0) == 0)
1459     ac->priv.userCash = a;
1460 else
1461     {
1462     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1463     errorStr = "Error in parameter ChgCash";
1464     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgcash read failed for admin '%s'\n", ac->login.c_str());
1465     return -1;
1466     }
1467
1468 if (cf.ReadInt("UsrAddDel", &a, 0) == 0)
1469     ac->priv.userAddDel = a;
1470 else
1471     {
1472     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1473     errorStr = "Error in parameter UsrAddDel";
1474     printfd(__FILE__, "FILES_STORE::RestoreAdmin - usradddel read failed for admin '%s'\n", ac->login.c_str());
1475     return -1;
1476     }
1477
1478 if (cf.ReadInt("ChgAdmin", &a, 0) == 0)
1479     ac->priv.adminChg = a;
1480 else
1481     {
1482     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1483     errorStr = "Error in parameter ChgAdmin";
1484     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgadmin read failed for admin '%s'\n", ac->login.c_str());
1485     return -1;
1486     }
1487
1488 if (cf.ReadInt("ChgTariff", &a, 0) == 0)
1489     ac->priv.tariffChg = a;
1490 else
1491     {
1492     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1493     errorStr = "Error in parameter ChgTariff";
1494     printfd(__FILE__, "FILES_STORE::RestoreAdmin - chgtariff read failed for admin '%s'\n", ac->login.c_str());
1495     return -1;
1496     }
1497
1498 return 0;
1499 }
1500 //-----------------------------------------------------------------------------
1501 int FILES_STORE::AddTariff(const string & name) const
1502 {
1503 string fileName;
1504 strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
1505 FILE * f;
1506 f = fopen(fileName.c_str(), "wt");
1507 if (f)
1508     {
1509     fprintf(f, "\n");
1510     fclose(f);
1511     return 0;
1512     }
1513
1514 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1515 errorStr = "Cannot create file " + fileName;
1516 printfd(__FILE__, "FILES_STORE::AddTariff - failed to add tariff '%s'\n", name.c_str());
1517 return -1;
1518 }
1519 //-----------------------------------------------------------------------------
1520 int FILES_STORE::DelTariff(const string & name) const
1521 {
1522 string fileName;
1523 strprintf(&fileName, "%s/%s.tf", storeSettings.GetTariffsDir().c_str(), name.c_str());
1524 if (unlink(fileName.c_str()))
1525     {
1526     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1527     errorStr = "unlink failed. Message: '";
1528     errorStr += strerror(errno);
1529     errorStr += "'";
1530     printfd(__FILE__, "FILES_STORE::DelTariff - unlink failed. Message: '%s'\n", strerror(errno));
1531     }
1532 return 0;
1533 }
1534 //-----------------------------------------------------------------------------
1535 int FILES_STORE::RestoreTariff(TARIFF_DATA * td, const string & tariffName) const
1536 {
1537 string tariffFileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
1538 CONFIGFILE conf(tariffFileName);
1539 string str;
1540 td->tariffConf.name = tariffName;
1541
1542 if (conf.Error() != 0)
1543     {
1544     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1545     errorStr = "Cannot read file " + tariffFileName;
1546     printfd(__FILE__, "FILES_STORE::RestoreTariff - failed to read tariff '%s'\n", tariffName.c_str());
1547     return -1;
1548     }
1549
1550 string param;
1551 for (int i = 0; i<DIR_NUM; i++)
1552     {
1553     strprintf(&param, "Time%d", i);
1554     if (conf.ReadString(param, &str, "00:00-00:00") < 0)
1555         {
1556         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1557         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1558         printfd(__FILE__, "FILES_STORE::RestoreTariff - time%d read failed for tariff '%s'\n", i, tariffName.c_str());
1559         return -1;
1560         }
1561
1562     ParseTariffTimeStr(str.c_str(),
1563                        td->dirPrice[i].hDay,
1564                        td->dirPrice[i].mDay,
1565                        td->dirPrice[i].hNight,
1566                        td->dirPrice[i].mNight);
1567
1568     strprintf(&param, "PriceDayA%d", i);
1569     if (conf.ReadDouble(param, &td->dirPrice[i].priceDayA, 0.0) < 0)
1570         {
1571         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1572         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1573         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricedaya read failed for tariff '%s'\n", tariffName.c_str());
1574         return -1;
1575         }
1576     td->dirPrice[i].priceDayA /= (1024*1024);
1577
1578     strprintf(&param, "PriceDayB%d", i);
1579     if (conf.ReadDouble(param, &td->dirPrice[i].priceDayB, 0.0) < 0)
1580         {
1581         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1582         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1583         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricedayb read failed for tariff '%s'\n", tariffName.c_str());
1584         return -1;
1585         }
1586     td->dirPrice[i].priceDayB /= (1024*1024);
1587
1588     strprintf(&param, "PriceNightA%d", i);
1589     if (conf.ReadDouble(param, &td->dirPrice[i].priceNightA, 0.0) < 0)
1590         {
1591         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1592         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1593         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricenighta read failed for tariff '%s'\n", tariffName.c_str());
1594         return -1;
1595         }
1596     td->dirPrice[i].priceNightA /= (1024*1024);
1597
1598     strprintf(&param, "PriceNightB%d", i);
1599     if (conf.ReadDouble(param, &td->dirPrice[i].priceNightB, 0.0) < 0)
1600         {
1601         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1602         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1603         printfd(__FILE__, "FILES_STORE::RestoreTariff - pricenightb read failed for tariff '%s'\n", tariffName.c_str());
1604         return -1;
1605         }
1606     td->dirPrice[i].priceNightB /= (1024*1024);
1607
1608     strprintf(&param, "Threshold%d", i);
1609     if (conf.ReadInt(param, &td->dirPrice[i].threshold, 0) < 0)
1610         {
1611         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1612         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1613         printfd(__FILE__, "FILES_STORE::RestoreTariff - threshold read failed for tariff '%s'\n", tariffName.c_str());
1614         return -1;
1615         }
1616
1617     strprintf(&param, "SinglePrice%d", i);
1618     if (conf.ReadInt(param, &td->dirPrice[i].singlePrice, 0) < 0)
1619         {
1620         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1621         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1622         printfd(__FILE__, "FILES_STORE::RestoreTariff - singleprice read failed for tariff '%s'\n", tariffName.c_str());
1623         return -1;
1624         }
1625
1626     strprintf(&param, "NoDiscount%d", i);
1627     if (conf.ReadInt(param, &td->dirPrice[i].noDiscount, 0) < 0)
1628         {
1629         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1630         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1631         printfd(__FILE__, "FILES_STORE::RestoreTariff - nodiscount read failed for tariff '%s'\n", tariffName.c_str());
1632         return -1;
1633         }
1634     }
1635
1636 if (conf.ReadDouble("Fee", &td->tariffConf.fee, 0) < 0)
1637     {
1638     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1639     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1640     printfd(__FILE__, "FILES_STORE::RestoreTariff - fee read failed for tariff '%s'\n", tariffName.c_str());
1641     return -1;
1642     }
1643
1644 if (conf.ReadDouble("Free", &td->tariffConf.free, 0) < 0)
1645     {
1646     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1647     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1648     printfd(__FILE__, "FILES_STORE::RestoreTariff - free read failed for tariff '%s'\n", tariffName.c_str());
1649     return -1;
1650     }
1651
1652 if (conf.ReadDouble("PassiveCost", &td->tariffConf.passiveCost, 0) < 0)
1653     {
1654     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1655     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1656     printfd(__FILE__, "FILES_STORE::RestoreTariff - passivecost read failed for tariff '%s'\n", tariffName.c_str());
1657     return -1;
1658     }
1659
1660 if (conf.ReadString("TraffType", &str, "") < 0)
1661     {
1662     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1663     errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType";
1664     printfd(__FILE__, "FILES_STORE::RestoreTariff - trafftype read failed for tariff '%s'\n", tariffName.c_str());
1665     return -1;
1666     }
1667
1668 if (!strcasecmp(str.c_str(), "up"))
1669     td->tariffConf.traffType = TRAFF_UP;
1670 else
1671     if (!strcasecmp(str.c_str(), "down"))
1672         td->tariffConf.traffType = TRAFF_DOWN;
1673     else
1674         if (!strcasecmp(str.c_str(), "up+down"))
1675             td->tariffConf.traffType = TRAFF_UP_DOWN;
1676         else
1677             if (!strcasecmp(str.c_str(), "max"))
1678                 td->tariffConf.traffType = TRAFF_MAX;
1679             else
1680                 {
1681                 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1682                 errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType incorrect";
1683                 printfd(__FILE__, "FILES_STORE::RestoreTariff - invalid trafftype for tariff '%s'\n", tariffName.c_str());
1684                 return -1;
1685                 }
1686 return 0;
1687 }
1688 //-----------------------------------------------------------------------------
1689 int FILES_STORE::SaveTariff(const TARIFF_DATA & td, const string & tariffName) const
1690 {
1691 string tariffFileName = storeSettings.GetTariffsDir() + "/" + tariffName + ".tf";
1692 if (access(tariffFileName.c_str(), W_OK) != 0)
1693     {
1694     int fd = open(tariffFileName.c_str(), O_CREAT, 0600);
1695     if (fd)
1696         close(fd);
1697     }
1698
1699 CONFIGFILE cf(tariffFileName);
1700
1701 int e = cf.Error();
1702
1703 if (e)
1704     {
1705     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1706     errorStr = "Error writing tariff " + tariffName;
1707     printfd(__FILE__, "FILES_STORE::RestoreTariff - failed to save tariff '%s'\n", tariffName.c_str());
1708     return e;
1709     }
1710
1711 string param;
1712 for (int i = 0; i < DIR_NUM; i++)
1713     {
1714     strprintf(&param, "PriceDayA%d", i);
1715     cf.WriteDouble(param, td.dirPrice[i].priceDayA * pt_mega);
1716
1717     strprintf(&param, "PriceDayB%d", i);
1718     cf.WriteDouble(param, td.dirPrice[i].priceDayB * pt_mega);
1719
1720     strprintf(&param, "PriceNightA%d", i);
1721     cf.WriteDouble(param, td.dirPrice[i].priceNightA * pt_mega);
1722
1723     strprintf(&param, "PriceNightB%d", i);
1724     cf.WriteDouble(param, td.dirPrice[i].priceNightB * pt_mega);
1725
1726     strprintf(&param, "Threshold%d", i);
1727     cf.WriteInt(param, td.dirPrice[i].threshold);
1728
1729     string s;
1730     strprintf(&param, "Time%d", i);
1731
1732     strprintf(&s, "%0d:%0d-%0d:%0d",
1733             td.dirPrice[i].hDay,
1734             td.dirPrice[i].mDay,
1735             td.dirPrice[i].hNight,
1736             td.dirPrice[i].mNight);
1737
1738     cf.WriteString(param, s);
1739
1740     strprintf(&param, "NoDiscount%d", i);
1741     cf.WriteInt(param, td.dirPrice[i].noDiscount);
1742
1743     strprintf(&param, "SinglePrice%d", i);
1744     cf.WriteInt(param, td.dirPrice[i].singlePrice);
1745     }
1746
1747 cf.WriteDouble("PassiveCost", td.tariffConf.passiveCost);
1748 cf.WriteDouble("Fee", td.tariffConf.fee);
1749 cf.WriteDouble("Free", td.tariffConf.free);
1750
1751 switch (td.tariffConf.traffType)
1752     {
1753     case TRAFF_UP:
1754         cf.WriteString("TraffType", "up");
1755         break;
1756     case TRAFF_DOWN:
1757         cf.WriteString("TraffType", "down");
1758         break;
1759     case TRAFF_UP_DOWN:
1760         cf.WriteString("TraffType", "up+down");
1761         break;
1762     case TRAFF_MAX:
1763         cf.WriteString("TraffType", "max");
1764         break;
1765     }
1766 return 0;
1767 }
1768 //-----------------------------------------------------------------------------
1769 int FILES_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> * statTree,
1770                                    time_t lastStat,
1771                                    const string & login) const
1772 {
1773 char fn[FN_STR_LEN];
1774 char dn[FN_STR_LEN];
1775 FILE * statFile;
1776 //char timestr[30];
1777 time_t t;//, lastTimeReal;
1778 tm * lt;
1779
1780 t = time(NULL);
1781
1782 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat", storeSettings.GetUsersDir().c_str(), login.c_str());
1783 if (access(dn, F_OK) != 0)
1784     {
1785     if (mkdir(dn, 0700) != 0)
1786         {
1787         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1788         errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
1789         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
1790         return -1;
1791         }
1792     }
1793
1794 int e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
1795 e += chmod(dn, storeSettings.GetStatModeDir());
1796
1797 if (e)
1798     {
1799     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1800     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1801     }
1802
1803 lt = localtime(&t);
1804
1805 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1806     {
1807     t -= 3600 * 24;
1808     lt = localtime(&t);
1809     }
1810
1811 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat/%d",
1812          storeSettings.GetUsersDir().c_str(),
1813          login.c_str(),
1814          lt->tm_year+1900);
1815
1816 if (access(dn, F_OK) != 0)
1817     {
1818     if (mkdir(dn, 0700) != 0)
1819         {
1820         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1821         errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
1822         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
1823         return -1;
1824         }
1825     }
1826
1827 e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
1828 e += chmod(dn, storeSettings.GetStatModeDir());
1829
1830 if (e)
1831     {
1832     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1833     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1834     }
1835
1836 snprintf(dn, FN_STR_LEN, "%s/%s/detail_stat/%d/%s%d", 
1837          storeSettings.GetUsersDir().c_str(),
1838          login.c_str(),
1839          lt->tm_year+1900,
1840          lt->tm_mon+1 < 10 ? "0" : "",
1841          lt->tm_mon+1);
1842 if (access(dn, F_OK) != 0)
1843     {
1844     if (mkdir(dn, 0700) != 0)
1845         {
1846         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1847         errorStr = "Directory \'" + string(dn) + "\' cannot be created.";
1848         printfd(__FILE__, "FILES_STORE::WriteDetailStat - mkdir failed. Message: '%s'\n", strerror(errno));
1849         return -1;
1850         }
1851     }
1852
1853 e = chown(dn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
1854 e += chmod(dn, storeSettings.GetStatModeDir());
1855
1856 if (e)
1857     {
1858     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1859     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1860     }
1861
1862 snprintf(fn, FN_STR_LEN, "%s/%s%d", dn, lt->tm_mday < 10 ? "0" : "", lt->tm_mday);
1863
1864 statFile = fopen (fn, "at");
1865
1866 if (!statFile)
1867     {
1868     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1869     errorStr = "File \'" + string(fn) + "\' cannot be written.";
1870     printfd(__FILE__, "FILES_STORE::WriteDetailStat - fopen failed. Message: '%s'\n", strerror(errno));
1871     return -1;
1872     }
1873
1874 struct tm * lt1;
1875 struct tm * lt2;
1876
1877 lt1 = localtime(&lastStat);
1878
1879 int h1, m1, s1;
1880 int h2, m2, s2;
1881
1882 h1 = lt1->tm_hour;
1883 m1 = lt1->tm_min;
1884 s1 = lt1->tm_sec;
1885
1886 lt2 = localtime(&t);
1887
1888 h2 = lt2->tm_hour;
1889 m2 = lt2->tm_min;
1890 s2 = lt2->tm_sec;
1891
1892 if (fprintf(statFile, "-> %02d.%02d.%02d - %02d.%02d.%02d\n",
1893             h1, m1, s1, h2, m2, s2) < 0)
1894     {
1895     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1896     errorStr = string("fprint failed. Message: '") + strerror(errno) + "'";
1897     printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
1898     return -1;
1899     }
1900
1901 map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
1902 stIter = statTree->begin();
1903
1904 while (stIter != statTree->end())
1905     {
1906     string u, d;
1907     x2str(stIter->second.up, u);
1908     x2str(stIter->second.down, d);
1909     #ifdef TRAFF_STAT_WITH_PORTS
1910     if (fprintf(statFile, "%17s:%hu\t%15d\t%15s\t%15s\t%f\n",
1911                 inet_ntostring(stIter->first.ip).c_str(),
1912                 stIter->first.port,
1913                 stIter->first.dir,
1914                 d.c_str(),
1915                 u.c_str(),
1916                 stIter->second.cash) < 0)
1917         {
1918         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1919         errorStr = "fprint failed. Message: '";
1920         errorStr += strerror(errno);
1921         errorStr += "'";
1922         printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
1923         return -1;
1924         }
1925     #else
1926     if (fprintf(statFile, "%17s\t%15d\t%15s\t%15s\t%f\n",
1927                 inet_ntostring(stIter->first.ip).c_str(),
1928                 stIter->first.dir,
1929                 d.c_str(),
1930                 u.c_str(),
1931                 stIter->second.cash) < 0)
1932         {
1933         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1934         errorStr = string("fprint failed. Message: '");
1935         errorStr += strerror(errno);
1936         errorStr += "'";
1937         printfd(__FILE__, "FILES_STORE::WriteDetailStat - fprintf failed. Message: '%s'\n", strerror(errno));
1938         return -1;
1939         }
1940     #endif
1941
1942     ++stIter;
1943     }
1944
1945 fclose(statFile);
1946
1947 e = chown(fn, storeSettings.GetStatUID(), storeSettings.GetStatGID());
1948 e += chmod(fn, storeSettings.GetStatMode());
1949
1950 if (e)
1951     {
1952     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1953     printfd(__FILE__, "FILES_STORE::WriteDetailStat - chmod/chown failed for user '%s'. Error: '%s'\n", login.c_str(), strerror(errno));
1954     }
1955
1956 return 0;
1957 }
1958 //-----------------------------------------------------------------------------
1959 int FILES_STORE::AddMessage(STG_MSG * msg, const string & login) const
1960 {
1961 //ðÒÏ×ÅÒÉÔØ ÅÓÌÔØ ÌÉ ÄÉÒÅËÔÏÒÉÑ ÄÌÑ ÓÏÏÂÝÅÎÉÊ. åÓÌÉ ÎÅÔ - ÓÏÚÄÁÔØ.
1962 //úÁÔÅÍ ÐÏÌÏÖÉÔØ ÓÏÏÂÝÅÎÉÅ Ó ÉÍÅÎÅÍ ÆÁÊÌÁ - ×ÒÅÍÅÎÎOÊ ÍÅÔËÏÊ. úÁÐÉÓÁÔØ ÔÕÄÁ
1963 //ÔÅËÓÔ É ÐÒÉÏÒÉÔÅÔ.
1964
1965 string fn;
1966 string dn;
1967 struct timeval tv;
1968 FILE * msgFile;
1969
1970 strprintf(&dn, "%s/%s/messages", storeSettings.GetUsersDir().c_str(), login.c_str());
1971 if (access(dn.c_str(), F_OK) != 0)
1972     {
1973     if (mkdir(dn.c_str(), 0700) != 0)
1974         {
1975         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1976         errorStr = "Directory \'";
1977         errorStr += dn;
1978         errorStr += "\' cannot be created.";
1979         printfd(__FILE__, "FILES_STORE::AddMessage - mkdir failed. Message: '%s'\n", strerror(errno));
1980         return -1;
1981         }
1982     }
1983
1984 chmod(dn.c_str(), storeSettings.GetConfMode() | S_IXUSR);
1985
1986 gettimeofday(&tv, NULL);
1987
1988 msg->header.id = ((long long)tv.tv_sec) * 1000000 + ((long long)tv.tv_usec);
1989 strprintf(&fn, "%s/%lld", dn.c_str(), msg->header.id);
1990
1991 msgFile = fopen (fn.c_str(), "wt");
1992
1993 if (!msgFile)
1994     {
1995     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1996     errorStr = "File \'";
1997     errorStr += fn;
1998     errorStr += "\' cannot be writen.";
1999     printfd(__FILE__, "FILES_STORE::AddMessage - fopen failed. Message: '%s'\n", strerror(errno));
2000     return -1;
2001     }
2002 fclose(msgFile);
2003 return EditMessage(*msg, login);
2004 }
2005 //-----------------------------------------------------------------------------
2006 int FILES_STORE::EditMessage(const STG_MSG & msg, const string & login) const
2007 {
2008 //ðÒÏ×ÅÒÉÔØ ÅÓÌÔØ ÌÉ ÄÉÒÅËÔÏÒÉÑ ÄÌÑ ÓÏÏÂÝÅÎÉÊ. åÓÌÉ ÎÅÔ - ÓÏÚÄÁÔØ.
2009 //úÁÔÅÍ ÐÏÌÏÖÉÔØ ÓÏÏÂÝÅÎÉÅ Ó ÉÍÅÎÅÍ ÆÁÊÌÁ - ×ÒÅÍÅÎÎOÊ ÍÅÔËÏÊ. úÁÐÉÓÁÔØ ÔÕÄÁ
2010 //ÔÅËÓÔ É ÐÒÉÏÒÉÔÅÔ.
2011
2012 string fn;
2013
2014 FILE * msgFile;
2015 strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), msg.header.id);
2016
2017 if (access(fn.c_str(), F_OK) != 0)
2018     {
2019     string idstr;
2020     x2str(msg.header.id, idstr);
2021     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2022     errorStr = "Message for user \'";
2023     errorStr += login + "\' with ID \'";
2024     errorStr += idstr + "\' does not exist.";
2025     printfd(__FILE__, "FILES_STORE::EditMessage - %s\n", errorStr.c_str());
2026     return -1;
2027     }
2028
2029 msgFile = fopen(fn.c_str(), "wt");
2030 if (!msgFile)
2031     {
2032     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2033     errorStr = "File \'" + fn + "\' cannot be writen.";
2034     printfd(__FILE__, "FILES_STORE::EditMessage - fopen failed. Message: '%s'\n", strerror(errno));
2035     return -1;
2036     }
2037
2038 bool res = true;
2039 res &= (fprintf(msgFile, "%d\n", msg.header.type) >= 0);
2040 res &= (fprintf(msgFile, "%u\n", msg.header.lastSendTime) >= 0);
2041 res &= (fprintf(msgFile, "%u\n", msg.header.creationTime) >= 0);
2042 res &= (fprintf(msgFile, "%u\n", msg.header.showTime) >= 0);
2043 res &= (fprintf(msgFile, "%d\n", msg.header.repeat) >= 0);
2044 res &= (fprintf(msgFile, "%u\n", msg.header.repeatPeriod) >= 0);
2045 res &= (fprintf(msgFile, "%s", msg.text.c_str()) >= 0);
2046
2047 if (!res)
2048     {
2049     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2050     errorStr = string("fprintf failed. Message: '") + strerror(errno) + "'";
2051     printfd(__FILE__, "FILES_STORE::EditMessage - fprintf failed. Message: '%s'\n", strerror(errno));
2052     return -1;
2053     }
2054
2055 fclose(msgFile);
2056
2057 chmod(fn.c_str(), storeSettings.GetConfMode());
2058 return 0;
2059 }
2060 //-----------------------------------------------------------------------------
2061 int FILES_STORE::GetMessage(uint64_t id, STG_MSG * msg, const string & login) const
2062 {
2063 string fn;
2064 strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
2065 msg->header.id = id;
2066 return ReadMessage(fn, &msg->header, &msg->text);
2067 }
2068 //-----------------------------------------------------------------------------
2069 int FILES_STORE::DelMessage(uint64_t id, const string & login) const
2070 {
2071 string fn;
2072 strprintf(&fn, "%s/%s/messages/%lld", storeSettings.GetUsersDir().c_str(), login.c_str(), id);
2073
2074 return unlink(fn.c_str());
2075 }
2076 //-----------------------------------------------------------------------------
2077 int FILES_STORE::GetMessageHdrs(vector<STG_MSG_HDR> * hdrsList, const string & login) const
2078 {
2079 vector<string> messages;
2080 string dn;
2081 dn = storeSettings.GetUsersDir() + "/" + login + "/messages/";
2082 GetFilesList(&messages, dn, S_IFREG, "");
2083
2084 //hdrsList->resize(messages.size());
2085
2086 for (unsigned i = 0; i < messages.size(); i++)
2087     {
2088     unsigned long long id = 0;
2089
2090     if (str2x(messages[i].c_str(), id))
2091         {
2092         if (unlink((dn + messages[i]).c_str()))
2093             {
2094             STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2095             errorStr = string("unlink failed. Message: '") + strerror(errno) + "'";
2096             printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
2097             return -1;
2098             }
2099         continue;
2100         }
2101
2102     STG_MSG_HDR hdr;
2103     if (ReadMessage(dn + messages[i], &hdr, NULL))
2104         {
2105         return -1;
2106         }
2107
2108     if (hdr.repeat < 0)
2109         {
2110         if (unlink((dn + messages[i]).c_str()))
2111             {
2112             STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2113             errorStr = string("unlink failed. Message: '") + strerror(errno) + "'";
2114             printfd(__FILE__, "FILES_STORE::GetMessageHdrs - unlink failed. Message: '%s'\n", strerror(errno));
2115             return -1;
2116             }
2117         continue;
2118         }
2119
2120     hdr.id = id;
2121     hdrsList->push_back(hdr);
2122     }
2123 return 0;
2124 }
2125 //-----------------------------------------------------------------------------
2126 int FILES_STORE::ReadMessage(const string & fileName,
2127                              STG_MSG_HDR * hdr,
2128                              string * text) const
2129 {
2130 FILE * msgFile;
2131 msgFile = fopen(fileName.c_str(), "rt");
2132 if (!msgFile)
2133     {
2134     STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2135     errorStr = "File \'";
2136     errorStr += fileName;
2137     errorStr += "\' cannot be openned.";
2138     printfd(__FILE__, "FILES_STORE::ReadMessage - fopen failed. Message: '%s'\n", strerror(errno));
2139     return -1;
2140     }
2141 char p[20];
2142 unsigned * d[6];
2143 d[0] = &hdr->type;
2144 d[1] = &hdr->lastSendTime;
2145 d[2] = &hdr->creationTime;
2146 d[3] = &hdr->showTime;
2147 d[4] = (unsigned*)(&hdr->repeat);
2148 d[5] = &hdr->repeatPeriod;
2149
2150 memset(p, 0, sizeof(p));
2151
2152 for (int pos = 0; pos < 6; pos++)
2153     {
2154     if (fgets(p, sizeof(p) - 1, msgFile) == NULL) {
2155         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2156         errorStr = "Cannot read file \'";
2157         errorStr += fileName;
2158         errorStr += "\'. Missing data.";
2159         printfd(__FILE__, "FILES_STORE::ReadMessage - cannot read file (missing data)\n");
2160         printfd(__FILE__, "FILES_STORE::ReadMessage - position: %d\n", pos);
2161         fclose(msgFile);
2162         return -1;
2163     }
2164
2165     char * ep;
2166     ep = strrchr(p, '\r');
2167     if (ep) *ep = 0;
2168     ep = strrchr(p, '\n');
2169     if (ep) *ep = 0;
2170
2171     if (feof(msgFile))
2172         {
2173         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2174         errorStr = "Cannot read file \'";
2175         errorStr += fileName;
2176         errorStr += "\'. Missing data.";
2177         printfd(__FILE__, "FILES_STORE::ReadMessage - cannot read file (feof)\n");
2178         printfd(__FILE__, "FILES_STORE::ReadMessage - position: %d\n", pos);
2179         fclose(msgFile);
2180         return -1;
2181         }
2182
2183     if (str2x(p, *(d[pos])))
2184         {
2185         STG_LOCKER lock(&mutex, __FILE__, __LINE__);
2186         errorStr = "Cannot read file \'";
2187         errorStr += fileName;
2188         errorStr += "\'. Incorrect value. \'";
2189         errorStr += p;
2190         errorStr += "\'";
2191         printfd(__FILE__, "FILES_STORE::ReadMessage - incorrect value\n");
2192         fclose(msgFile);
2193         return -1;
2194         }
2195     }
2196
2197 char txt[2048];
2198 memset(txt, 0, sizeof(txt));
2199 if (text)
2200     {
2201     text->erase(text->begin(), text->end());
2202     while (!feof(msgFile))
2203         {
2204         txt[0] = 0;
2205         if (fgets(txt, sizeof(txt) - 1, msgFile) == NULL) {
2206             break;
2207         }
2208
2209         (*text) += txt;
2210         }
2211     }
2212 //fprintf(msgFile, "%s\n", msg.text.c_str());
2213 fclose(msgFile);
2214 return 0;
2215 }
2216 //-----------------------------------------------------------------------------
2217