]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/store/mysql/.#mysql_store.cpp.1.3
Переход к новой схеме работы с детальной статистикой
[stg.git] / projects / stargazer / plugins / store / mysql / .#mysql_store.cpp.1.3
1 #include <sys/time.h>
2 #include <errno.h>
3 #include <string>
4
5 #include <mysql/mysql.h>
6 #include <mysql/errmsg.h>
7
8 #include "user_ips.h"
9 #include "user_conf.h"
10 #include "user_stat.h"
11 #include "mysql_store.h"
12 #include "blowfish.h"
13
14 #define adm_enc_passwd "cjeifY8m3"
15 char qbuf[4096];
16
17 using namespace std;
18
19 const int pt_mega = 1024 * 1024;
20 const string badSyms = "'`";
21 const char repSym = '\"';
22 const int RepitTimes = 3;
23
24 int GetInt(const string & str, int * val, int defaultVal)
25 {
26     char *res;
27     
28     *val = strtol(str.c_str(), &res, 10);
29     
30     if (*res != 0) 
31     {
32         *val = defaultVal; //Error!
33         return EINVAL;
34     }
35
36     return 0;
37 }
38
39 int GetDouble(const string & str, double * val, double defaultVal)
40 {
41     char *res;
42     
43     *val = strtod(str.c_str(), &res);
44     
45     if (*res != 0) 
46     {
47         *val = defaultVal; //Error!
48         return EINVAL;
49     }
50
51     return 0;
52 }
53
54 int GetTime(const string & str, time_t * val, time_t defaultVal)
55 {
56     char *res;
57     
58     *val = strtol(str.c_str(), &res, 10);
59     
60     if (*res != 0) 
61     {
62         *val = defaultVal; //Error!
63         return EINVAL;
64     }
65
66     return 0;
67 }
68
69 //-----------------------------------------------------------------------------
70 string ReplaceStr(string source, const string symlist, const char chgsym)
71 {
72     string::size_type pos=0;
73
74     while( (pos = source.find_first_of(symlist,pos)) != string::npos)
75         source.replace(pos, 1,1, chgsym);
76
77     return source;
78 }
79
80 int GetULongLongInt(const string & str, uint64_t * val, uint64_t defaultVal)
81 {
82     char *res;
83     
84     *val = strtoull(str.c_str(), &res, 10);
85     
86     if (*res != 0) 
87     {
88         *val = defaultVal; //Error!
89         return EINVAL;
90     }
91
92     return 0;
93
94
95 class STORE_CREATOR
96 {
97 private:
98     BASE_STORE * bs;
99
100 public:
101     STORE_CREATOR()
102         {
103         bs = new MYSQL_STORE();
104         };
105     ~STORE_CREATOR()
106         {
107         if (bs)
108             delete bs;
109         };
110
111     BASE_STORE * GetStore()
112     {
113         return bs;
114     };
115 };
116 //-----------------------------------------------------------------------------
117 //-----------------------------------------------------------------------------
118 //-----------------------------------------------------------------------------
119 //STORE_CREATOR sc;
120 //-----------------------------------------------------------------------------
121 //-----------------------------------------------------------------------------
122 //-----------------------------------------------------------------------------
123 BASE_STORE * GetStore()
124 {
125 //return sc.GetStore();
126 return new MYSQL_STORE();
127 }
128 //-----------------------------------------------------------------------------
129 MYSQL_STORE_SETTINGS::MYSQL_STORE_SETTINGS()
130 {
131 }
132 //-----------------------------------------------------------------------------
133 MYSQL_STORE_SETTINGS::~MYSQL_STORE_SETTINGS()
134 {
135
136 }
137 //-----------------------------------------------------------------------------
138 int MYSQL_STORE_SETTINGS::ParseParam(const vector<PARAM_VALUE> & moduleParams, 
139                         const string & name, string & result)
140 {
141 PARAM_VALUE pv;
142 pv.param = name;
143 vector<PARAM_VALUE>::const_iterator pvi;
144 pvi = find(moduleParams.begin(), moduleParams.end(), pv);
145 if (pvi == moduleParams.end())
146     {
147     errorStr = "Parameter \'" + name + "\' not found.";
148     return -1;
149     }
150     
151 result = pvi->value[0];
152
153 return 0;
154 }
155 //-----------------------------------------------------------------------------
156 int MYSQL_STORE_SETTINGS::ParseSettings(const MODULE_SETTINGS & s)
157 {
158 if (ParseParam(s.moduleParams, "dbuser", dbUser) < 0)
159     return -1;
160 if (ParseParam(s.moduleParams, "rootdbpass", dbPass) < 0)
161     return -1;
162 if (ParseParam(s.moduleParams, "dbname", dbName) < 0)
163     return -1;
164 if (ParseParam(s.moduleParams, "dbhost", dbHost) < 0)
165     return -1;
166
167 return 0;
168 }
169 //-----------------------------------------------------------------------------
170 const string & MYSQL_STORE_SETTINGS::GetStrError() const
171 {
172 return errorStr;
173 }
174 //-----------------------------------------------------------------------------
175 string MYSQL_STORE_SETTINGS::GetDBUser() const
176 {
177 return dbUser;
178 }
179 //-----------------------------------------------------------------------------
180 string MYSQL_STORE_SETTINGS::GetDBPassword() const
181 {
182 return dbPass;
183 }
184 //-----------------------------------------------------------------------------
185 string MYSQL_STORE_SETTINGS::GetDBHost() const
186 {
187 return dbHost;
188 }
189 //-----------------------------------------------------------------------------
190 string MYSQL_STORE_SETTINGS::GetDBName() const
191 {
192 return dbName;
193 }
194 //-----------------------------------------------------------------------------
195 //-----------------------------------------------------------------------------
196 //-----------------------------------------------------------------------------
197 MYSQL_STORE::MYSQL_STORE()
198 {
199 version = "mysql_store v.0.67";
200 };
201 //-----------------------------------------------------------------------------
202 MYSQL_STORE::~MYSQL_STORE()
203 {    
204 };
205 //-----------------------------------------------------------------------------
206 void MYSQL_STORE::SetSettings(const MODULE_SETTINGS & s)
207 {
208 settings = s;
209 }
210 //-----------------------------------------------------------------------------
211 int    MYSQL_STORE::MysqlQuery(const char* sQuery,MYSQL * sock) const
212 {
213     int ret,i;
214
215     if( (ret = mysql_query(sock,sQuery)) )
216     {
217         for(i=0; i<RepitTimes; i++)
218         {
219             if( (ret = mysql_query(sock,sQuery)) )
220                 ;//need to send error result
221             else
222                 return 0;
223         }
224     }
225     
226     return ret;
227 }
228 //-----------------------------------------------------------------------------
229
230 //-----------------------------------------------------------------------------
231 int MYSQL_STORE::ParseSettings()
232 {
233 int ret = storeSettings.ParseSettings(settings);
234 MYSQL mysql;
235 MYSQL * sock;
236 mysql_init(&mysql);
237 if (ret)
238     errorStr = storeSettings.GetStrError();
239 else
240 {
241     if(storeSettings.GetDBPassword().length() == 0)
242     {
243         errorStr = "Database password must be not empty. Please read Manual.";
244         return -1;
245     }
246     
247     if (!(sock = mysql_real_connect(&mysql,storeSettings.GetDBHost().c_str(),
248             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
249             0,0,NULL,0)))
250         {
251             errorStr = "Couldn't connect to mysql engine! With error:\n";
252             errorStr += mysql_error(&mysql);
253             mysql_close(sock);
254             ret = -1;
255         }
256     else
257     {
258          if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
259          {
260              string res = "CREATE DATABASE " + storeSettings.GetDBName();
261             
262             if(MysqlQuery(res.c_str(),sock))
263             {
264                 errorStr = "Couldn't create database! With error:\n";
265                 errorStr += mysql_error(sock);
266                 mysql_close(sock);
267                 ret = -1;
268             }
269             else
270             {
271                  if(mysql_select_db(sock, storeSettings.GetDBName().c_str()))
272                  {
273                     errorStr = "Couldn't select database! With error:\n";
274                     errorStr += mysql_error(sock);
275                     mysql_close(sock);
276                     ret = -1;
277                  }
278                  ret = CheckAllTables(sock);
279             }
280          }
281          else
282              ret = CheckAllTables(sock);
283          mysql_close(sock);
284     }
285     
286 }
287 return ret;
288 }
289 //-----------------------------------------------------------------------------
290 const string & MYSQL_STORE::GetStrError() const
291 {
292 return errorStr;
293 }
294 //-----------------------------------------------------------------------------
295 const string & MYSQL_STORE::GetVersion() const
296 {
297 return version;
298 }
299 //-----------------------------------------------------------------------------
300 bool MYSQL_STORE::IsTablePresent(const string & str,MYSQL * sock)
301 {
302 MYSQL_RES* result;
303
304 if (!(result=mysql_list_tables(sock,str.c_str() )))
305 {
306     errorStr = "Couldn't get tables list With error:\n";
307     errorStr += mysql_error(sock);
308     mysql_close(sock);
309     return -1;
310 }
311
312 unsigned int num_rows =  mysql_num_rows(result);
313
314 if(result)
315     mysql_free_result(result);
316
317 return (num_rows == 1);
318 }
319 //-----------------------------------------------------------------------------
320 int MYSQL_STORE::CheckAllTables(MYSQL * sock)
321 {
322 //admins-----------------------------------------------------------------------
323 if(!IsTablePresent("admins",sock))
324 {
325     sprintf(qbuf,"CREATE TABLE admins (login VARCHAR(40) DEFAULT '' PRIMARY KEY,"\
326         "password VARCHAR(150) DEFAULT '*',ChgConf TINYINT DEFAULT 0,"\
327         "ChgPassword TINYINT DEFAULT 0,ChgStat TINYINT DEFAULT 0,"\
328         "ChgCash TINYINT DEFAULT 0,UsrAddDel TINYINT DEFAULT 0,"\
329         "ChgTariff TINYINT DEFAULT 0,ChgAdmin TINYINT DEFAULT 0)");
330     
331     if(MysqlQuery(qbuf,sock))
332     {
333         errorStr = "Couldn't create admin table list With error:\n";
334         errorStr += mysql_error(sock);
335         mysql_close(sock);
336         return -1;
337     }
338
339     sprintf(qbuf,"INSERT INTO admins SET login='admin',"\
340         "password='geahonjehjfofnhammefahbbbfbmpkmkmmefahbbbfbmpkmkmmefahbbbfbmpkmkaa',"\
341         "ChgConf=1,ChgPassword=1,ChgStat=1,ChgCash=1,UsrAddDel=1,ChgTariff=1,ChgAdmin=1");
342     
343     if(MysqlQuery(qbuf,sock))
344     {
345         errorStr = "Couldn't create default admin. With error:\n";
346         errorStr += mysql_error(sock);
347         mysql_close(sock);
348         return -1;
349     }
350 }
351
352 //tariffs-----------------------------------------------------------------------
353 string param, res;
354 if(!IsTablePresent("tariffs",sock))
355 {
356     res = "CREATE TABLE tariffs (name VARCHAR(40) DEFAULT '' PRIMARY KEY,";
357         
358     for (int i = 0; i < DIR_NUM; i++)
359         {
360         strprintf(&param, " PriceDayA%d DOUBLE DEFAULT 0.0,", i); 
361         res += param;
362     
363         strprintf(&param, " PriceDayB%d DOUBLE DEFAULT 0.0,", i);
364         res += param;
365             
366         strprintf(&param, " PriceNightA%d DOUBLE DEFAULT 0.0,", i);
367         res += param;
368     
369         strprintf(&param, " PriceNightB%d DOUBLE DEFAULT 0.0,", i);
370         res += param;
371             
372         strprintf(&param, " Threshold%d INT DEFAULT 0,", i);
373         res += param;
374     
375         string s;
376         strprintf(&param, " Time%d VARCHAR(15) DEFAULT '0:0-0:0',", i);
377         res += param;
378     
379         strprintf(&param, " NoDiscount%d INT DEFAULT 0,", i);
380         res += param;
381     
382         strprintf(&param, " SinglePrice%d INT DEFAULT 0,", i);
383         res += param;
384         }
385     
386     res += "PassiveCost DOUBLE DEFAULT 0.0, Fee DOUBLE DEFAULT 0.0,"\
387         "Free DOUBLE DEFAULT 0.0, TraffType VARCHAR(10) DEFAULT '')";
388     
389     if(MysqlQuery(res.c_str(),sock))
390     {
391         errorStr = "Couldn't create tariffs table list With error:\n";
392         errorStr += mysql_error(sock);
393         mysql_close(sock);
394         return -1;
395     }
396
397     res = "INSERT INTO tariffs SET name='tariff',";
398         
399     for (int i = 0; i < DIR_NUM; i++)
400         {
401         strprintf(&param, " NoDiscount%d=1,", i);
402         res += param;
403     
404         strprintf(&param, " Threshold%d=0,", i);
405         res += param;
406     
407         strprintf(&param, " Time%d='0:0-0:0',", i);
408         res += param;
409     
410         if(i != 0 && i != 1)
411         {
412             strprintf(&param, " SinglePrice%d=0,", i);
413             res += param;        
414         }
415     
416         if(i != 1)
417         {
418             strprintf(&param, " PriceDayA%d=0.0,", i); 
419             res += param;        
420         }
421         if(i != 1)
422         {
423             strprintf(&param, " PriceDayB%d=0.0,", i);        
424             res += param;    
425         }
426     
427         if(i != 0)
428         {
429             strprintf(&param, " PriceNightA%d=0.0,", i); 
430             res += param;        
431         }
432         if(i != 0)
433         {
434             strprintf(&param, " PriceNightB%d=0.0,", i);        
435             res += param;    
436         }
437         }
438     
439     res += "PassiveCost=0.0, Fee=10.0, Free=0,"\
440         "SinglePrice0=1, SinglePrice1=1,PriceDayA1=0.75,PriceDayB1=0.75,"\
441         "PriceNightA0=1.0,PriceNightB0=1.0,TraffType='up+down'";
442     
443     if(MysqlQuery(res.c_str(),sock))
444     {
445         errorStr = "Couldn't create default tariff. With error:\n";
446         errorStr += mysql_error(sock);
447         mysql_close(sock);
448         return -1;
449     }
450 }
451
452 //users-----------------------------------------------------------------------
453 if(!IsTablePresent("users",sock))
454 {
455     res = "CREATE TABLE users (login VARCHAR(50) NOT NULL DEFAULT '' PRIMARY KEY, Password VARCHAR(150) NOT NULL DEFAULT '*',"\
456         "Passive INT(3) DEFAULT 0,Down INT(3) DEFAULT 0,DisabledDetailStat INT(3) DEFAULT 0,AlwaysOnline INT(3) DEFAULT 0,Tariff VARCHAR(40) NOT NULL DEFAULT '',"\
457         "Address VARCHAR(254) NOT NULL DEFAULT '',Phone VARCHAR(128) NOT NULL DEFAULT '',Email VARCHAR(50) NOT NULL DEFAULT '',"\
458         "Note TEXT NOT NULL,RealName VARCHAR(254) NOT NULL DEFAULT '',StgGroup VARCHAR(40) NOT NULL DEFAULT '',"\
459         "Credit DOUBLE DEFAULT 0, TariffChange VARCHAR(40) NOT NULL DEFAULT '',";
460     
461     for (int i = 0; i < USERDATA_NUM; i++)
462         {
463         strprintf(&param, " Userdata%d VARCHAR(254) NOT NULL,", i);
464         res += param;
465         }
466     
467     param = " CreditExpire INT(11) DEFAULT 0,";
468     res += param;
469     
470     strprintf(&param, " IP VARCHAR(254) DEFAULT '*',");
471     res += param;
472     
473     for (int i = 0; i < DIR_NUM; i++)
474         {
475         strprintf(&param, " D%d BIGINT(30) DEFAULT 0,", i);
476         res += param;
477     
478         strprintf(&param, " U%d BIGINT(30) DEFAULT 0,", i);
479         res += param;
480         }
481     
482     strprintf(&param, "Cash DOUBLE DEFAULT 0,FreeMb DOUBLE DEFAULT 0,LastCashAdd DOUBLE DEFAULT 0,"\
483         "LastCashAddTime INT(11) DEFAULT 0,PassiveTime INT(11) DEFAULT 0,LastActivityTime INT(11) DEFAULT 0,"\
484         "NAS VARCHAR(17) NOT NULL, INDEX (AlwaysOnline), INDEX (IP), INDEX (Address),"\
485         " INDEX (Tariff),INDEX (Phone),INDEX (Email),INDEX (RealName))");
486     res += param;
487         
488     if(MysqlQuery(res.c_str(),sock))
489     {
490         errorStr = "Couldn't create users table list With error:\n";
491         errorStr += mysql_error(sock);
492         errorStr += "\n\n" + res;
493         mysql_close(sock);
494         return -1;
495     }
496
497     res = "INSERT INTO users SET login='test',Address='',AlwaysOnline=0,"\
498         "Credit=0.0,CreditExpire=0,Down=0,Email='',DisabledDetailStat=0,"\
499         "StgGroup='',IP='192.168.1.1',Note='',Passive=0,Password='123456',"\
500         "Phone='', RealName='',Tariff='tariff',TariffChange='',Userdata0='',"\
501         "Userdata1='',";
502     
503     for (int i = 0; i < DIR_NUM; i++)
504         {
505         strprintf(&param, " D%d=0,", i);
506         res += param;
507     
508         strprintf(&param, " U%d=0,", i);
509         res += param;
510         }
511     
512     res += "Cash=10.0,FreeMb=0.0,LastActivityTime=0,LastCashAdd=0,"\
513         "LastCashAddTime=0, PassiveTime=0";
514         
515     if(MysqlQuery(res.c_str(),sock))
516     {
517         errorStr = "Couldn't create default user. With error:\n";
518         errorStr += mysql_error(sock);
519         mysql_close(sock);
520         return -1;
521     }
522 }
523 /*
524 //logs-----------------------------------------------------------------------
525 if(!IsTablePresent("logs"))
526 {
527     sprintf(qbuf,"CREATE TABLE logs (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)");
528     
529     if(MysqlQuery(qbuf))
530     {
531         errorStr = "Couldn't create admin table list With error:\n";
532         errorStr += mysql_error(sock);
533         return -1;
534     }
535 }
536 */
537 //messages---------------------------------------------------------------------
538 if(!IsTablePresent("messages",sock))
539 {
540     sprintf(qbuf,"CREATE TABLE messages (login VARCHAR(40) DEFAULT '', id BIGINT, "\
541             "type INT, lastSendTime INT, creationTime INT, showTime INT,"\
542             "stgRepeat INT, repeatPeriod INT, text TEXT)");
543     
544     if(MysqlQuery(qbuf,sock))
545     {
546         errorStr = "Couldn't create messages table. With error:\n";
547         errorStr += mysql_error(sock);
548         mysql_close(sock);
549         return -1;
550     }
551 }
552
553 //month_stat-------------------------------------------------------------------
554 if(!IsTablePresent("stat",sock))
555 {
556     res = "CREATE TABLE stat (login VARCHAR(50), month TINYINT, year SMALLINT,";
557     
558     for (int i = 0; i < DIR_NUM; i++)
559         {
560         strprintf(&param, " U%d BIGINT,", i); 
561         res += param;
562             
563         strprintf(&param, " D%d BIGINT,", i); 
564         res += param;
565         }
566         
567     res += " cash DOUBLE, INDEX (login))";
568     
569     if(MysqlQuery(res.c_str(),sock))
570     {
571         errorStr = "Couldn't create stat table. With error:\n";
572         errorStr += mysql_error(sock);
573         mysql_close(sock);
574         return -1;
575     }
576 }
577
578 return 0;
579 }
580 //-----------------------------------------------------------------------------
581 //-----------------------------------------------------------------------------
582
583 int MYSQL_STORE::GetAllParams(vector<string> * ParamList, 
584                             const string & table, const string & name) const
585 {
586 MYSQL_RES *res;
587 MYSQL_ROW row;
588 MYSQL * sock=NULL;
589 unsigned int num,i;
590     
591 ParamList->clear();
592     
593 sprintf(qbuf,"SELECT %s FROM %s", name.c_str(), table.c_str());
594     
595 if(MysqlGetQuery(qbuf,sock))
596 {
597     errorStr = "Couldn't GetAllParams Query for: ";
598     errorStr += name + " - " + table + "\n";
599     errorStr += mysql_error(sock);
600     mysql_close(sock);
601     return -1;
602 }
603
604 if (!(res=mysql_store_result(sock)))
605 {
606     errorStr = "Couldn't GetAllParams Results for: ";
607     errorStr += name + " - " + table + "\n";
608     errorStr += mysql_error(sock);
609     return -1;
610 }
611
612 num = mysql_num_rows(res);
613
614 for(i=0;i<num;i++)
615 {
616     row = mysql_fetch_row(res);    
617     ParamList->push_back(row[0]);
618 }
619
620 mysql_free_result(res);
621 mysql_close(sock);
622
623 return 0;
624 }
625
626 //-----------------------------------------------------------------------------
627 int MYSQL_STORE::GetUsersList(vector<string> * usersList) const
628 {
629 if(GetAllParams(usersList, "users", "login"))
630     return -1;
631
632 return 0;
633 }
634 //-----------------------------------------------------------------------------
635 int MYSQL_STORE::GetAdminsList(vector<string> * adminsList) const
636 {
637 if(GetAllParams(adminsList, "admins", "login"))
638     return -1;
639
640 return 0;
641 }
642 //-----------------------------------------------------------------------------
643 int MYSQL_STORE::GetTariffsList(vector<string> * tariffsList) const
644 {
645 if(GetAllParams(tariffsList, "tariffs", "name"))
646     return -1;
647
648 return 0;
649 }
650 //-----------------------------------------------------------------------------
651 int MYSQL_STORE::AddUser(const string & login) const
652 {
653 sprintf(qbuf,"INSERT INTO users SET login='%s'", login.c_str());
654     
655 if(MysqlSetQuery(qbuf))
656 {
657     errorStr = "Couldn't add user:\n";
658     //errorStr += mysql_error(sock);
659     return -1;
660 }
661
662 return 0;
663 }
664 //-----------------------------------------------------------------------------
665 int MYSQL_STORE::DelUser(const string & login) const
666 {
667 sprintf(qbuf,"DELETE FROM users WHERE login='%s' LIMIT 1", login.c_str());
668     
669 if(MysqlSetQuery(qbuf))
670 {
671     errorStr = "Couldn't delete user:\n";
672     //errorStr += mysql_error(sock);
673     return -1;
674 }
675
676 return 0;
677 }
678 //-----------------------------------------------------------------------------
679 int MYSQL_STORE::RestoreUserConf(USER_CONF * conf, const string & login) const
680 {
681 MYSQL_RES *res;
682 MYSQL_ROW row;
683 MYSQL * sock;
684 string query;
685
686 query = "SELECT login, Password, Passive, Down, DisabledDetailStat, \
687          AlwaysOnline, Tariff, Address, Phone, Email, Note, \
688          RealName, StgGroup, Credit, TariffChange, ";
689
690 for (int i = 0; i < USERDATA_NUM; i++)
691 {
692     sprintf(qbuf, "Userdata%d, ", i);
693     query += qbuf;
694 }
695
696 query += "CreditExpire, IP FROM users WHERE login='";
697 query += login + "' LIMIT 1";
698
699 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
700     
701 if(MysqlGetQuery(query.c_str(),sock))
702 {
703     errorStr = "Couldn't restore Tariff(on query):\n";
704     errorStr += mysql_error(sock);
705     mysql_close(sock);
706     return -1;
707 }
708
709 if (!(res=mysql_store_result(sock)))
710 {
711     errorStr = "Couldn't restore Tariff(on getting result):\n";
712     errorStr += mysql_error(sock);
713     mysql_close(sock);
714     return -1;
715 }
716
717 row = mysql_fetch_row(res);
718
719 string param;
720
721 conf->password = row[1];
722
723 if (conf->password.empty())
724     {
725     mysql_free_result(res);
726     errorStr = "User \'" + login + "\' password is blank.";
727     mysql_close(sock);
728     return -1;
729     }
730
731 if (GetInt(row[2],&conf->passive, 0) != 0)
732     {
733     mysql_free_result(res);
734     errorStr = "User \'" + login + "\' data not read. Parameter Passive.";
735     mysql_close(sock);
736     return -1;
737     }
738
739 if (GetInt(row[3], &conf->disabled, 0) != 0)
740     {
741     mysql_free_result(res);
742     errorStr = "User \'" + login + "\' data not read. Parameter Down.";
743     mysql_close(sock);
744     return -1;
745     }
746
747 if (GetInt(row[4], &conf->disabledDetailStat, 0) != 0)
748     {
749     mysql_free_result(res);
750     errorStr = "User \'" + login + "\' data not read. Parameter DisabledDetailStat.";
751     mysql_close(sock);
752     return -1;
753     }
754
755 if (GetInt(row[5], &conf->alwaysOnline, 0) != 0)
756     {
757     mysql_free_result(res);
758     errorStr = "User \'" + login + "\' data not read. Parameter AlwaysOnline.";
759     mysql_close(sock);
760     return -1;
761     }
762
763 conf->tariffName = row[6];
764
765 if (conf->tariffName.empty()) 
766     {
767     mysql_free_result(res);
768     errorStr = "User \'" + login + "\' tariff is blank.";
769     mysql_close(sock);
770     return -1;
771     }
772
773 conf->address = row[7];
774 conf->phone = row[8];
775 conf->email = row[9];
776 conf->note = row[10];
777 conf->realName = row[11];
778 conf->group = row[12];
779
780 if (GetDouble(row[13], &conf->credit, 0) != 0)
781     {
782     mysql_free_result(res);
783     errorStr = "User \'" + login + "\' data not read. Parameter Credit.";
784     mysql_close(sock);
785     return -1;
786     }
787
788 conf->nextTariff = row[14];
789
790 for (int i = 0; i < USERDATA_NUM; i++)
791     {
792     conf->userdata[i] = row[15+i];
793     }
794
795 GetTime(row[15+USERDATA_NUM], &conf->creditExpire, 0);
796     
797 string ipStr = row[16+USERDATA_NUM];
798 USER_IPS i;
799 try
800     {
801     i = StrToIPS(ipStr);
802     }
803 catch (string s)
804     {
805     mysql_free_result(res);
806     errorStr = "User \'" + login + "\' data not read. Parameter IP address. " + s;
807     mysql_close(sock);
808     return -1;
809     }
810 conf->ips = i;
811
812 mysql_free_result(res);
813 mysql_close(sock);
814
815 return 0;
816 }
817 //-----------------------------------------------------------------------------
818 int MYSQL_STORE::RestoreUserStat(USER_STAT * stat, const string & login) const
819 {
820 MYSQL_RES *res;
821 MYSQL_ROW row;
822 MYSQL * sock;
823
824 string query;
825
826 query = "SELECT ";
827
828 for (int i = 0; i < DIR_NUM; i++)
829 {
830     sprintf(qbuf, "D%d, U%d, ", i, i);
831     query += qbuf;
832 }
833
834 query += "Cash, FreeMb, LastCashAdd, LastCashAddTime, PassiveTime, LastActivityTime \
835           FROM users WHERE login = '";
836 query += login + "'";
837
838 //sprintf(qbuf,"SELECT * FROM users WHERE login='%s' LIMIT 1", login.c_str());
839     
840 if(MysqlGetQuery(query.c_str() ,sock))
841 {
842     errorStr = "Couldn't restore UserStat(on query):\n";
843     errorStr += mysql_error(sock);
844     mysql_close(sock);
845     return -1;
846 }
847
848 if (!(res=mysql_store_result(sock)))
849 {
850     errorStr = "Couldn't restore UserStat(on getting result):\n";
851     errorStr += mysql_error(sock);
852     mysql_close(sock);
853     return -1;
854 }
855
856 row = mysql_fetch_row(res);
857
858 unsigned int startPos=0;
859
860 char s[22];
861 uint64_t traffU[DIR_NUM];
862 uint64_t traffD[DIR_NUM];
863
864 for (int i = 0; i < DIR_NUM; i++)
865     {
866     sprintf(s, "D%d", i);
867     if (GetULongLongInt(row[startPos+i*2],&traffD[i], 0) != 0)
868         {
869         mysql_free_result(res);
870         errorStr = "User \'" + login + "\' stat not read. Parameter " + string(s);
871         mysql_close(sock);
872         return -1;
873         }
874     stat->down = traffD;
875
876     sprintf(s, "U%d", i);
877     if (GetULongLongInt(row[startPos+i*2+1], &traffU[i], 0) != 0)
878         {
879         mysql_free_result(res);
880         errorStr =   "User \'" + login + "\' stat not read. Parameter " + string(s);
881         mysql_close(sock);
882         return -1;
883         }
884     stat->up = traffU;
885     }//for
886
887 startPos += (2*DIR_NUM);
888
889 if (GetDouble(row[startPos], &stat->cash, 0) != 0)
890     {
891     mysql_free_result(res);
892     errorStr =   "User \'" + login + "\' stat not read. Parameter Cash";
893     mysql_close(sock);
894     return -1;
895     }
896
897 if (GetDouble(row[startPos+1],&stat->freeMb, 0) != 0)
898     {
899     mysql_free_result(res);
900     errorStr =   "User \'" + login + "\' stat not read. Parameter FreeMb";
901     mysql_close(sock);
902     return -1;
903     }
904
905 if (GetDouble(row[startPos+2], &stat->lastCashAdd, 0) != 0)
906     {
907     mysql_free_result(res);
908     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAdd";
909     mysql_close(sock);
910     return -1;
911     }
912
913 if (GetTime(row[startPos+3], &stat->lastCashAddTime, 0) != 0)
914     {
915     mysql_free_result(res);
916     errorStr =   "User \'" + login + "\' stat not read. Parameter LastCashAddTime";
917     mysql_close(sock);
918     return -1;
919     }
920
921 if (GetTime(row[startPos+4], &stat->passiveTime, 0) != 0)
922     {
923     mysql_free_result(res);
924     errorStr =   "User \'" + login + "\' stat not read. Parameter PassiveTime";
925     mysql_close(sock);
926     return -1;
927     }
928
929 if (GetTime(row[startPos+5], &stat->lastActivityTime, 0) != 0)
930     {
931     mysql_free_result(res);
932     errorStr =   "User \'" + login + "\' stat not read. Parameter LastActivityTime";
933     mysql_close(sock);
934     return -1;
935     }
936
937 mysql_free_result(res);
938 mysql_close(sock);
939 return 0;
940 }
941 //-----------------------------------------------------------------------------
942 int MYSQL_STORE::SaveUserConf(const USER_CONF & conf, const string & login) const
943 {
944 string param;
945 string res;
946
947 strprintf(&res,"UPDATE users SET Password='%s', Passive=%d, Down=%d, DisabledDetailStat = %d, "\
948     "AlwaysOnline=%d, Tariff='%s', Address='%s', Phone='%s', Email='%s', "\
949     "Note='%s', RealName='%s', StgGroup='%s', Credit=%f, TariffChange='%s', ", 
950     conf.password.c_str(),
951     conf.passive,
952     conf.disabled,
953     conf.disabledDetailStat,
954     conf.alwaysOnline,
955     conf.tariffName.c_str(),
956     (ReplaceStr(conf.address,badSyms,repSym)).c_str(),
957     (ReplaceStr(conf.phone,badSyms,repSym)).c_str(),
958     (ReplaceStr(conf.email,badSyms,repSym)).c_str(),
959     (ReplaceStr(conf.note,badSyms,repSym)).c_str(),
960     (ReplaceStr(conf.realName,badSyms,repSym)).c_str(),
961     (ReplaceStr(conf.group,badSyms,repSym)).c_str(),
962     conf.credit,
963     conf.nextTariff.c_str()
964     );
965
966 for (int i = 0; i < USERDATA_NUM; i++)
967     {
968     strprintf(&param, " Userdata%d='%s',", i, 
969         (ReplaceStr(conf.userdata[i],badSyms,repSym)).c_str());
970     res += param;
971     }
972     
973 strprintf(&param, " CreditExpire=%d,", conf.creditExpire);
974 res += param;
975
976 stringstream ipStr;
977 ipStr << conf.ips;
978
979 strprintf(&param, " IP='%s'", ipStr.str().c_str());
980 res += param;
981
982 strprintf(&param, " WHERE login='%s' LIMIT 1", login.c_str());
983 res += param;
984
985 if(MysqlSetQuery(res.c_str()))
986 {
987     errorStr = "Couldn't save user conf:\n";
988     //errorStr += mysql_error(sock);
989     return -1;
990 }
991
992 return 0;
993 }
994 //-----------------------------------------------------------------------------
995 int MYSQL_STORE::SaveUserStat(const USER_STAT & stat, const string & login) const
996 {
997 string param;
998 string res;
999
1000 res = "UPDATE users SET";
1001
1002 for (int i = 0; i < DIR_NUM; i++)
1003     {
1004     strprintf(&param, " D%d=%lld,", i, stat.down[i]);
1005     res += param;
1006
1007     strprintf(&param, " U%d=%lld,", i, stat.up[i]);
1008     res += param;
1009     }
1010
1011 strprintf(&param, " Cash=%f, FreeMb=%f, LastCashAdd=%f, LastCashAddTime=%d,"\
1012     " PassiveTime=%d, LastActivityTime=%d", 
1013     stat.cash,
1014     stat.freeMb,
1015     stat.lastCashAdd,
1016     stat.lastCashAddTime,
1017     stat.passiveTime,
1018     stat.lastActivityTime
1019     );
1020 res += param;
1021
1022 strprintf(&param, " WHERE login='%s' LIMIT 1", login.c_str());
1023 res += param;
1024
1025 if(MysqlSetQuery(res.c_str()))
1026 {
1027     errorStr = "Couldn't save user stat:\n";
1028 //    errorStr += mysql_error(sock);
1029     return -1;
1030 }
1031
1032 return 0;
1033 }
1034 //-----------------------------------------------------------------------------
1035 int MYSQL_STORE::WriteLogString(const string & str, const string & login) const
1036 {
1037 string res, tempStr;
1038 time_t t;
1039 tm * lt;
1040
1041 t = time(NULL);
1042 lt = localtime(&t);
1043
1044 MYSQL_RES* result;
1045 MYSQL * sock;
1046 strprintf(&tempStr, "logs_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1047 if (!(sock=MysqlConnect())){
1048     errorStr = "Couldn't connect to Server";
1049     return -1;
1050 }
1051 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1052 {
1053     errorStr = "Couldn't get table " + tempStr + ":\n";
1054     errorStr += mysql_error(sock);
1055     mysql_close(sock);
1056     return -1;
1057 }
1058
1059 unsigned int num_rows =  mysql_num_rows(result);
1060
1061 mysql_free_result(result);
1062
1063 if (num_rows < 1)
1064 {
1065     sprintf(qbuf,"CREATE TABLE logs_%02d_%4d (unid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(40),text TEXT)",
1066     lt->tm_mon+1, lt->tm_year+1900);
1067     
1068     if(MysqlQuery(qbuf,sock))
1069     {
1070         errorStr = "Couldn't create WriteDetailedStat table:\n";
1071         errorStr += mysql_error(sock);
1072         mysql_close(sock);
1073         return -1;
1074     }
1075 }
1076
1077 strprintf(&res, "%s -- %s",LogDate(t), str.c_str());
1078
1079 string send;
1080
1081 strprintf(&send,"INSERT INTO logs_%02d_%4d SET login='%s', text='%s'",
1082         lt->tm_mon+1, lt->tm_year+1900,
1083     login.c_str(), (ReplaceStr(res,badSyms,repSym)).c_str());
1084
1085 if(MysqlQuery(send.c_str(),sock))
1086 {
1087     errorStr = "Couldn't write log string:\n";
1088     errorStr += mysql_error(sock);
1089     mysql_close(sock);
1090     return -1;
1091 }
1092 mysql_close(sock);
1093 return 0;
1094
1095 }
1096 //-----------------------------------------------------------------------------
1097 int MYSQL_STORE::WriteUserChgLog(const string & login,
1098                                  const string & admLogin,
1099                                  uint32_t       admIP,
1100                                  const string & paramName,
1101                                  const string & oldValue,
1102                                  const string & newValue,
1103                                  const string & message) const
1104 {
1105 string userLogMsg = "Admin \'" + admLogin + "\', " + string(inet_ntostr(admIP)) + ": \'"
1106     + paramName + "\' parameter changed from \'" + oldValue +
1107     "\' to \'" + newValue + "\'. " + message;
1108
1109 return WriteLogString(userLogMsg, login);
1110 }
1111 //-----------------------------------------------------------------------------
1112 int MYSQL_STORE::WriteUserConnect(const string & login, uint32_t ip) const
1113 {
1114 string logStr = "Connect, " + string(inet_ntostr(ip));
1115 return WriteLogString(logStr, login);
1116 }
1117 //-----------------------------------------------------------------------------
1118 int MYSQL_STORE::WriteUserDisconnect(const string & login,
1119                                      const DIR_TRAFF & up,
1120                                      const DIR_TRAFF & down,
1121                                      const DIR_TRAFF & sessionUp,
1122                                      const DIR_TRAFF & sessionDown,
1123                                      double cash,
1124                                      double freeMb) const
1125 {
1126 string logStr = "Disconnect, ";
1127 stringstream sssu;
1128 stringstream sssd;
1129 stringstream ssmu;
1130 stringstream ssmd;
1131 stringstream sscash;
1132
1133 ssmu << up;
1134 ssmd << down;
1135
1136 sssu << sessionUp;
1137 sssd << sessionDown;
1138
1139 sscash << cash;
1140
1141 logStr += " session upload: \'";
1142 logStr += sssu.str();
1143 logStr += "\' session download: \'";
1144 logStr += sssd.str();
1145 logStr += "\' month upload: \'";
1146 logStr += ssmu.str();
1147 logStr += "\' month download: \'";
1148 logStr += ssmd.str();
1149 logStr += "\' cash: \'";
1150 logStr += sscash.str();
1151 logStr += "\'";
1152
1153 return WriteLogString(logStr, login);
1154 }
1155 //-----------------------------------------------------------------------------
1156 int MYSQL_STORE::SaveMonthStat(const USER_STAT & stat, int month, int year, 
1157                                 const string & login) const
1158 {
1159 string param, res;
1160
1161 strprintf(&res, "INSERT INTO stat SET login='%s', month=%d, year=%d,", 
1162     login.c_str(), month+1, year+1900);
1163     
1164 for (int i = 0; i < DIR_NUM; i++)
1165     {
1166     strprintf(&param, " U%d=%lld,", i, stat.up[i]); 
1167     res += param;
1168
1169     strprintf(&param, " D%d=%lld,", i, stat.down[i]);        
1170     res += param;
1171     }
1172     
1173 strprintf(&param, " cash=%f", stat.cash);        
1174 res += param;
1175
1176 if(MysqlSetQuery(res.c_str()))
1177 {
1178     errorStr = "Couldn't SaveMonthStat:\n";
1179     //errorStr += mysql_error(sock);
1180     return -1;
1181 }
1182
1183 return 0;
1184 }
1185 //-----------------------------------------------------------------------------*/
1186 int MYSQL_STORE::AddAdmin(const string & login) const
1187 {
1188 sprintf(qbuf,"INSERT INTO admins SET login='%s'", login.c_str());
1189     
1190 if(MysqlSetQuery(qbuf))
1191 {
1192     errorStr = "Couldn't add admin:\n";
1193     //errorStr += mysql_error(sock);
1194     return -1;
1195 }
1196
1197 return 0;
1198 }
1199 //-----------------------------------------------------------------------------*/
1200 int MYSQL_STORE::DelAdmin(const string & login) const
1201 {
1202 sprintf(qbuf,"DELETE FROM admins where login='%s' LIMIT 1", login.c_str());
1203     
1204 if(MysqlSetQuery(qbuf))
1205 {
1206     errorStr = "Couldn't delete admin:\n";
1207     //errorStr += mysql_error(sock);
1208     return -1;
1209 }
1210
1211 return 0;
1212 }
1213 //-----------------------------------------------------------------------------*/
1214 int MYSQL_STORE::SaveAdmin(const ADMIN_CONF & ac) const
1215 {
1216 char passwordE[2 * ADM_PASSWD_LEN + 2];
1217 char pass[ADM_PASSWD_LEN + 1];
1218 char adminPass[ADM_PASSWD_LEN + 1];
1219
1220 memset(pass, 0, sizeof(pass));
1221 memset(adminPass, 0, sizeof(adminPass));
1222
1223 BLOWFISH_CTX ctx;
1224 EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1225
1226 strncpy(adminPass, ac.password.c_str(), ADM_PASSWD_LEN);
1227 adminPass[ADM_PASSWD_LEN - 1] = 0;
1228
1229 for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1230     {
1231     EncodeString(pass + 8*i, adminPass + 8*i, &ctx);
1232     }
1233
1234 pass[ADM_PASSWD_LEN - 1] = 0;
1235 Encode12(passwordE, pass, ADM_PASSWD_LEN);
1236
1237 sprintf(qbuf,"UPDATE admins SET password='%s', ChgConf=%d, ChgPassword=%d, "\
1238     "ChgStat=%d, ChgCash=%d, UsrAddDel=%d, ChgTariff=%d, ChgAdmin=%d "\
1239     "WHERE login='%s' LIMIT 1", 
1240     passwordE,
1241     ac.priv.userConf,
1242     ac.priv.userPasswd,
1243     ac.priv.userStat,
1244     ac.priv.userCash,
1245     ac.priv.userAddDel,
1246     ac.priv.tariffChg,
1247     ac.priv.adminChg,
1248     ac.login.c_str()
1249     );
1250
1251 if(MysqlSetQuery(qbuf))
1252 {
1253     errorStr = "Couldn't save admin:\n";
1254     //errorStr += mysql_error(sock);
1255     return -1;
1256 }
1257
1258 return 0;
1259 }
1260 //-----------------------------------------------------------------------------
1261 int MYSQL_STORE::RestoreAdmin(ADMIN_CONF * ac, const string & login) const
1262 {
1263 char pass[ADM_PASSWD_LEN + 1];
1264 char password[ADM_PASSWD_LEN + 1];
1265 char passwordE[2*ADM_PASSWD_LEN + 2];
1266 BLOWFISH_CTX ctx;
1267
1268 string p;
1269 MYSQL_RES *res;
1270 MYSQL_ROW row;
1271 MYSQL * sock;
1272 sprintf(qbuf,"SELECT * FROM admins WHERE login='%s' LIMIT 1", login.c_str());
1273     
1274 if(MysqlGetQuery(qbuf,sock))
1275 {
1276     errorStr = "Couldn't restore admin:\n";
1277     errorStr += mysql_error(sock);
1278     mysql_close(sock);
1279     return -1;
1280 }
1281
1282 if (!(res=mysql_store_result(sock)))
1283 {
1284     errorStr = "Couldn't restore admin:\n";
1285     errorStr += mysql_error(sock);
1286     mysql_close(sock);
1287     return -1;
1288 }
1289
1290 if ( mysql_num_rows(res) == 0)
1291 {
1292     mysql_free_result(res);
1293     errorStr = "Couldn't restore admin as couldn't found him in table.\n";
1294     mysql_close(sock);
1295     return -1;
1296 }
1297   
1298 row = mysql_fetch_row(res);
1299
1300 p = row[1];
1301 int a;
1302
1303 if(p.length() == 0)
1304 {
1305     mysql_free_result(res);
1306     errorStr = "Error in parameter password";
1307     mysql_close(sock);
1308     return -1;
1309 }
1310
1311 memset(passwordE, 0, sizeof(passwordE));
1312 strncpy(passwordE, p.c_str(), 2*ADM_PASSWD_LEN);
1313
1314 memset(pass, 0, sizeof(pass));
1315
1316 if (passwordE[0] != 0)
1317     {
1318     Decode21(pass, passwordE);
1319     EnDecodeInit(adm_enc_passwd, strlen(adm_enc_passwd), &ctx);
1320
1321     for (int i = 0; i < ADM_PASSWD_LEN/8; i++)
1322         {
1323         DecodeString(password + 8*i, pass + 8*i, &ctx);
1324         }
1325     }
1326 else
1327     {
1328     password[0] = 0;
1329     }
1330
1331 ac->password = password;
1332
1333 if (GetInt(row[2], &a, 0) == 0) 
1334     ac->priv.userConf = a;
1335 else
1336     {
1337     mysql_free_result(res);
1338     errorStr = "Error in parameter ChgConf";
1339     mysql_close(sock);
1340     return -1;
1341     }
1342
1343 if (GetInt(row[3], &a, 0) == 0) 
1344     ac->priv.userPasswd = a;
1345 else
1346     {
1347     mysql_free_result(res);
1348     errorStr = "Error in parameter ChgPassword";
1349     mysql_close(sock);
1350     return -1;
1351     }
1352
1353 if (GetInt(row[4], &a, 0) == 0) 
1354     ac->priv.userStat = a;
1355 else
1356     {
1357     mysql_free_result(res);
1358     errorStr = "Error in parameter ChgStat";
1359     mysql_close(sock);
1360     return -1;
1361     }
1362
1363 if (GetInt(row[5], &a, 0) == 0) 
1364     ac->priv.userCash = a;
1365 else
1366     {
1367     mysql_free_result(res);
1368     errorStr = "Error in parameter ChgCash";
1369     mysql_close(sock);
1370     return -1;
1371     }
1372
1373 if (GetInt(row[6], &a, 0) == 0) 
1374     ac->priv.userAddDel = a;
1375 else
1376     {
1377     mysql_free_result(res);
1378     errorStr = "Error in parameter UsrAddDel";
1379     mysql_close(sock);
1380     return -1;
1381     }
1382
1383 if (GetInt(row[7], &a, 0) == 0) 
1384     ac->priv.tariffChg = a;
1385 else
1386     {
1387     mysql_free_result(res);
1388     errorStr = "Error in parameter ChgTariff";
1389     mysql_close(sock);
1390     return -1;
1391     }
1392
1393 if (GetInt(row[8], &a, 0) == 0) 
1394     ac->priv.adminChg = a;
1395 else
1396     {
1397     mysql_free_result(res);
1398     errorStr = "Error in parameter ChgAdmin";
1399     mysql_close(sock);
1400     return -1;
1401     }
1402
1403 mysql_free_result(res);
1404 mysql_close(sock);
1405 return 0;
1406 }
1407 //-----------------------------------------------------------------------------
1408 int MYSQL_STORE::AddTariff(const string & name) const
1409 {
1410 sprintf(qbuf,"INSERT INTO tariffs SET name='%s'", name.c_str());
1411     
1412 if(MysqlSetQuery(qbuf))
1413 {
1414     errorStr = "Couldn't add tariff:\n";
1415 //    errorStr += mysql_error(sock);
1416     return -1;
1417 }
1418
1419 return 0;
1420 }
1421 //-----------------------------------------------------------------------------
1422 int MYSQL_STORE::DelTariff(const string & name) const
1423 {
1424 sprintf(qbuf,"DELETE FROM tariffs WHERE name='%s' LIMIT 1", name.c_str());
1425     
1426 if(MysqlSetQuery(qbuf))
1427 {
1428     errorStr = "Couldn't delete tariff: ";
1429 //    errorStr += mysql_error(sock);
1430     return -1;
1431 }
1432
1433 return 0;
1434 }
1435 //-----------------------------------------------------------------------------
1436 int MYSQL_STORE::RestoreTariff(TARIFF_DATA * td, const string & tariffName) const
1437 {
1438 MYSQL_RES *res;
1439 MYSQL_ROW row;
1440 MYSQL * sock;
1441 sprintf(qbuf,"SELECT * FROM tariffs WHERE name='%s' LIMIT 1", tariffName.c_str());
1442     
1443 if(MysqlGetQuery(qbuf,sock))
1444 {
1445     errorStr = "Couldn't restore Tariff:\n";
1446     errorStr += mysql_error(sock);
1447     mysql_close(sock);
1448     return -1;
1449 }
1450
1451 if (!(res=mysql_store_result(sock)))
1452 {
1453     errorStr = "Couldn't restore Tariff:\n";
1454     errorStr += mysql_error(sock);
1455     mysql_close(sock);
1456     return -1;
1457 }
1458
1459 string str;
1460 td->tariffConf.name = tariffName;
1461
1462 row = mysql_fetch_row(res);
1463
1464 string param;
1465 for (int i = 0; i<DIR_NUM; i++)
1466     {
1467     strprintf(&param, "Time%d", i);
1468     str = row[6+i*8];
1469     if (str.length() == 0)
1470         {
1471         mysql_free_result(res);
1472         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1473         mysql_close(sock);
1474         return -1;
1475         }
1476
1477     ParseTariffTimeStr(str.c_str(), 
1478                        td->dirPrice[i].hDay, 
1479                        td->dirPrice[i].mDay, 
1480                        td->dirPrice[i].hNight, 
1481                        td->dirPrice[i].mNight);
1482
1483     strprintf(&param, "PriceDayA%d", i);
1484     if (GetDouble(row[1+i*8], &td->dirPrice[i].priceDayA, 0.0) < 0)
1485         {
1486         mysql_free_result(res);
1487         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1488         mysql_close(sock);
1489         return -1;
1490         }
1491     td->dirPrice[i].priceDayA /= (1024*1024);
1492
1493     strprintf(&param, "PriceDayB%d", i);
1494     if (GetDouble(row[2+i*8], &td->dirPrice[i].priceDayB, 0.0) < 0)
1495         {
1496         mysql_free_result(res);
1497         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1498         mysql_close(sock);
1499         return -1;
1500         }
1501     td->dirPrice[i].priceDayB /= (1024*1024);
1502
1503     strprintf(&param, "PriceNightA%d", i);
1504     if (GetDouble(row[3+i*8], &td->dirPrice[i].priceNightA, 0.0) < 0)
1505         {
1506         mysql_free_result(res);
1507         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1508         mysql_close(sock);
1509         return -1;
1510         }
1511     td->dirPrice[i].priceNightA /= (1024*1024);
1512
1513     strprintf(&param, "PriceNightB%d", i);
1514     if (GetDouble(row[4+i*8], &td->dirPrice[i].priceNightB, 0.0) < 0)
1515         {
1516         mysql_free_result(res);
1517         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1518         mysql_close(sock);
1519         return -1;
1520         }
1521     td->dirPrice[i].priceNightB /= (1024*1024);
1522
1523     strprintf(&param, "Threshold%d", i);
1524     if (GetInt(row[5+i*8], &td->dirPrice[i].threshold, 0) < 0)
1525         {
1526         mysql_free_result(res);
1527         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1528         mysql_close(sock);
1529         return -1;
1530         }
1531
1532     strprintf(&param, "SinglePrice%d", i);
1533     if (GetInt(row[8+i*8], &td->dirPrice[i].singlePrice, 0) < 0)
1534         {
1535         mysql_free_result(res);
1536         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1537         mysql_close(sock);
1538         return -1;
1539         }
1540
1541     strprintf(&param, "NoDiscount%d", i);
1542     if (GetInt(row[7+i*8], &td->dirPrice[i].noDiscount, 0) < 0)
1543         {
1544         mysql_free_result(res);
1545         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1546         mysql_close(sock);
1547         return -1;
1548         }
1549     }//main for
1550
1551 if (GetDouble(row[2+8*DIR_NUM], &td->tariffConf.fee, 0.0) < 0)
1552     {
1553     mysql_free_result(res);
1554     errorStr = "Cannot read tariff " + tariffName + ". Parameter Fee";
1555     mysql_close(sock);
1556     return -1;
1557     }
1558
1559 if (GetDouble(row[3+8*DIR_NUM], &td->tariffConf.free, 0.0) < 0)
1560     {
1561     mysql_free_result(res);
1562     errorStr = "Cannot read tariff " + tariffName + ". Parameter Free";
1563     mysql_close(sock);
1564     return -1;
1565     }
1566
1567 if (GetDouble(row[1+8*DIR_NUM], &td->tariffConf.passiveCost, 0.0) < 0)
1568     {
1569     mysql_free_result(res);
1570     errorStr = "Cannot read tariff " + tariffName + ". Parameter PassiveCost";
1571     mysql_close(sock);
1572     return -1;
1573     }
1574
1575     str = row[4+8*DIR_NUM];
1576     param = "TraffType";
1577     
1578     if (str.length() == 0)
1579         {
1580         mysql_free_result(res);
1581         errorStr = "Cannot read tariff " + tariffName + ". Parameter " + param;
1582         mysql_close(sock);
1583         return -1;
1584         }
1585
1586 if (!strcasecmp(str.c_str(), "up"))
1587     td->tariffConf.traffType = TRAFF_UP;
1588 else
1589     if (!strcasecmp(str.c_str(), "down"))
1590         td->tariffConf.traffType = TRAFF_DOWN;
1591     else
1592         if (!strcasecmp(str.c_str(), "up+down"))
1593             td->tariffConf.traffType = TRAFF_UP_DOWN;
1594         else
1595             if (!strcasecmp(str.c_str(), "max"))
1596                 td->tariffConf.traffType = TRAFF_MAX;
1597             else
1598                 {
1599                 mysql_free_result(res);
1600                 errorStr = "Cannot read tariff " + tariffName + ". Parameter TraffType incorrect";
1601                 mysql_close(sock);
1602                 return -1;
1603                 }
1604
1605 mysql_free_result(res);
1606 mysql_close(sock);
1607 return 0;
1608 }
1609 //-----------------------------------------------------------------------------
1610 int MYSQL_STORE::SaveTariff(const TARIFF_DATA & td, const string & tariffName) const
1611 {
1612 string param;
1613
1614 string res="UPDATE tariffs SET";
1615
1616 for (int i = 0; i < DIR_NUM; i++)
1617     {
1618     strprintf(&param, " PriceDayA%d=%f,", i, 
1619         td.dirPrice[i].priceDayA * pt_mega);
1620     res += param;
1621
1622     strprintf(&param, " PriceDayB%d=%f,", i, 
1623         td.dirPrice[i].priceDayB * pt_mega);        
1624     res += param;
1625         
1626     strprintf(&param, " PriceNightA%d=%f,", i,
1627         td.dirPrice[i].priceNightA * pt_mega);
1628     res += param;
1629
1630     strprintf(&param, " PriceNightB%d=%f,", i, 
1631         td.dirPrice[i].priceNightB * pt_mega);
1632     res += param;
1633         
1634     strprintf(&param, " Threshold%d=%d,", i, 
1635         td.dirPrice[i].threshold);
1636     res += param;
1637
1638     string s;
1639     strprintf(&param, " Time%d", i);
1640
1641     strprintf(&s, "%0d:%0d-%0d:%0d", 
1642             td.dirPrice[i].hDay,
1643             td.dirPrice[i].mDay,
1644             td.dirPrice[i].hNight,
1645             td.dirPrice[i].mNight);
1646
1647     res += (param + "='" + s + "',");
1648
1649     strprintf(&param, " NoDiscount%d=%d,", i, 
1650         td.dirPrice[i].noDiscount);
1651     res += param;
1652
1653     strprintf(&param, " SinglePrice%d=%d,", i, 
1654         td.dirPrice[i].singlePrice);
1655     res += param;
1656     }
1657
1658 strprintf(&param, " PassiveCost=%f,", td.tariffConf.passiveCost);
1659 res += param;
1660
1661 strprintf(&param, " Fee=%f,", td.tariffConf.fee);
1662 res += param;
1663
1664 strprintf(&param, " Free=%f,", td.tariffConf.free);
1665 res += param;
1666
1667 switch (td.tariffConf.traffType)
1668     {
1669     case TRAFF_UP:
1670         res += " TraffType='up'";
1671         break;
1672     case TRAFF_DOWN:
1673         res += " TraffType='down'";
1674         break;
1675     case TRAFF_UP_DOWN:
1676         res += " TraffType='up+down'";
1677         break;
1678     case TRAFF_MAX:
1679         res += " TraffType='max'";
1680         break;
1681     }
1682 strprintf(&param, " WHERE name='%s' LIMIT 1", tariffName.c_str());
1683 res += param;
1684
1685 if(MysqlSetQuery(res.c_str()))
1686 {
1687     errorStr = "Couldn't save admin:\n";
1688     //errorStr += mysql_error(sock);
1689     return -1;
1690 }
1691
1692 return 0;
1693 }
1694 //-----------------------------------------------------------------------------
1695 int MYSQL_STORE::WriteDetailedStat(const map<IP_DIR_PAIR, STAT_NODE> * statTree, 
1696                                    time_t lastStat, 
1697                                    const string & login) const
1698 {
1699 string res, stTime, endTime, tempStr;
1700 time_t t;
1701 tm * lt;
1702
1703 t = time(NULL);
1704 lt = localtime(&t);
1705
1706 if (lt->tm_hour == 0 && lt->tm_min <= 5)
1707     {
1708         t -= 3600 * 24;
1709         lt = localtime(&t);
1710     }
1711
1712 MYSQL_RES* result;
1713 MYSQL * sock;
1714 strprintf(&tempStr, "detailstat_%02d_%4d", lt->tm_mon+1, lt->tm_year+1900);
1715
1716 if (!(sock=MysqlConnect())){
1717     mysql_close(sock);
1718     return -1;
1719 }
1720
1721 if (!(result=mysql_list_tables(sock,tempStr.c_str() )))
1722 {
1723     errorStr = "Couldn't get table " + tempStr + ":\n";
1724     errorStr += mysql_error(sock);
1725     mysql_close(sock);
1726     return -1;
1727 }
1728
1729 unsigned int num_rows =  mysql_num_rows(result);
1730
1731 mysql_free_result(result);
1732
1733 if (num_rows < 1)
1734 {
1735     sprintf(qbuf,"CREATE TABLE detailstat_%02d_%4d (login VARCHAR(40) DEFAULT '',"\
1736         "day TINYINT DEFAULT 0,startTime TIME,endTime TIME,"\
1737         "IP VARCHAR(17) DEFAULT '',dir INT DEFAULT 0,"\
1738         "down BIGINT DEFAULT 0,up BIGINT DEFAULT 0, cash DOUBLE DEFAULT 0.0, INDEX (login), INDEX(dir), INDEX(day), INDEX(IP))",
1739     lt->tm_mon+1, lt->tm_year+1900);
1740     
1741     if(MysqlQuery(qbuf,sock))
1742     {
1743         errorStr = "Couldn't create WriteDetailedStat table:\n";
1744         errorStr += mysql_error(sock);
1745         mysql_close(sock);
1746         return -1;
1747     }
1748 }
1749
1750 struct tm * lt1;
1751 struct tm * lt2;
1752
1753 lt1 = localtime(&lastStat);
1754
1755 int h1, m1, s1;
1756 int h2, m2, s2;
1757
1758 h1 = lt1->tm_hour;
1759 m1 = lt1->tm_min;
1760 s1 = lt1->tm_sec;
1761
1762 lt2 = localtime(&t);
1763
1764 h2 = lt2->tm_hour;
1765 m2 = lt2->tm_min;
1766 s2 = lt2->tm_sec;
1767     
1768 strprintf(&stTime, "%02d:%02d:%02d", h1, m1, s1);
1769 strprintf(&endTime, "%02d:%02d:%02d", h2, m2, s2);
1770
1771 strprintf(&res,"INSERT INTO detailstat_%02d_%4d SET login='%s',"\
1772     "day=%d,startTime='%s',endTime='%s',", 
1773     lt->tm_mon+1, lt->tm_year+1900,
1774     login.c_str(),
1775     lt->tm_mday,
1776     stTime.c_str(),
1777     endTime.c_str()
1778     );
1779
1780 int retRes;
1781 map<IP_DIR_PAIR, STAT_NODE>::const_iterator stIter;
1782 stIter = statTree->begin();
1783
1784 while (stIter != statTree->end())
1785     {
1786         strprintf(&tempStr,"IP='%s', dir=%d, down=%lld, up=%lld, cash=%f", 
1787                 inet_ntostr(stIter->first.ip),
1788                 stIter->first.dir, 
1789                 stIter->second.down, 
1790                 stIter->second.up, 
1791                 stIter->second.cash
1792             );
1793     
1794         if( (retRes = MysqlQuery((res+tempStr).c_str(),sock)) )
1795         {
1796             errorStr = "Couldn't insert data in WriteDetailedStat:\n";
1797             errorStr += mysql_error(sock);
1798             mysql_close(sock);
1799             return -1;
1800         }
1801
1802         result=mysql_store_result(sock);
1803         if(result)
1804             mysql_free_result(result);
1805
1806         ++stIter;
1807     }
1808 mysql_close(sock);
1809 return 0;
1810 }
1811 //-----------------------------------------------------------------------------
1812 int MYSQL_STORE::AddMessage(STG_MSG * msg, const string & login) const
1813 {
1814 struct timeval tv;
1815
1816 gettimeofday(&tv, NULL);
1817
1818 msg->header.id = ((long long)tv.tv_sec) * 1000000 + ((long long)tv.tv_usec);
1819
1820 sprintf(qbuf,"INSERT INTO messages SET login='%s', id=%lld", 
1821     login.c_str(),
1822     (long long)msg->header.id
1823     );
1824     
1825 if(MysqlSetQuery(qbuf))
1826 {
1827     errorStr = "Couldn't add message:\n";
1828     //errorStr += mysql_error(sock);
1829     return -1;
1830 }
1831
1832 return EditMessage(*msg, login);
1833 }
1834 //-----------------------------------------------------------------------------
1835 int MYSQL_STORE::EditMessage(const STG_MSG & msg, const string & login) const
1836 {
1837 string res;
1838
1839 strprintf(&res,"UPDATE messages SET type=%d, lastSendTime=%u, creationTime=%u, "\
1840     "showTime=%u, stgRepeat=%d, repeatPeriod=%u, text='%s' "\
1841     "WHERE login='%s' AND id=%lld LIMIT 1", 
1842     msg.header.type,
1843     msg.header.lastSendTime,
1844     msg.header.creationTime,
1845     msg.header.showTime,
1846     msg.header.repeat,
1847     msg.header.repeatPeriod,
1848     (ReplaceStr(msg.text,badSyms,repSym)).c_str(),
1849     login.c_str(),
1850     (long long)msg.header.id
1851     );
1852
1853 if(MysqlSetQuery(res.c_str()))
1854 {
1855     errorStr = "Couldn't edit message:\n";
1856     //errorStr += mysql_error(sock);
1857     return -1;
1858 }
1859
1860 return 0;
1861 }
1862 //-----------------------------------------------------------------------------
1863 int MYSQL_STORE::GetMessage(uint64_t id, STG_MSG * msg, const string & login) const
1864 {
1865 MYSQL_RES *res;
1866 MYSQL_ROW row;
1867 MYSQL * sock;
1868
1869 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s' AND id=%lld LIMIT 1",
1870     login.c_str(), id);
1871     
1872 if(MysqlGetQuery(qbuf,sock))
1873 {
1874     errorStr = "Couldn't GetMessage:\n";
1875     errorStr += mysql_error(sock);
1876     mysql_close(sock);
1877     return -1;
1878 }
1879
1880 if (!(res=mysql_store_result(sock)))
1881 {
1882     errorStr = "Couldn't GetMessage:\n";
1883     errorStr += mysql_error(sock);
1884     mysql_close(sock);
1885     return -1;
1886 }
1887
1888 row = mysql_fetch_row(res);
1889
1890 if(row[2]&&str2x(row[2], msg->header.type))
1891 {
1892     mysql_free_result(res);
1893     errorStr = "Invalid value in message header for user: " + login;
1894     mysql_close(sock);
1895     return -1;
1896 }
1897
1898 if(row[3] && str2x(row[3], msg->header.lastSendTime))
1899 {
1900     mysql_free_result(res);
1901     errorStr = "Invalid value in message header for user: " + login;
1902     mysql_close(sock);
1903     return -1;
1904 }
1905
1906 if(row[4] && str2x(row[4], msg->header.creationTime))
1907 {
1908     mysql_free_result(res);
1909     errorStr = "Invalid value in message header for user: " + login;
1910     mysql_close(sock);
1911     return -1;
1912 }
1913
1914 if(row[5] && str2x(row[5], msg->header.showTime))
1915 {
1916     mysql_free_result(res);
1917     errorStr = "Invalid value in message header for user: " + login;
1918     mysql_close(sock);
1919     return -1;
1920 }
1921
1922 if(row[6] && str2x(row[6], msg->header.repeat))
1923 {
1924     mysql_free_result(res);
1925     errorStr = "Invalid value in message header for user: " + login;
1926     mysql_close(sock);
1927     return -1;
1928 }
1929
1930 if(row[7] && str2x(row[7], msg->header.repeatPeriod))
1931 {
1932     mysql_free_result(res);
1933     errorStr = "Invalid value in message header for user: " + login;
1934     mysql_close(sock);
1935     return -1;
1936 }
1937
1938 msg->header.id = id;
1939 msg->text = row[8];
1940
1941 mysql_free_result(res);
1942 mysql_close(sock);
1943 return 0;
1944 }
1945 //-----------------------------------------------------------------------------
1946 int MYSQL_STORE::DelMessage(uint64_t id, const string & login) const
1947 {
1948 sprintf(qbuf,"DELETE FROM messages WHERE login='%s' AND id=%lld LIMIT 1", 
1949     login.c_str(),(long long)id);
1950     
1951 if(MysqlSetQuery(qbuf))
1952 {
1953     errorStr = "Couldn't delete Message:\n";
1954     //errorStr += mysql_error(sock);
1955     return -1;
1956 }
1957
1958 return 0;
1959 }
1960 //-----------------------------------------------------------------------------
1961 int MYSQL_STORE::GetMessageHdrs(vector<STG_MSG_HDR> * hdrsList, const string & login) const
1962 {
1963 MYSQL_RES *res;
1964 MYSQL_ROW row;
1965 MYSQL * sock;
1966 sprintf(qbuf,"SELECT * FROM messages WHERE login='%s'", login.c_str());
1967     
1968 if(MysqlGetQuery(qbuf,sock))
1969 {
1970     errorStr = "Couldn't GetMessageHdrs:\n";
1971     errorStr += mysql_error(sock);
1972     mysql_close(sock);
1973     return -1;
1974 }
1975
1976 if (!(res=mysql_store_result(sock)))
1977 {
1978     errorStr = "Couldn't GetMessageHdrs:\n";
1979     errorStr += mysql_error(sock);
1980     mysql_close(sock);
1981     return -1;
1982 }
1983
1984 unsigned int i, num_rows =  mysql_num_rows(res);
1985 long long int unsigned id;
1986
1987 for (i=0; i<num_rows; i++)
1988 {
1989     row = mysql_fetch_row(res);
1990     if (str2x(row[1], id))
1991         continue;
1992     
1993     STG_MSG_HDR hdr;
1994     if (row[2]) 
1995         if(str2x(row[2], hdr.type))
1996             continue;
1997
1998     if (row[3])
1999         if(str2x(row[3], hdr.lastSendTime))
2000             continue;
2001
2002     if (row[4])
2003         if(str2x(row[4], hdr.creationTime))
2004             continue;
2005
2006     if (row[5])
2007         if(str2x(row[5], hdr.showTime))
2008             continue;
2009
2010     if (row[6])
2011         if(str2x(row[6], hdr.repeat))
2012             continue;
2013
2014     if (row[7])
2015         if(str2x(row[7], hdr.repeatPeriod))
2016             continue;
2017
2018     hdr.id = id;
2019     hdrsList->push_back(hdr);
2020 }
2021
2022 mysql_free_result(res);
2023 mysql_close(sock);
2024 return 0;
2025 }
2026 //-----------------------------------------------------------------------------
2027
2028 int MYSQL_STORE::MysqlSetQuery(const char * Query) const {
2029
2030     MYSQL * sock;
2031     int ret=MysqlGetQuery(Query,sock);
2032     mysql_close(sock);
2033     return ret;
2034 }
2035 //-----------------------------------------------------------------------------
2036 int  MYSQL_STORE::MysqlGetQuery(const char * Query,MYSQL * & sock) const {
2037     if (!(sock=MysqlConnect())) {
2038         return -1;
2039     }
2040     return   MysqlQuery(Query,sock);
2041 }
2042 //-----------------------------------------------------------------------------
2043 MYSQL *  MYSQL_STORE::MysqlConnect() const {
2044     MYSQL * sock;
2045     if ( !(sock=mysql_init(NULL)) ){
2046         errorStr= "mysql init susck\n";
2047         return NULL;
2048     }
2049     if (!(sock = mysql_real_connect(sock,storeSettings.GetDBHost().c_str(),
2050             storeSettings.GetDBUser().c_str(),storeSettings.GetDBPassword().c_str(),
2051             0,0,NULL,0)))
2052         {
2053             errorStr = "Couldn't connect to mysql engine! With error:\n";
2054             errorStr += mysql_error(sock);
2055             return NULL;
2056         }
2057     else{
2058          if(mysql_select_db(sock, storeSettings.GetDBName().c_str())){
2059              errorStr = "Database lost !\n";
2060              return NULL;
2061          }
2062     }
2063     return sock;
2064 }
2065 //-----------------------------------------------------------------------------