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;
119 property.tariffName.AddBeforeNotifier(&tariffNotifier);
120 property.passive.AddBeforeNotifier(&passiveNotifier);
121 property.cash.AddBeforeNotifier(&cashNotifier);
122 currIP.AddAfterNotifier(&ipNotifier);
124 lastScanMessages = 0;
126 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
128 pthread_mutexattr_t attr;
129 pthread_mutexattr_init(&attr);
130 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
131 pthread_mutex_init(&mutex, &attr);
133 //-----------------------------------------------------------------------------
134 USER::USER(const USER & u)
135 : property(u.settings),
136 WriteServLog(GetStgLogger()),
139 __connected(u.__connected),
140 connected(__connected),
141 __currIP(u.__currIP),
143 lastIPForDisconnect(0),
144 pingTime(u.pingTime),
145 sysAdmin(u.sysAdmin),
152 lastCashAdd(property.lastCashAdd),
153 passiveTime(property.passiveTime),
154 lastCashAddTime(property.lastCashAddTime),
155 freeMb(property.freeMb),
156 lastActivityTime(property.lastActivityTime),
157 password(property.password),
158 passive(property.passive),
159 disabled(property.disabled),
160 disabledDetailStat(property.disabledDetailStat),
161 alwaysOnline(property.alwaysOnline),
162 tariffName(property.tariffName),
163 nextTariff(property.nextTariff),
164 address(property.address),
166 group(property.group),
167 email(property.email),
168 phone(property.phone),
169 realName(property.realName),
170 credit(property.credit),
171 creditExpire(property.creditExpire),
173 userdata0(property.userdata0),
174 userdata1(property.userdata1),
175 userdata2(property.userdata2),
176 userdata3(property.userdata3),
177 userdata4(property.userdata4),
178 userdata5(property.userdata5),
179 userdata6(property.userdata6),
180 userdata7(property.userdata7),
181 userdata8(property.userdata8),
182 userdata9(property.userdata9),
183 passiveNotifier(this),
184 tariffNotifier(this),
197 lastWriteStat = u.lastWriteStat;
198 lastWriteDeatiledStat = u.lastWriteDeatiledStat;
200 settings = u.settings;
202 property.tariffName.AddBeforeNotifier(&tariffNotifier);
203 property.passive.AddBeforeNotifier(&passiveNotifier);
204 property.cash.AddBeforeNotifier(&cashNotifier);
205 currIP.AddAfterNotifier(&ipNotifier);
207 lastScanMessages = 0;
209 writeFreeMbTraffCost = settings->GetWriteFreeMbTraffCost();
211 property.SetProperties(u.property);
213 pthread_mutexattr_t attr;
214 pthread_mutexattr_init(&attr);
215 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
216 pthread_mutex_init(&mutex, &attr);
218 //-----------------------------------------------------------------------------
221 property.passive.DelBeforeNotifier(&passiveNotifier);
222 property.tariffName.DelBeforeNotifier(&tariffNotifier);
223 pthread_mutex_destroy(&mutex);
225 //-----------------------------------------------------------------------------
226 void USER::SetLogin(string const & l)
228 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
229 assert(login.empty() && "Login is already set");
231 id = userIDGenerator.GetNextID();
233 //-----------------------------------------------------------------------------
236 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
239 if (store->RestoreUserConf(&conf, login))
241 WriteServLog("Cannot read conf for user %s.", login.c_str());
242 WriteServLog("%s", store->GetStrError().c_str());
243 printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str());
244 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
248 property.SetConf(conf);
250 tariff = tariffs->FindByName(tariffName);
253 WriteServLog("Cannot read user %s. Tariff %s not exist.",
254 login.c_str(), property.tariffName.Get().c_str());
260 //-----------------------------------------------------------------------------
263 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
266 if (store->RestoreUserStat(&stat, login))
268 WriteServLog("Cannot read stat for user %s.", login.c_str());
269 WriteServLog("%s", store->GetStrError().c_str());
270 printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str());
271 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
275 property.SetStat(stat);
279 //-----------------------------------------------------------------------------
280 int USER::WriteConf()
282 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
283 USER_CONF conf(property.GetConf());
285 printfd(__FILE__, "USER::WriteConf()\n");
287 if (store->SaveUserConf(conf, login))
289 WriteServLog("Cannot write conf for user %s.", login.c_str());
290 WriteServLog("%s", store->GetStrError().c_str());
291 printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str());
292 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
298 //-----------------------------------------------------------------------------
299 int USER::WriteStat()
301 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
302 USER_STAT stat(property.GetStat());
304 printfd(__FILE__, "USER::WriteStat()\n");
306 if (store->SaveUserStat(stat, login))
308 WriteServLog("Cannot write stat for user %s.", login.c_str());
309 WriteServLog("%s", store->GetStrError().c_str());
310 printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str());
311 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
315 lastWriteStat = stgTime;
319 //-----------------------------------------------------------------------------
320 int USER::WriteMonthStat()
322 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
323 time_t tt = stgTime - 3600;
324 struct tm * t1 = localtime(&tt);
326 USER_STAT stat(property.GetStat());
327 if (store->SaveMonthStat(stat, t1->tm_mon, t1->tm_year, login))
329 WriteServLog("Cannot write month stat for user %s.", login.c_str());
330 WriteServLog("%s", store->GetStrError().c_str());
331 printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str());
332 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
338 //-----------------------------------------------------------------------------
339 int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth)
341 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
343 * Authorize user. It only means that user will be authorized. Nothing more.
344 * User can be connected or disconnected while authorized.
345 * Example: user is authorized but disconnected due to 0 money or blocking
349 * Prevent double authorization by identical authorizers
351 if (authorizedBy.find(auth) != authorizedBy.end())
357 for (int i = 0; i < DIR_NUM; i++)
359 enabledDirs[i] = dirs & (1 << i);
362 if (authorizedBy.size())
366 // We are already authorized, but with different IP address
367 errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip);
371 map<uint32_t, user_iter>::const_iterator ci = ipIndex->find(ip);
372 if (ci != ipIndex->end())
374 // Address is already present in IP-index
375 // If it's not our IP - throw an error
376 if (&(*ci->second) != this)
378 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
385 if (ipIndex->find(ip) != ipIndex->end())
387 // Address is already present in IP-index
388 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
392 if (ips.ConstData().IsIPInIPS(ip))
395 lastIPForDisconnect = currIP;
399 printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str());
400 errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login;
405 authorizedBy.insert(auth);
411 //-----------------------------------------------------------------------------
412 void USER::Unauthorize(const BASE_AUTH * auth)
414 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
416 * Authorizer tries to unauthorize user, that was not authorized by it
418 if (!authorizedBy.erase(auth))
421 if (authorizedBy.empty())
423 lastIPForDisconnect = currIP;
424 currIP = 0; // DelUser in traffcounter
428 //-----------------------------------------------------------------------------
429 bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const
431 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
432 // Is this user authorized by specified authorizer?
433 return authorizedBy.find(auth) != authorizedBy.end();
435 //-----------------------------------------------------------------------------
436 void USER::Connect(bool fakeConnect)
439 * Connect user to Internet. This function is differ from Authorize() !!!
442 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
446 string scriptOnConnect = settings->GetScriptDir() + "/OnConnect";
448 if (access(scriptOnConnect.c_str(), X_OK) == 0)
450 char dirsStr[DIR_NUM + 1];
451 dirsStr[DIR_NUM] = 0;
452 for (int i = 0; i < DIR_NUM; i++)
454 dirsStr[i] = enabledDirs[i] ? '1' : '0';
457 string scriptOnConnectParams;
458 strprintf(&scriptOnConnectParams,
459 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
460 scriptOnConnect.c_str(),
462 inet_ntostring(currIP).c_str(),
467 ScriptExec(scriptOnConnectParams);
471 WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
477 if (store->WriteUserConnect(login, currIP))
479 WriteServLog("Cannot write connect for user %s.", login.c_str());
480 WriteServLog("%s", store->GetStrError().c_str());
484 lastIPForDisconnect = currIP;
486 //-----------------------------------------------------------------------------
487 void USER::Disconnect(bool fakeDisconnect, const std::string & reason)
490 * Disconnect user from Internet. This function is differ from UnAuthorize() !!!
493 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
495 if (!lastIPForDisconnect)
497 printfd(__FILE__, "lastIPForDisconnect\n");
503 string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect";
505 if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
507 char dirsStr[DIR_NUM + 1];
508 dirsStr[DIR_NUM] = 0;
509 for (int i = 0; i < DIR_NUM; i++)
511 dirsStr[i] = enabledDirs[i] ? '1' : '0';
514 string scriptOnDisonnectParams;
515 strprintf(&scriptOnDisonnectParams,
516 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
517 scriptOnDisonnect.c_str(),
519 inet_ntostring(lastIPForDisconnect).c_str(),
524 ScriptExec(scriptOnDisonnectParams);
528 WriteServLog("Script OnDisconnect cannot be executed. File not found.");
534 if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason))
536 WriteServLog("Cannot write disconnect for user %s.", login.c_str());
537 WriteServLog("%s", store->GetStrError().c_str());
541 lastIPForDisconnect = 0;
543 DIR_TRAFF zeroSesssion;
545 sessionUpload = zeroSesssion;
546 sessionDownload = zeroSesssion;
548 //-----------------------------------------------------------------------------
549 void USER::PrintUser() const
552 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
553 cout << "============================================================" << endl;
554 cout << "id=" << id << endl;
555 cout << "login=" << login << endl;
556 cout << "password=" << password << endl;
557 cout << "passive=" << passive << endl;
558 cout << "disabled=" << disabled << endl;
559 cout << "disabledDetailStat=" << disabledDetailStat << endl;
560 cout << "alwaysOnline=" << alwaysOnline << endl;
561 cout << "tariffName=" << tariffName << endl;
562 cout << "address=" << address << endl;
563 cout << "phone=" << phone << endl;
564 cout << "email=" << email << endl;
565 cout << "note=" << note << endl;
566 cout << "realName=" <<realName << endl;
567 cout << "group=" << group << endl;
568 cout << "credit=" << credit << endl;
569 cout << "nextTariff=" << nextTariff << endl;
570 cout << "userdata0" << userdata0 << endl;
571 cout << "userdata1" << userdata1 << endl;
572 cout << "creditExpire=" << creditExpire << endl;
573 cout << "ips=" << ips << endl;
574 cout << "------------------------" << endl;
575 cout << "up=" << up << endl;
576 cout << "down=" << down << endl;
577 cout << "cash=" << cash << endl;
578 cout << "freeMb=" << freeMb << endl;
579 cout << "lastCashAdd=" << lastCashAdd << endl;
580 cout << "lastCashAddTime=" << lastCashAddTime << endl;
581 cout << "passiveTime=" << passiveTime << endl;
582 cout << "lastActivityTime=" << lastActivityTime << endl;
583 cout << "============================================================" << endl;
585 //-----------------------------------------------------------------------------
588 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
590 if (stgTime - lastWriteStat > settings->GetStatWritePeriod())
592 printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str());
595 if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime)
597 WriteServLog("User: %s. Credit expired.", login.c_str());
603 if (passive.ConstData()
604 && (stgTime % 30 == 0)
605 && (passiveTime.ModificationTime() != stgTime))
607 passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime());
608 printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData());
611 if (!authorizedBy.empty())
615 lastActivityTime = *const_cast<time_t *>(&stgTime);
617 if (!connected && IsInetable())
621 if (connected && !IsInetable())
624 Disconnect(false, "disabled");
626 Disconnect(false, "passive");
628 Disconnect(false, "no cash");
631 if (stgTime - lastScanMessages > 10)
634 lastScanMessages = stgTime;
641 Disconnect(false, "not authorized");
646 //-----------------------------------------------------------------------------
647 void USER::UpdatePingTime(time_t t)
649 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
650 //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str());
656 //-----------------------------------------------------------------------------
657 bool USER::IsInetable()
659 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
661 if (disabled || passive)
664 if (settings->GetFreeMbAllowInet())
670 if (settings->GetShowFeeInCash())
672 return (cash >= -credit);
675 return (cash - tariff->GetFee() >= -credit);
677 //-----------------------------------------------------------------------------
678 string USER::GetEnabledDirs()
680 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
683 for(int i = 0; i < DIR_NUM; i++)
684 dirs += enabledDirs[i] ? "1" : "0";
687 //-----------------------------------------------------------------------------
688 #ifdef TRAFF_STAT_WITH_PORTS
689 void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len)
691 void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
694 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
702 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
703 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
707 int tt = tariff->GetTraffType();
708 if (tt == TRAFF_UP ||
709 tt == TRAFF_UP_DOWN ||
710 // Check NEW traff data
711 (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir]))
714 if (traff < threshold &&
715 traff + len >= threshold)
717 // cash = partBeforeThreshold * priceBeforeThreshold +
718 // partAfterThreshold * priceAfterThreshold
719 int64_t before = threshold - traff; // Chunk part before threshold
720 int64_t after = len - before; // Chunk part after threshold
721 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk
722 down.ConstData()[dir],
725 tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk
726 down.ConstData()[dir],
732 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
733 down.ConstData()[dir],
738 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
740 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
741 cost = dc - freeMb.ConstData();
743 // Direct access to internal data structures via friend-specifier
744 property.stat.freeMb -= dc;
745 property.stat.cash -= cost;
751 sessionUpload[dir] += len;
755 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
758 #ifdef TRAFF_STAT_WITH_PORTS
759 IP_DIR_PAIR idp(ip, dir, port);
761 IP_DIR_PAIR idp(ip, dir);
764 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
765 lb = traffStat.lower_bound(idp);
766 if (lb == traffStat.end() || lb->first != idp)
769 pair<IP_DIR_PAIR, STAT_NODE>(idp,
770 STAT_NODE(len, 0, cost)));
774 lb->second.cash += cost;
775 lb->second.up += len;
778 //-----------------------------------------------------------------------------
779 #ifdef TRAFF_STAT_WITH_PORTS
780 void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
782 void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
785 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
793 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
794 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
798 int tt = tariff->GetTraffType();
799 if (tt == TRAFF_DOWN ||
800 tt == TRAFF_UP_DOWN ||
801 // Check NEW traff data
802 (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir]))
805 if (traff < threshold &&
806 traff + len >= threshold)
808 // cash = partBeforeThreshold * priceBeforeThreshold +
809 // partAfterThreshold * priceAfterThreshold
810 int64_t before = threshold - traff; // Chunk part before threshold
811 int64_t after = len - before; // Chunk part after threshold
812 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
813 down.ConstData()[dir], // Traff before chunk
816 tariff->GetPriceWithTraffType(up.ConstData()[dir],
817 dt[dir], // Traff after chunk
823 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
824 down.ConstData()[dir],
829 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
831 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
832 cost = dc - freeMb.ConstData();
834 property.stat.freeMb -= dc;
835 property.stat.cash -= cost;
841 sessionDownload[dir] += len;
845 if (!writeFreeMbTraffCost && freeMb.ConstData() >= 0)
848 #ifdef TRAFF_STAT_WITH_PORTS
849 IP_DIR_PAIR idp(ip, dir, port);
851 IP_DIR_PAIR idp(ip, dir);
854 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
855 lb = traffStat.lower_bound(idp);
856 if (lb == traffStat.end() || lb->first != idp)
859 pair<IP_DIR_PAIR, STAT_NODE>(idp,
860 STAT_NODE(0, len, cost)));
864 lb->second.cash += cost;
865 lb->second.down += len;
868 //-----------------------------------------------------------------------------
869 void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
871 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
872 currIP.AddBeforeNotifier(n);
874 //-----------------------------------------------------------------------------
875 void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
877 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
878 currIP.DelBeforeNotifier(n);
880 //-----------------------------------------------------------------------------
881 void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
883 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
884 currIP.AddAfterNotifier(n);
886 //-----------------------------------------------------------------------------
887 void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
889 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
890 currIP.DelAfterNotifier(n);
892 //-----------------------------------------------------------------------------
895 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
897 string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd";
899 if (access(scriptOnAdd.c_str(), X_OK) == 0)
901 string scriptOnAddParams;
902 strprintf(&scriptOnAddParams,
907 ScriptExec(scriptOnAddParams);
911 WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str());
914 //-----------------------------------------------------------------------------
915 void USER::OnDelete()
917 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
919 string scriptOnDel = settings->GetScriptDir() + "/OnUserDel";
921 if (access(scriptOnDel.c_str(), X_OK) == 0)
923 string scriptOnDelParams;
924 strprintf(&scriptOnDelParams,
929 ScriptExec(scriptOnDelParams);
933 WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str());
938 //-----------------------------------------------------------------------------
939 int USER::WriteDetailStat(bool hard)
941 printfd(__FILE__, "USER::WriteDetailedStat() - saved size = %d\n", traffStatSaved.second.size());
943 if (!traffStatSaved.second.empty())
945 if (store->WriteDetailedStat(traffStatSaved.second, traffStatSaved.first, login))
947 printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n");
948 WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatSaved.second.size(), login.c_str());
949 WriteServLog("%s", store->GetStrError().c_str());
952 traffStatSaved.second.erase(traffStatSaved.second.begin(), traffStatSaved.second.end());
958 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
962 printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size());
964 if (ts.size() && !disabledDetailStat)
966 if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login))
968 printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n");
969 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
970 WriteServLog("%s", store->GetStrError().c_str());
973 printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n");
974 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
975 traffStatSaved.second.swap(ts);
976 traffStatSaved.first = lastWriteDeatiledStat;
981 lastWriteDeatiledStat = stgTime;
984 //-----------------------------------------------------------------------------
985 double USER::GetPassiveTimePart() const
987 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
989 static int daysInMonth[12] =
990 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
996 time_t secMonth = daysInMonth[(tms->tm_mon + 11) % 12] * 24 * 3600; // Previous month
998 if (tms->tm_year % 4 == 0 && tms->tm_mon == 1)
1001 secMonth += 24 * 3600;
1004 int dt = secMonth - passiveTime;
1009 return double(dt) / (secMonth);
1011 //-----------------------------------------------------------------------------
1012 void USER::SetPassiveTimeAsNewUser()
1014 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1020 int daysCurrMon = DaysInCurrentMonth();
1021 double pt = (tm->tm_mday - 1) / (double)daysCurrMon;
1023 passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
1025 //-----------------------------------------------------------------------------
1026 void USER::MidnightResetSessionStat()
1028 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1032 Disconnect(true, "fake");
1036 //-----------------------------------------------------------------------------
1037 void USER::ProcessNewMonth()
1039 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1043 Disconnect(true, "fake");
1045 DIR_TRAFF zeroTarff;
1058 if (nextTariff.ConstData() != "")
1061 nt = tariffs->FindByName(nextTariff);
1064 WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
1065 login.c_str(), property.tariffName.Get().c_str());
1069 property.tariffName.Set(nextTariff, sysAdmin, login, store);
1076 //-----------------------------------------------------------------------------
1077 void USER::ProcessDayFeeSpread()
1079 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1081 if (passive.ConstData())
1084 double f = tariff->GetFee() / DaysInCurrentMonth();
1090 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1093 //-----------------------------------------------------------------------------
1094 void USER::ProcessDayFee()
1096 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1098 double passiveTimePart = 1.0;
1099 if (!settings->GetFullFee())
1101 passiveTimePart = GetPassiveTimePart();
1105 if (passive.ConstData())
1107 printfd(__FILE__, "Don't charge fee `cause we are passive\n");
1111 double f = tariff->GetFee() * passiveTimePart;
1119 printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
1124 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1126 //-----------------------------------------------------------------------------
1127 void USER::SetPrepaidTraff()
1129 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1131 property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic");
1133 //-----------------------------------------------------------------------------
1134 int USER::AddMessage(STG_MSG * msg)
1136 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1138 if (SendMessage(*msg) == 0)
1140 if (msg->header.repeat > 0)
1142 msg->header.repeat--;
1144 //TODO: gcc v. 4.x generate ICE on x86_64
1145 msg->header.lastSendTime = time(NULL);
1147 msg->header.lastSendTime = stgTime;
1149 if (store->AddMessage(msg, login))
1151 errorStr = store->GetStrError();
1152 STG_LOGGER & WriteServLog = GetStgLogger();
1153 WriteServLog("Error adding message %s", errorStr.c_str());
1154 WriteServLog("%s", store->GetStrError().c_str());
1161 if (store->AddMessage(msg, login))
1163 errorStr = store->GetStrError();
1164 STG_LOGGER & WriteServLog = GetStgLogger();
1165 WriteServLog("Error adding message %s", errorStr.c_str());
1166 WriteServLog("%s", store->GetStrError().c_str());
1172 //-----------------------------------------------------------------------------
1173 int USER::SendMessage(const STG_MSG & msg)
1175 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1177 if (authorizedBy.empty())
1183 set<const BASE_AUTH*>::iterator it;
1185 it = authorizedBy.begin();
1186 while (it != authorizedBy.end())
1188 if ((*it)->SendMessage(msg, currIP) == 0)
1194 //-----------------------------------------------------------------------------
1195 int USER::ScanMessage()
1197 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1199 vector<STG_MSG_HDR> hdrsList;
1201 if (store->GetMessageHdrs(&hdrsList, login))
1203 printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
1207 for (unsigned i = 0; i < hdrsList.size(); i++)
1210 if (hdrsList[i].lastSendTime + hdrsList[i].repeatPeriod * 60 < (unsigned)stgTime)
1213 if (store->GetMessage(hdrsList[i].id, &msg, login) == 0)
1215 if (SendMessage(msg) == 0)
1217 msg.header.repeat--;
1218 if (msg.header.repeat < 0)
1220 printfd(__FILE__, "DelMessage\n");
1221 store->DelMessage(hdrsList[i].id, login);
1226 //TODO: gcc v. 4.x generate ICE on x86_64
1227 msg.header.lastSendTime = time(NULL);
1229 msg.header.lastSendTime = stgTime;
1231 if (store->EditMessage(msg, login))
1233 printfd(__FILE__, "EditMessage Error %s\n", store->GetStrError().c_str());
1240 WriteServLog("Cannot get message for user %s.", login.c_str());
1241 WriteServLog("%s", store->GetStrError().c_str());
1247 //-----------------------------------------------------------------------------
1248 //-----------------------------------------------------------------------------
1249 //-----------------------------------------------------------------------------
1250 void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
1252 if (newPassive && !oldPassive)
1253 user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(),
1259 //-----------------------------------------------------------------------------
1260 void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
1262 user->tariff = user->tariffs->FindByName(newTariff);
1264 //-----------------------------------------------------------------------------
1265 void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash)
1267 user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
1268 user->lastCashAdd = newCash - oldCash;
1270 //-----------------------------------------------------------------------------
1271 void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to)
1273 printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str());
1275 if (user->connected)
1276 user->Disconnect(false, "Change IP");
1278 if (user->IsInetable())
1279 user->Connect(false);
1281 //-----------------------------------------------------------------------------