2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
27 $Date: 2010/11/03 10:50:03 $
36 #include <unistd.h> // access
43 #include "script_executer.h"
48 USER::USER(const SETTINGS * s,
49 const BASE_STORE * st,
52 const map<uint32_t, user_iter> * ipIdx)
54 WriteServLog(GetStgLogger()),
58 connected(__connected),
62 lastIPForDisconnect(0),
67 tariff(tariffs->GetNoTariff()),
71 lastCashAdd(property.lastCashAdd),
72 passiveTime(property.passiveTime),
73 lastCashAddTime(property.lastCashAddTime),
74 freeMb(property.freeMb),
75 lastActivityTime(property.lastActivityTime),
76 password(property.password),
77 passive(property.passive),
78 disabled(property.disabled),
79 disabledDetailStat(property.disabledDetailStat),
80 alwaysOnline(property.alwaysOnline),
81 tariffName(property.tariffName),
82 nextTariff(property.nextTariff),
83 address(property.address),
85 group(property.group),
86 email(property.email),
87 phone(property.phone),
88 realName(property.realName),
89 credit(property.credit),
90 creditExpire(property.creditExpire),
92 userdata0(property.userdata0),
93 userdata1(property.userdata1),
94 userdata2(property.userdata2),
95 userdata3(property.userdata3),
96 userdata4(property.userdata4),
97 userdata5(property.userdata5),
98 userdata6(property.userdata6),
99 userdata7(property.userdata7),
100 userdata8(property.userdata8),
101 userdata9(property.userdata9),
102 passiveNotifier(this),
103 tariffNotifier(this),
110 password = "*_EMPTY_PASSWORD_*";
111 tariffName = NO_TARIFF_NAME;
113 tariff = tariffs->GetNoTariff();
116 lastWriteStat = stgTime + random() % settings->GetStatWritePeriod();
117 lastWriteDeatiledStat = stgTime;
118 lastSwapDeatiledStat = stgTime;
120 property.tariffName.AddBeforeNotifier(&tariffNotifier);
121 property.passive.AddBeforeNotifier(&passiveNotifier);
122 property.cash.AddBeforeNotifier(&cashNotifier);
123 currIP.AddAfterNotifier(&ipNotifier);
125 lastScanMessages = 0;
127 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
129 pthread_mutexattr_t attr;
130 pthread_mutexattr_init(&attr);
131 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
132 pthread_mutex_init(&mutex, &attr);
134 //-----------------------------------------------------------------------------
135 USER::USER(const USER & u)
136 : property(u.settings),
137 WriteServLog(GetStgLogger()),
140 __connected(u.__connected),
141 connected(__connected),
142 __currIP(u.__currIP),
144 lastIPForDisconnect(0),
145 pingTime(u.pingTime),
146 sysAdmin(u.sysAdmin),
153 lastCashAdd(property.lastCashAdd),
154 passiveTime(property.passiveTime),
155 lastCashAddTime(property.lastCashAddTime),
156 freeMb(property.freeMb),
157 lastActivityTime(property.lastActivityTime),
158 password(property.password),
159 passive(property.passive),
160 disabled(property.disabled),
161 disabledDetailStat(property.disabledDetailStat),
162 alwaysOnline(property.alwaysOnline),
163 tariffName(property.tariffName),
164 nextTariff(property.nextTariff),
165 address(property.address),
167 group(property.group),
168 email(property.email),
169 phone(property.phone),
170 realName(property.realName),
171 credit(property.credit),
172 creditExpire(property.creditExpire),
174 userdata0(property.userdata0),
175 userdata1(property.userdata1),
176 userdata2(property.userdata2),
177 userdata3(property.userdata3),
178 userdata4(property.userdata4),
179 userdata5(property.userdata5),
180 userdata6(property.userdata6),
181 userdata7(property.userdata7),
182 userdata8(property.userdata8),
183 userdata9(property.userdata9),
184 passiveNotifier(this),
185 tariffNotifier(this),
198 lastWriteStat = u.lastWriteStat;
199 lastWriteDeatiledStat = u.lastWriteDeatiledStat;
200 lastSwapDeatiledStat = u.lastSwapDeatiledStat;
202 settings = u.settings;
204 property.tariffName.AddBeforeNotifier(&tariffNotifier);
205 property.passive.AddBeforeNotifier(&passiveNotifier);
206 property.cash.AddBeforeNotifier(&cashNotifier);
207 currIP.AddAfterNotifier(&ipNotifier);
209 lastScanMessages = 0;
211 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
213 property.SetProperties(u.property);
215 pthread_mutexattr_t attr;
216 pthread_mutexattr_init(&attr);
217 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
218 pthread_mutex_init(&mutex, &attr);
220 //-----------------------------------------------------------------------------
223 property.passive.DelBeforeNotifier(&passiveNotifier);
224 property.tariffName.DelBeforeNotifier(&tariffNotifier);
225 pthread_mutex_destroy(&mutex);
227 //-----------------------------------------------------------------------------
228 void USER::SetLogin(string const & l)
230 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
231 assert(login.empty() && "Login is already set");
233 id = userIDGenerator.GetNextID();
235 //-----------------------------------------------------------------------------
238 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
241 if (store->RestoreUserConf(&conf, login))
243 WriteServLog("Cannot read conf for user %s.", login.c_str());
244 WriteServLog("%s", store->GetStrError().c_str());
245 printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str());
246 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
250 property.SetConf(conf);
252 tariff = tariffs->FindByName(tariffName);
255 WriteServLog("Cannot read user %s. Tariff %s not exist.",
256 login.c_str(), property.tariffName.Get().c_str());
262 //-----------------------------------------------------------------------------
265 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
268 if (store->RestoreUserStat(&stat, login))
270 WriteServLog("Cannot read stat for user %s.", login.c_str());
271 WriteServLog("%s", store->GetStrError().c_str());
272 printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str());
273 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
277 property.SetStat(stat);
281 //-----------------------------------------------------------------------------
282 int USER::WriteConf()
284 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
285 USER_CONF conf(property.GetConf());
287 printfd(__FILE__, "USER::WriteConf()\n");
289 if (store->SaveUserConf(conf, login))
291 WriteServLog("Cannot write conf for user %s.", login.c_str());
292 WriteServLog("%s", store->GetStrError().c_str());
293 printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str());
294 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
300 //-----------------------------------------------------------------------------
301 int USER::WriteStat()
303 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
304 USER_STAT stat(property.GetStat());
306 printfd(__FILE__, "USER::WriteStat()\n");
308 if (store->SaveUserStat(stat, login))
310 WriteServLog("Cannot write stat for user %s.", login.c_str());
311 WriteServLog("%s", store->GetStrError().c_str());
312 printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str());
313 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
317 lastWriteStat = stgTime;
321 //-----------------------------------------------------------------------------
322 int USER::WriteMonthStat()
324 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
325 time_t tt = stgTime - 3600;
326 struct tm * t1 = localtime(&tt);
328 USER_STAT stat(property.GetStat());
329 if (store->SaveMonthStat(stat, t1->tm_mon, t1->tm_year, login))
331 WriteServLog("Cannot write month stat for user %s.", login.c_str());
332 WriteServLog("%s", store->GetStrError().c_str());
333 printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str());
334 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
340 //-----------------------------------------------------------------------------
341 int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth)
343 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
345 * Authorize user. It only means that user will be authorized. Nothing more.
346 * User can be connected or disconnected while authorized.
347 * Example: user is authorized but disconnected due to 0 money or blocking
351 * Prevent double authorization by identical authorizers
353 if (authorizedBy.find(auth) != authorizedBy.end())
359 for (int i = 0; i < DIR_NUM; i++)
361 enabledDirs[i] = dirs & (1 << i);
364 if (authorizedBy.size())
368 // We are already authorized, but with different IP address
369 errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip);
373 map<uint32_t, user_iter>::const_iterator ci = ipIndex->find(ip);
374 if (ci != ipIndex->end())
376 // Address is already present in IP-index
377 // If it's not our IP - throw an error
378 if (&(*ci->second) != this)
380 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
387 if (ipIndex->find(ip) != ipIndex->end())
389 // Address is already present in IP-index
390 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
394 if (ips.ConstData().IsIPInIPS(ip))
397 lastIPForDisconnect = currIP;
401 printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str());
402 errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login;
407 authorizedBy.insert(auth);
413 //-----------------------------------------------------------------------------
414 void USER::Unauthorize(const BASE_AUTH * auth)
416 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
418 * Authorizer tries to unauthorize user, that was not authorized by it
420 if (!authorizedBy.erase(auth))
423 if (authorizedBy.empty())
425 lastIPForDisconnect = currIP;
426 currIP = 0; // DelUser in traffcounter
430 //-----------------------------------------------------------------------------
431 bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const
433 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
434 // Is this user authorized by specified authorizer?
435 return authorizedBy.find(auth) != authorizedBy.end();
437 //-----------------------------------------------------------------------------
438 void USER::Connect(bool fakeConnect)
441 * Connect user to Internet. This function is differ from Authorize() !!!
444 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
448 string scriptOnConnect = settings->GetScriptDir() + "/OnConnect";
450 if (access(scriptOnConnect.c_str(), X_OK) == 0)
452 char dirsStr[DIR_NUM + 1];
453 dirsStr[DIR_NUM] = 0;
454 for (int i = 0; i < DIR_NUM; i++)
456 dirsStr[i] = enabledDirs[i] ? '1' : '0';
459 string scriptOnConnectParams;
460 strprintf(&scriptOnConnectParams,
461 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
462 scriptOnConnect.c_str(),
464 inet_ntostring(currIP).c_str(),
469 ScriptExec(scriptOnConnectParams);
473 WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
479 if (store->WriteUserConnect(login, currIP))
481 WriteServLog("Cannot write connect for user %s.", login.c_str());
482 WriteServLog("%s", store->GetStrError().c_str());
486 lastIPForDisconnect = currIP;
488 //-----------------------------------------------------------------------------
489 void USER::Disconnect(bool fakeDisconnect, const std::string & reason)
492 * Disconnect user from Internet. This function is differ from UnAuthorize() !!!
495 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
497 if (!lastIPForDisconnect)
499 printfd(__FILE__, "lastIPForDisconnect\n");
505 string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect";
507 if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
509 char dirsStr[DIR_NUM + 1];
510 dirsStr[DIR_NUM] = 0;
511 for (int i = 0; i < DIR_NUM; i++)
513 dirsStr[i] = enabledDirs[i] ? '1' : '0';
516 string scriptOnDisonnectParams;
517 strprintf(&scriptOnDisonnectParams,
518 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
519 scriptOnDisonnect.c_str(),
521 inet_ntostring(lastIPForDisconnect).c_str(),
526 ScriptExec(scriptOnDisonnectParams);
530 WriteServLog("Script OnDisconnect cannot be executed. File not found.");
536 if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason))
538 WriteServLog("Cannot write disconnect for user %s.", login.c_str());
539 WriteServLog("%s", store->GetStrError().c_str());
543 lastIPForDisconnect = 0;
545 DIR_TRAFF zeroSesssion;
547 sessionUpload = zeroSesssion;
548 sessionDownload = zeroSesssion;
550 //-----------------------------------------------------------------------------
551 void USER::PrintUser() const
554 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
555 cout << "============================================================" << endl;
556 cout << "id=" << id << endl;
557 cout << "login=" << login << endl;
558 cout << "password=" << password << endl;
559 cout << "passive=" << passive << endl;
560 cout << "disabled=" << disabled << endl;
561 cout << "disabledDetailStat=" << disabledDetailStat << endl;
562 cout << "alwaysOnline=" << alwaysOnline << endl;
563 cout << "tariffName=" << tariffName << endl;
564 cout << "address=" << address << endl;
565 cout << "phone=" << phone << endl;
566 cout << "email=" << email << endl;
567 cout << "note=" << note << endl;
568 cout << "realName=" <<realName << endl;
569 cout << "group=" << group << endl;
570 cout << "credit=" << credit << endl;
571 cout << "nextTariff=" << nextTariff << endl;
572 cout << "userdata0" << userdata0 << endl;
573 cout << "userdata1" << userdata1 << endl;
574 cout << "creditExpire=" << creditExpire << endl;
575 cout << "ips=" << ips << endl;
576 cout << "------------------------" << endl;
577 cout << "up=" << up << endl;
578 cout << "down=" << down << endl;
579 cout << "cash=" << cash << endl;
580 cout << "freeMb=" << freeMb << endl;
581 cout << "lastCashAdd=" << lastCashAdd << endl;
582 cout << "lastCashAddTime=" << lastCashAddTime << endl;
583 cout << "passiveTime=" << passiveTime << endl;
584 cout << "lastActivityTime=" << lastActivityTime << endl;
585 cout << "============================================================" << endl;
587 //-----------------------------------------------------------------------------
590 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
592 if (stgTime - lastWriteStat > settings->GetStatWritePeriod())
594 printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str());
597 if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime)
599 WriteServLog("User: %s. Credit expired.", login.c_str());
605 if (passive.ConstData()
606 && (stgTime % 30 == 0)
607 && (passiveTime.ModificationTime() != stgTime))
609 passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime());
610 printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData());
613 if (!authorizedBy.empty())
617 lastActivityTime = *const_cast<time_t *>(&stgTime);
619 if (!connected && IsInetable())
623 if (connected && !IsInetable())
626 Disconnect(false, "disabled");
628 Disconnect(false, "passive");
630 Disconnect(false, "no cash");
633 if (stgTime - lastScanMessages > 10)
636 lastScanMessages = stgTime;
643 Disconnect(false, "not authorized");
648 //-----------------------------------------------------------------------------
649 void USER::UpdatePingTime(time_t t)
651 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
652 //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str());
658 //-----------------------------------------------------------------------------
659 bool USER::IsInetable()
661 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
663 if (disabled || passive)
666 if (settings->GetFreeMbAllowInet())
672 if (settings->GetShowFeeInCash())
674 return (cash >= -credit);
677 return (cash - tariff->GetFee() >= -credit);
679 //-----------------------------------------------------------------------------
680 string USER::GetEnabledDirs()
682 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
685 for(int i = 0; i < DIR_NUM; i++)
686 dirs += enabledDirs[i] ? "1" : "0";
689 //-----------------------------------------------------------------------------
690 #ifdef TRAFF_STAT_WITH_PORTS
691 void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len)
693 void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
696 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
704 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
705 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
709 int tt = tariff->GetTraffType();
710 if (tt == TRAFF_UP ||
711 tt == TRAFF_UP_DOWN ||
712 // Check NEW traff data
713 (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir]))
716 if (traff < threshold &&
717 traff + len >= threshold)
719 // cash = partBeforeThreshold * priceBeforeThreshold +
720 // partAfterThreshold * priceAfterThreshold
721 int64_t before = threshold - traff; // Chunk part before threshold
722 int64_t after = len - before; // Chunk part after threshold
723 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk
724 down.ConstData()[dir],
727 tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk
728 down.ConstData()[dir],
734 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
735 down.ConstData()[dir],
740 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
742 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
743 cost = dc - freeMb.ConstData();
745 // Direct access to internal data structures via friend-specifier
746 property.stat.freeMb -= dc;
747 property.stat.cash -= cost;
753 sessionUpload[dir] += len;
757 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
760 #ifdef TRAFF_STAT_WITH_PORTS
761 IP_DIR_PAIR idp(ip, dir, port);
763 IP_DIR_PAIR idp(ip, dir);
766 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
767 lb = traffStat.lower_bound(idp);
768 if (lb == traffStat.end() || lb->first != idp)
771 pair<IP_DIR_PAIR, STAT_NODE>(idp,
772 STAT_NODE(len, 0, cost)));
776 lb->second.cash += cost;
777 lb->second.up += len;
780 //-----------------------------------------------------------------------------
781 #ifdef TRAFF_STAT_WITH_PORTS
782 void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
784 void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
787 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
795 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
796 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
800 int tt = tariff->GetTraffType();
801 if (tt == TRAFF_DOWN ||
802 tt == TRAFF_UP_DOWN ||
803 // Check NEW traff data
804 (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir]))
807 if (traff < threshold &&
808 traff + len >= threshold)
810 // cash = partBeforeThreshold * priceBeforeThreshold +
811 // partAfterThreshold * priceAfterThreshold
812 int64_t before = threshold - traff; // Chunk part before threshold
813 int64_t after = len - before; // Chunk part after threshold
814 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
815 down.ConstData()[dir], // Traff before chunk
818 tariff->GetPriceWithTraffType(up.ConstData()[dir],
819 dt[dir], // Traff after chunk
825 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
826 down.ConstData()[dir],
831 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
833 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
834 cost = dc - freeMb.ConstData();
836 property.stat.freeMb -= dc;
837 property.stat.cash -= cost;
843 sessionDownload[dir] += len;
847 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
850 #ifdef TRAFF_STAT_WITH_PORTS
851 IP_DIR_PAIR idp(ip, dir, port);
853 IP_DIR_PAIR idp(ip, dir);
856 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
857 lb = traffStat.lower_bound(idp);
858 if (lb == traffStat.end() || lb->first != idp)
861 pair<IP_DIR_PAIR, STAT_NODE>(idp,
862 STAT_NODE(0, len, cost)));
866 lb->second.cash += cost;
867 lb->second.down += len;
870 //-----------------------------------------------------------------------------
871 void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
873 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
874 currIP.AddBeforeNotifier(n);
876 //-----------------------------------------------------------------------------
877 void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
879 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
880 currIP.DelBeforeNotifier(n);
882 //-----------------------------------------------------------------------------
883 void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
885 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
886 currIP.AddAfterNotifier(n);
888 //-----------------------------------------------------------------------------
889 void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
891 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
892 currIP.DelAfterNotifier(n);
894 //-----------------------------------------------------------------------------
897 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
899 string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd";
901 if (access(scriptOnAdd.c_str(), X_OK) == 0)
903 string scriptOnAddParams;
904 strprintf(&scriptOnAddParams,
909 ScriptExec(scriptOnAddParams);
913 WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str());
916 //-----------------------------------------------------------------------------
917 void USER::OnDelete()
919 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
921 string scriptOnDel = settings->GetScriptDir() + "/OnUserDel";
923 if (access(scriptOnDel.c_str(), X_OK) == 0)
925 string scriptOnDelParams;
926 strprintf(&scriptOnDelParams,
931 ScriptExec(scriptOnDelParams);
935 WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str());
940 //-----------------------------------------------------------------------------
941 int USER::WriteDetailStat(bool hard)
943 printfd(__FILE__, "USER::WriteDetailedStat() - saved size = %d\n", traffStatSaved.second.size());
945 if (!traffStatSaved.second.empty())
947 if (store->WriteDetailedStat(traffStatSaved.second, traffStatSaved.first, login))
949 printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n");
950 WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatSaved.second.size(), login.c_str());
951 WriteServLog("%s", store->GetStrError().c_str());
954 traffStatSaved.second.erase(traffStatSaved.second.begin(), traffStatSaved.second.end());
960 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
964 printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size());
966 if (ts.size() && !disabledDetailStat)
968 if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login))
970 printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n");
971 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
972 WriteServLog("%s", store->GetStrError().c_str());
975 printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n");
976 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
977 traffStatSaved.second.swap(ts);
978 traffStatSaved.first = lastWriteDeatiledStat;
983 lastWriteDeatiledStat = stgTime;
986 //-----------------------------------------------------------------------------
987 double USER::GetPassiveTimePart() const
989 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
991 static int daysInMonth[12] =
992 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
998 time_t secMonth = daysInMonth[(tms->tm_mon + 11) % 12] * 24 * 3600; // Previous month
1000 if (tms->tm_year % 4 == 0 && tms->tm_mon == 1)
1003 secMonth += 24 * 3600;
1006 int dt = secMonth - passiveTime;
1011 return double(dt) / (secMonth);
1013 //-----------------------------------------------------------------------------
1014 void USER::SetPassiveTimeAsNewUser()
1016 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1022 int daysCurrMon = DaysInCurrentMonth();
1023 double pt = (tm->tm_mday - 1) / (double)daysCurrMon;
1025 passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
1027 //-----------------------------------------------------------------------------
1028 void USER::MidnightResetSessionStat()
1030 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1034 Disconnect(true, "fake");
1038 //-----------------------------------------------------------------------------
1039 void USER::ProcessNewMonth()
1041 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1045 Disconnect(true, "fake");
1047 DIR_TRAFF zeroTarff;
1060 if (nextTariff.ConstData() != "")
1063 nt = tariffs->FindByName(nextTariff);
1066 WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
1067 login.c_str(), property.tariffName.Get().c_str());
1071 property.tariffName.Set(nextTariff, sysAdmin, login, store);
1078 //-----------------------------------------------------------------------------
1079 void USER::ProcessDayFeeSpread()
1081 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1083 if (passive.ConstData())
1086 double f = tariff->GetFee() / DaysInCurrentMonth();
1092 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1095 //-----------------------------------------------------------------------------
1096 void USER::ProcessDayFee()
1098 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1100 double passiveTimePart = 1.0;
1101 if (!settings->GetFullFee())
1103 passiveTimePart = GetPassiveTimePart();
1107 if (passive.ConstData())
1109 printfd(__FILE__, "Don't charge fee `cause we are passive\n");
1113 double f = tariff->GetFee() * passiveTimePart;
1121 printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
1126 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1128 //-----------------------------------------------------------------------------
1129 void USER::SetPrepaidTraff()
1131 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1133 property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic");
1135 //-----------------------------------------------------------------------------
1136 int USER::AddMessage(STG_MSG * msg)
1138 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1140 if (SendMessage(*msg) == 0)
1142 if (msg->header.repeat > 0)
1144 msg->header.repeat--;
1146 //TODO: gcc v. 4.x generate ICE on x86_64
1147 msg->header.lastSendTime = time(NULL);
1149 msg->header.lastSendTime = stgTime;
1151 if (store->AddMessage(msg, login))
1153 errorStr = store->GetStrError();
1154 STG_LOGGER & WriteServLog = GetStgLogger();
1155 WriteServLog("Error adding message %s", errorStr.c_str());
1156 WriteServLog("%s", store->GetStrError().c_str());
1163 if (store->AddMessage(msg, login))
1165 errorStr = store->GetStrError();
1166 STG_LOGGER & WriteServLog = GetStgLogger();
1167 WriteServLog("Error adding message %s", errorStr.c_str());
1168 WriteServLog("%s", store->GetStrError().c_str());
1174 //-----------------------------------------------------------------------------
1175 int USER::SendMessage(const STG_MSG & msg)
1177 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1179 if (authorizedBy.empty())
1185 set<const BASE_AUTH*>::iterator it;
1187 it = authorizedBy.begin();
1188 while (it != authorizedBy.end())
1190 if ((*it)->SendMessage(msg, currIP) == 0)
1196 //-----------------------------------------------------------------------------
1197 int USER::ScanMessage()
1199 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1201 vector<STG_MSG_HDR> hdrsList;
1203 if (store->GetMessageHdrs(&hdrsList, login))
1205 printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
1209 for (unsigned i = 0; i < hdrsList.size(); i++)
1212 if (hdrsList[i].lastSendTime + hdrsList[i].repeatPeriod * 60 < (unsigned)stgTime)
1215 if (store->GetMessage(hdrsList[i].id, &msg, login) == 0)
1217 if (SendMessage(msg) == 0)
1219 msg.header.repeat--;
1220 if (msg.header.repeat < 0)
1222 printfd(__FILE__, "DelMessage\n");
1223 store->DelMessage(hdrsList[i].id, login);
1228 //TODO: gcc v. 4.x generate ICE on x86_64
1229 msg.header.lastSendTime = time(NULL);
1231 msg.header.lastSendTime = stgTime;
1233 if (store->EditMessage(msg, login))
1235 printfd(__FILE__, "EditMessage Error %s\n", store->GetStrError().c_str());
1242 WriteServLog("Cannot get message for user %s.", login.c_str());
1243 WriteServLog("%s", store->GetStrError().c_str());
1249 //-----------------------------------------------------------------------------
1250 //-----------------------------------------------------------------------------
1251 //-----------------------------------------------------------------------------
1252 void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
1254 if (newPassive && !oldPassive)
1255 user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(),
1261 //-----------------------------------------------------------------------------
1262 void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
1264 user->tariff = user->tariffs->FindByName(newTariff);
1266 //-----------------------------------------------------------------------------
1267 void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash)
1269 user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
1270 user->lastCashAdd = newCash - oldCash;
1272 //-----------------------------------------------------------------------------
1273 void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to)
1275 printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str());
1277 if (user->connected)
1278 user->Disconnect(false, "Change IP");
1280 if (user->IsInetable())
1281 user->Connect(false);
1283 //-----------------------------------------------------------------------------