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 pthread_mutexattr_t attr;
127 pthread_mutexattr_init(&attr);
128 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
129 pthread_mutex_init(&mutex, &attr);
131 //-----------------------------------------------------------------------------
132 USER::USER(const USER & u)
133 : property(u.settings),
134 WriteServLog(GetStgLogger()),
137 __connected(u.__connected),
138 connected(__connected),
139 __currIP(u.__currIP),
141 lastIPForDisconnect(0),
142 pingTime(u.pingTime),
143 sysAdmin(u.sysAdmin),
150 lastCashAdd(property.lastCashAdd),
151 passiveTime(property.passiveTime),
152 lastCashAddTime(property.lastCashAddTime),
153 freeMb(property.freeMb),
154 lastActivityTime(property.lastActivityTime),
155 password(property.password),
156 passive(property.passive),
157 disabled(property.disabled),
158 disabledDetailStat(property.disabledDetailStat),
159 alwaysOnline(property.alwaysOnline),
160 tariffName(property.tariffName),
161 nextTariff(property.nextTariff),
162 address(property.address),
164 group(property.group),
165 email(property.email),
166 phone(property.phone),
167 realName(property.realName),
168 credit(property.credit),
169 creditExpire(property.creditExpire),
171 userdata0(property.userdata0),
172 userdata1(property.userdata1),
173 userdata2(property.userdata2),
174 userdata3(property.userdata3),
175 userdata4(property.userdata4),
176 userdata5(property.userdata5),
177 userdata6(property.userdata6),
178 userdata7(property.userdata7),
179 userdata8(property.userdata8),
180 userdata9(property.userdata9),
181 passiveNotifier(this),
182 tariffNotifier(this),
195 lastWriteStat = u.lastWriteStat;
196 lastWriteDeatiledStat = u.lastWriteDeatiledStat;
198 settings = u.settings;
200 property.tariffName.AddBeforeNotifier(&tariffNotifier);
201 property.passive.AddBeforeNotifier(&passiveNotifier);
202 property.cash.AddBeforeNotifier(&cashNotifier);
203 currIP.AddAfterNotifier(&ipNotifier);
205 lastScanMessages = 0;
207 property.SetProperties(u.property);
209 pthread_mutexattr_t attr;
210 pthread_mutexattr_init(&attr);
211 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
212 pthread_mutex_init(&mutex, &attr);
214 //-----------------------------------------------------------------------------
217 property.passive.DelBeforeNotifier(&passiveNotifier);
218 property.tariffName.DelBeforeNotifier(&tariffNotifier);
219 pthread_mutex_destroy(&mutex);
221 //-----------------------------------------------------------------------------
222 void USER::SetLogin(string const & l)
224 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
225 assert(login.empty() && "Login is already set");
227 id = userIDGenerator.GetNextID();
229 //-----------------------------------------------------------------------------
232 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
235 if (store->RestoreUserConf(&conf, login))
237 WriteServLog("Cannot read conf for user %s.", login.c_str());
238 WriteServLog("%s", store->GetStrError().c_str());
239 printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str());
240 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
244 property.SetConf(conf);
246 tariff = tariffs->FindByName(tariffName);
249 WriteServLog("Cannot read user %s. Tariff %s not exist.",
250 login.c_str(), property.tariffName.Get().c_str());
254 std::vector<STG_MSG_HDR> hdrsList;
256 if (store->GetMessageHdrs(&hdrsList, login))
258 printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
262 std::vector<STG_MSG_HDR>::const_iterator it;
263 for (it = hdrsList.begin(); it != hdrsList.end(); ++it)
266 if (store->GetMessage(it->id, &msg, login) == 0)
268 messages.push_back(msg);
274 //-----------------------------------------------------------------------------
277 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
280 if (store->RestoreUserStat(&stat, login))
282 WriteServLog("Cannot read stat for user %s.", login.c_str());
283 WriteServLog("%s", store->GetStrError().c_str());
284 printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str());
285 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
289 property.SetStat(stat);
293 //-----------------------------------------------------------------------------
294 int USER::WriteConf()
296 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
297 USER_CONF conf(property.GetConf());
299 printfd(__FILE__, "USER::WriteConf()\n");
301 if (store->SaveUserConf(conf, login))
303 WriteServLog("Cannot write conf for user %s.", login.c_str());
304 WriteServLog("%s", store->GetStrError().c_str());
305 printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str());
306 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
312 //-----------------------------------------------------------------------------
313 int USER::WriteStat()
315 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
316 USER_STAT stat(property.GetStat());
318 printfd(__FILE__, "USER::WriteStat()\n");
320 if (store->SaveUserStat(stat, login))
322 WriteServLog("Cannot write stat for user %s.", login.c_str());
323 WriteServLog("%s", store->GetStrError().c_str());
324 printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str());
325 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
329 lastWriteStat = stgTime;
333 //-----------------------------------------------------------------------------
334 int USER::WriteMonthStat()
336 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
337 time_t tt = stgTime - 3600;
338 struct tm * t1 = localtime(&tt);
340 USER_STAT stat(property.GetStat());
341 if (store->SaveMonthStat(stat, t1->tm_mon, t1->tm_year, login))
343 WriteServLog("Cannot write month stat for user %s.", login.c_str());
344 WriteServLog("%s", store->GetStrError().c_str());
345 printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str());
346 printfd(__FILE__, "%s\n", store->GetStrError().c_str());
352 //-----------------------------------------------------------------------------
353 int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth)
355 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
357 * Authorize user. It only means that user will be authorized. Nothing more.
358 * User can be connected or disconnected while authorized.
359 * Example: user is authorized but disconnected due to 0 money or blocking
363 * Prevent double authorization by identical authorizers
365 if (authorizedBy.find(auth) != authorizedBy.end())
371 for (int i = 0; i < DIR_NUM; i++)
373 enabledDirs[i] = dirs & (1 << i);
376 if (authorizedBy.size())
380 // We are already authorized, but with different IP address
381 errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip);
385 map<uint32_t, user_iter>::const_iterator ci = ipIndex->find(ip);
386 if (ci != ipIndex->end())
388 // Address is already present in IP-index
389 // If it's not our IP - throw an error
390 if (&(*ci->second) != this)
392 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
399 if (ipIndex->find(ip) != ipIndex->end())
401 // Address is already present in IP-index
402 errorStr = "IP address " + inet_ntostring(ip) + " alredy in use";
406 if (ips.ConstData().IsIPInIPS(ip))
409 lastIPForDisconnect = currIP;
413 printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str());
414 errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login;
419 authorizedBy.insert(auth);
425 //-----------------------------------------------------------------------------
426 void USER::Unauthorize(const BASE_AUTH * auth)
428 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
430 * Authorizer tries to unauthorize user, that was not authorized by it
432 if (!authorizedBy.erase(auth))
435 if (authorizedBy.empty())
437 lastIPForDisconnect = currIP;
438 currIP = 0; // DelUser in traffcounter
442 //-----------------------------------------------------------------------------
443 bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const
445 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
446 // Is this user authorized by specified authorizer?
447 return authorizedBy.find(auth) != authorizedBy.end();
449 //-----------------------------------------------------------------------------
450 void USER::Connect(bool fakeConnect)
453 * Connect user to Internet. This function is differ from Authorize() !!!
456 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
460 string scriptOnConnect = settings->GetScriptDir() + "/OnConnect";
462 if (access(scriptOnConnect.c_str(), X_OK) == 0)
464 char dirsStr[DIR_NUM + 1];
465 dirsStr[DIR_NUM] = 0;
466 for (int i = 0; i < DIR_NUM; i++)
468 dirsStr[i] = enabledDirs[i] ? '1' : '0';
471 string scriptOnConnectParams;
472 strprintf(&scriptOnConnectParams,
473 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
474 scriptOnConnect.c_str(),
476 inet_ntostring(currIP).c_str(),
481 ScriptExec(scriptOnConnectParams);
485 WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str());
491 if (store->WriteUserConnect(login, currIP))
493 WriteServLog("Cannot write connect for user %s.", login.c_str());
494 WriteServLog("%s", store->GetStrError().c_str());
498 lastIPForDisconnect = currIP;
500 //-----------------------------------------------------------------------------
501 void USER::Disconnect(bool fakeDisconnect, const std::string & reason)
504 * Disconnect user from Internet. This function is differ from UnAuthorize() !!!
507 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
509 if (!lastIPForDisconnect)
511 printfd(__FILE__, "lastIPForDisconnect\n");
517 string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect";
519 if (access(scriptOnDisonnect.c_str(), X_OK) == 0)
521 char dirsStr[DIR_NUM + 1];
522 dirsStr[DIR_NUM] = 0;
523 for (int i = 0; i < DIR_NUM; i++)
525 dirsStr[i] = enabledDirs[i] ? '1' : '0';
528 string scriptOnDisonnectParams;
529 strprintf(&scriptOnDisonnectParams,
530 "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"",
531 scriptOnDisonnect.c_str(),
533 inet_ntostring(lastIPForDisconnect).c_str(),
538 ScriptExec(scriptOnDisonnectParams);
542 WriteServLog("Script OnDisconnect cannot be executed. File not found.");
548 if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason))
550 WriteServLog("Cannot write disconnect for user %s.", login.c_str());
551 WriteServLog("%s", store->GetStrError().c_str());
555 lastIPForDisconnect = 0;
557 DIR_TRAFF zeroSesssion;
559 sessionUpload = zeroSesssion;
560 sessionDownload = zeroSesssion;
562 //-----------------------------------------------------------------------------
563 void USER::PrintUser() const
566 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
567 cout << "============================================================" << endl;
568 cout << "id=" << id << endl;
569 cout << "login=" << login << endl;
570 cout << "password=" << password << endl;
571 cout << "passive=" << passive << endl;
572 cout << "disabled=" << disabled << endl;
573 cout << "disabledDetailStat=" << disabledDetailStat << endl;
574 cout << "alwaysOnline=" << alwaysOnline << endl;
575 cout << "tariffName=" << tariffName << endl;
576 cout << "address=" << address << endl;
577 cout << "phone=" << phone << endl;
578 cout << "email=" << email << endl;
579 cout << "note=" << note << endl;
580 cout << "realName=" <<realName << endl;
581 cout << "group=" << group << endl;
582 cout << "credit=" << credit << endl;
583 cout << "nextTariff=" << nextTariff << endl;
584 cout << "userdata0" << userdata0 << endl;
585 cout << "userdata1" << userdata1 << endl;
586 cout << "creditExpire=" << creditExpire << endl;
587 cout << "ips=" << ips << endl;
588 cout << "------------------------" << endl;
589 cout << "up=" << up << endl;
590 cout << "down=" << down << endl;
591 cout << "cash=" << cash << endl;
592 cout << "freeMb=" << freeMb << endl;
593 cout << "lastCashAdd=" << lastCashAdd << endl;
594 cout << "lastCashAddTime=" << lastCashAddTime << endl;
595 cout << "passiveTime=" << passiveTime << endl;
596 cout << "lastActivityTime=" << lastActivityTime << endl;
597 cout << "============================================================" << endl;
599 //-----------------------------------------------------------------------------
602 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
604 if (stgTime > static_cast<time_t>(lastWriteStat + settings->GetStatWritePeriod()))
606 printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str());
609 if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime)
611 WriteServLog("User: %s. Credit expired.", login.c_str());
617 if (passive.ConstData()
618 && (stgTime % 30 == 0)
619 && (passiveTime.ModificationTime() != stgTime))
621 passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime());
622 printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData());
625 if (!authorizedBy.empty())
629 lastActivityTime = *const_cast<time_t *>(&stgTime);
631 if (!connected && IsInetable())
635 if (connected && !IsInetable())
638 Disconnect(false, "disabled");
640 Disconnect(false, "passive");
642 Disconnect(false, "no cash");
645 if (stgTime - lastScanMessages > 10)
648 lastScanMessages = stgTime;
655 Disconnect(false, "not authorized");
660 //-----------------------------------------------------------------------------
661 void USER::UpdatePingTime(time_t t)
663 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
664 //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str());
670 //-----------------------------------------------------------------------------
671 bool USER::IsInetable()
673 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
675 if (disabled || passive)
678 if (settings->GetFreeMbAllowInet())
684 if (settings->GetShowFeeInCash())
686 return (cash >= -credit);
689 return (cash - tariff->GetFee() >= -credit);
691 //-----------------------------------------------------------------------------
692 string USER::GetEnabledDirs()
694 //STG_LOCKER lock(&mutex, __FILE__, __LINE__);
697 for(int i = 0; i < DIR_NUM; i++)
698 dirs += enabledDirs[i] ? "1" : "0";
701 //-----------------------------------------------------------------------------
702 #ifdef TRAFF_STAT_WITH_PORTS
703 void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len)
705 void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len)
708 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
716 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
717 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
721 int tt = tariff->GetTraffType();
722 if (tt == TRAFF_UP ||
723 tt == TRAFF_UP_DOWN ||
724 // Check NEW traff data
725 (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir]))
728 if (traff < threshold &&
729 traff + len >= threshold)
731 // cash = partBeforeThreshold * priceBeforeThreshold +
732 // partAfterThreshold * priceAfterThreshold
733 int64_t before = threshold - traff; // Chunk part before threshold
734 int64_t after = len - before; // Chunk part after threshold
735 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk
736 down.ConstData()[dir],
739 tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk
740 down.ConstData()[dir],
746 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
747 down.ConstData()[dir],
752 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
754 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
755 cost = dc - freeMb.ConstData();
757 // Direct access to internal data structures via friend-specifier
758 property.stat.freeMb -= dc;
759 property.stat.cash -= cost;
765 sessionUpload[dir] += len;
769 if (!settings->GetWriteFreeMbTraffCost() &&
770 freeMb.ConstData() >= 0)
773 #ifdef TRAFF_STAT_WITH_PORTS
774 IP_DIR_PAIR idp(ip, dir, port);
776 IP_DIR_PAIR idp(ip, dir);
779 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
780 lb = traffStat.lower_bound(idp);
781 if (lb == traffStat.end() || lb->first != idp)
784 pair<IP_DIR_PAIR, STAT_NODE>(idp,
785 STAT_NODE(len, 0, cost)));
789 lb->second.cash += cost;
790 lb->second.up += len;
793 //-----------------------------------------------------------------------------
794 #ifdef TRAFF_STAT_WITH_PORTS
795 void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len)
797 void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len)
800 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
808 int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]);
809 int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024;
813 int tt = tariff->GetTraffType();
814 if (tt == TRAFF_DOWN ||
815 tt == TRAFF_UP_DOWN ||
816 // Check NEW traff data
817 (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir]))
820 if (traff < threshold &&
821 traff + len >= threshold)
823 // cash = partBeforeThreshold * priceBeforeThreshold +
824 // partAfterThreshold * priceAfterThreshold
825 int64_t before = threshold - traff; // Chunk part before threshold
826 int64_t after = len - before; // Chunk part after threshold
827 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
828 down.ConstData()[dir], // Traff before chunk
831 tariff->GetPriceWithTraffType(up.ConstData()[dir],
832 dt[dir], // Traff after chunk
838 dc = tariff->GetPriceWithTraffType(up.ConstData()[dir],
839 down.ConstData()[dir],
844 if (freeMb.ConstData() <= 0) // FreeMb is exhausted
846 else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted
847 cost = dc - freeMb.ConstData();
849 property.stat.freeMb -= dc;
850 property.stat.cash -= cost;
856 sessionDownload[dir] += len;
860 if (!settings->GetWriteFreeMbTraffCost() &&
861 freeMb.ConstData() >= 0)
864 #ifdef TRAFF_STAT_WITH_PORTS
865 IP_DIR_PAIR idp(ip, dir, port);
867 IP_DIR_PAIR idp(ip, dir);
870 map<IP_DIR_PAIR, STAT_NODE>::iterator lb;
871 lb = traffStat.lower_bound(idp);
872 if (lb == traffStat.end() || lb->first != idp)
875 pair<IP_DIR_PAIR, STAT_NODE>(idp,
876 STAT_NODE(0, len, cost)));
880 lb->second.cash += cost;
881 lb->second.down += len;
884 //-----------------------------------------------------------------------------
885 void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
887 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
888 currIP.AddBeforeNotifier(n);
890 //-----------------------------------------------------------------------------
891 void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
893 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
894 currIP.DelBeforeNotifier(n);
896 //-----------------------------------------------------------------------------
897 void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
899 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
900 currIP.AddAfterNotifier(n);
902 //-----------------------------------------------------------------------------
903 void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
905 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
906 currIP.DelAfterNotifier(n);
908 //-----------------------------------------------------------------------------
911 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
913 string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd";
915 if (access(scriptOnAdd.c_str(), X_OK) == 0)
917 string scriptOnAddParams;
918 strprintf(&scriptOnAddParams,
923 ScriptExec(scriptOnAddParams);
927 WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str());
930 //-----------------------------------------------------------------------------
931 void USER::OnDelete()
933 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
935 string scriptOnDel = settings->GetScriptDir() + "/OnUserDel";
937 if (access(scriptOnDel.c_str(), X_OK) == 0)
939 string scriptOnDelParams;
940 strprintf(&scriptOnDelParams,
945 ScriptExec(scriptOnDelParams);
949 WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str());
954 //-----------------------------------------------------------------------------
955 int USER::WriteDetailStat(bool hard)
957 printfd(__FILE__, "USER::WriteDetailedStat() - saved size = %d\n", traffStatSaved.second.size());
959 if (!traffStatSaved.second.empty())
961 if (store->WriteDetailedStat(traffStatSaved.second, traffStatSaved.first, login))
963 printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n");
964 WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatSaved.second.size(), login.c_str());
965 WriteServLog("%s", store->GetStrError().c_str());
968 traffStatSaved.second.erase(traffStatSaved.second.begin(), traffStatSaved.second.end());
974 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
978 printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size());
980 if (ts.size() && !disabledDetailStat)
982 if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login))
984 printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n");
985 WriteServLog("Cannot write detail stat for user %s.", login.c_str());
986 WriteServLog("%s", store->GetStrError().c_str());
989 printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n");
990 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
991 traffStatSaved.second.swap(ts);
992 traffStatSaved.first = lastWriteDeatiledStat;
997 lastWriteDeatiledStat = stgTime;
1000 //-----------------------------------------------------------------------------
1001 double USER::GetPassiveTimePart() const
1003 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1005 static int daysInMonth[12] =
1006 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
1010 tms = localtime(&t);
1012 time_t secMonth = daysInMonth[(tms->tm_mon + 11) % 12] * 24 * 3600; // Previous month
1014 if (tms->tm_year % 4 == 0 && tms->tm_mon == 1)
1017 secMonth += 24 * 3600;
1020 int dt = secMonth - passiveTime;
1025 return double(dt) / (secMonth);
1027 //-----------------------------------------------------------------------------
1028 void USER::SetPassiveTimeAsNewUser()
1030 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1036 int daysCurrMon = DaysInCurrentMonth();
1037 double pt = (tm->tm_mday - 1) / (double)daysCurrMon;
1039 passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon);
1041 //-----------------------------------------------------------------------------
1042 void USER::MidnightResetSessionStat()
1044 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1048 Disconnect(true, "fake");
1052 //-----------------------------------------------------------------------------
1053 void USER::ProcessNewMonth()
1055 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1059 Disconnect(true, "fake");
1061 DIR_TRAFF zeroTarff;
1074 if (nextTariff.ConstData() != "")
1077 nt = tariffs->FindByName(nextTariff);
1080 WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.",
1081 login.c_str(), property.tariffName.Get().c_str());
1085 property.tariffName.Set(nextTariff, sysAdmin, login, store);
1092 //-----------------------------------------------------------------------------
1093 void USER::ProcessDayFeeSpread()
1095 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1097 if (passive.ConstData())
1100 double f = tariff->GetFee() / DaysInCurrentMonth();
1106 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1109 //-----------------------------------------------------------------------------
1110 void USER::ProcessDayFee()
1112 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1114 double passiveTimePart = 1.0;
1115 if (!settings->GetFullFee())
1117 passiveTimePart = GetPassiveTimePart();
1121 if (passive.ConstData())
1123 printfd(__FILE__, "Don't charge fee `cause we are passive\n");
1127 double f = tariff->GetFee() * passiveTimePart;
1135 printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n",
1140 property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge");
1142 //-----------------------------------------------------------------------------
1143 void USER::SetPrepaidTraff()
1145 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1147 property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic");
1149 //-----------------------------------------------------------------------------
1150 int USER::AddMessage(STG_MSG * msg)
1152 STG_LOCKER lock(&mutex, __FILE__, __LINE__);
1154 if (SendMessage(*msg))
1156 if (store->AddMessage(msg, login))
1158 errorStr = store->GetStrError();
1159 WriteServLog("Error adding message: '%s'", errorStr.c_str());
1160 printfd(__FILE__, "Error adding message: '%s'\n", errorStr.c_str());
1163 messages.push_back(*msg);
1167 if (msg->header.repeat > 0)
1169 msg->header.repeat--;
1171 //TODO: gcc v. 4.x generate ICE on x86_64
1172 msg->header.lastSendTime = time(NULL);
1174 msg->header.lastSendTime = stgTime;
1176 if (store->AddMessage(msg, login))
1178 errorStr = store->GetStrError();
1179 WriteServLog("Error adding repeatable message: '%s'", errorStr.c_str());
1180 printfd(__FILE__, "Error adding repeatable message: '%s'\n", errorStr.c_str());
1183 messages.push_back(*msg);
1188 //-----------------------------------------------------------------------------
1189 int USER::SendMessage(STG_MSG & msg) const
1191 // No lock `cause we are already locked from caller
1193 set<const BASE_AUTH*>::iterator it(authorizedBy.begin());
1194 while (it != authorizedBy.end())
1196 if (!(*it++)->SendMessage(msg, currIP))
1202 //TODO: gcc v. 4.x generate ICE on x86_64
1203 msg.header.lastSendTime = time(NULL);
1205 msg.header.lastSendTime = stgTime;
1207 msg.header.repeat--;
1211 //-----------------------------------------------------------------------------
1212 void USER::ScanMessage()
1214 // No lock `cause we are already locked from caller
1215 // We need not check for the authorizedBy `cause it has already checked by caller
1217 std::list<STG_MSG>::iterator it(messages.begin());
1218 while (it != messages.end())
1220 if (settings->GetMessageTimeout() > 0 &&
1221 difftime(stgTime, it->header.creationTime) > settings->GetMessageTimeout())
1224 if (store->DelMessage(it->header.id, login))
1226 WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str());
1227 printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str());
1229 messages.erase(it++);
1232 if (it->GetNextSendTime() <= stgTime)
1234 if (SendMessage(*it))
1236 // We need to check all messages in queue for timeout
1240 if (it->header.repeat < 0)
1242 if (store->DelMessage(it->header.id, login))
1244 WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str());
1245 printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str());
1247 messages.erase(it++);
1251 if (store->EditMessage(*it, login))
1253 WriteServLog("Error modifying message: '%s'", store->GetStrError().c_str());
1254 printfd(__FILE__, "Error modifying message: '%s'\n", store->GetStrError().c_str());
1261 //-----------------------------------------------------------------------------
1262 //-----------------------------------------------------------------------------
1263 //-----------------------------------------------------------------------------
1264 void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive)
1266 if (newPassive && !oldPassive)
1267 user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(),
1273 //-----------------------------------------------------------------------------
1274 void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff)
1276 user->tariff = user->tariffs->FindByName(newTariff);
1278 //-----------------------------------------------------------------------------
1279 void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash)
1281 user->lastCashAddTime = *const_cast<time_t *>(&stgTime);
1282 user->lastCashAdd = newCash - oldCash;
1284 //-----------------------------------------------------------------------------
1285 void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to)
1287 printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str());
1289 if (user->connected)
1290 user->Disconnect(false, "Change IP");
1292 if (user->IsInetable())
1293 user->Connect(false);
1295 //-----------------------------------------------------------------------------