X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/43d188bd1622464192974dc98f756f59a8ec02fe..ebe4af54bde52ca8182e97a3dc8d25449b9c1dbc:/projects/stargazer/user_impl.cpp diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp index 34c922b2..79321987 100644 --- a/projects/stargazer/user_impl.cpp +++ b/projects/stargazer/user_impl.cpp @@ -32,11 +32,9 @@ #define _GNU_SOURCE #endif -#include -#include // access - -#include -#include +#include "user_impl.h" +#include "settings_impl.h" +#include "stg_timer.h" #include "stg/users.h" #include "stg/common.h" @@ -44,22 +42,31 @@ #include "stg/tariff.h" #include "stg/tariffs.h" #include "stg/admin.h" -#include "user_impl.h" -#include "settings_impl.h" -USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s, +#include +#include + +#include +#include +#include + +#include +#include // access + +#ifdef USE_ABSTRACT_SETTINGS +USER_IMPL::USER_IMPL(const SETTINGS * s, const STORE * st, const TARIFFS * t, const ADMIN * a, const USERS * u) - : users(u), + : USER(), + users(u), property(s->GetScriptsDir()), WriteServLog(GetStgLogger()), - login(), + lastScanMessages(0), id(0), __connected(0), connected(__connected), - userIDGenerator(), __currIP(0), currIP(__currIP), lastIPForDisconnect(0), @@ -67,7 +74,12 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s, sysAdmin(a), store(st), tariffs(t), - tariff(tariffs->GetNoTariff()), + tariff(NULL), + settings(s), + authorizedModificationTime(0), + deleted(false), + lastWriteStat(0), + lastWriteDetailedStat(0), cash(property.cash), up(property.up), down(property.down), @@ -103,42 +115,125 @@ USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s, userdata8(property.userdata8), userdata9(property.userdata9), passiveNotifier(this), + disabledNotifier(this), tariffNotifier(this), cashNotifier(this), ipNotifier(this) { -settings = s; - password = "*_EMPTY_PASSWORD_*"; tariffName = NO_TARIFF_NAME; -connected = 0; -tariff = tariffs->GetNoTariff(); ips = StrToIPS("*"); -deleted = false; lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); lastWriteDetailedStat = stgTime; property.tariffName.AddBeforeNotifier(&tariffNotifier); property.passive.AddBeforeNotifier(&passiveNotifier); +property.disabled.AddAfterNotifier(&disabledNotifier); property.cash.AddBeforeNotifier(&cashNotifier); ips.AddAfterNotifier(&ipNotifier); -lastScanMessages = 0; +pthread_mutexattr_t attr; +pthread_mutexattr_init(&attr); +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +pthread_mutex_init(&mutex, &attr); +} +#else +USER_IMPL::USER_IMPL(const SETTINGS_IMPL * s, + const STORE * st, + const TARIFFS * t, + const ADMIN * a, + const USERS * u) + : USER(), + users(u), + property(s->GetScriptsDir()), + WriteServLog(GetStgLogger()), + lastScanMessages(0), + id(0), + __connected(0), + connected(__connected), + __currIP(0), + currIP(__currIP), + lastIPForDisconnect(0), + pingTime(0), + sysAdmin(a), + store(st), + tariffs(t), + tariff(NULL), + settings(s), + authorizedModificationTime(0), + deleted(false), + lastWriteStat(0), + lastWriteDetailedStat(0), + cash(property.cash), + up(property.up), + down(property.down), + lastCashAdd(property.lastCashAdd), + passiveTime(property.passiveTime), + lastCashAddTime(property.lastCashAddTime), + freeMb(property.freeMb), + lastActivityTime(property.lastActivityTime), + password(property.password), + passive(property.passive), + disabled(property.disabled), + disabledDetailStat(property.disabledDetailStat), + alwaysOnline(property.alwaysOnline), + tariffName(property.tariffName), + nextTariff(property.nextTariff), + address(property.address), + note(property.note), + group(property.group), + email(property.email), + phone(property.phone), + realName(property.realName), + credit(property.credit), + creditExpire(property.creditExpire), + ips(property.ips), + userdata0(property.userdata0), + userdata1(property.userdata1), + userdata2(property.userdata2), + userdata3(property.userdata3), + userdata4(property.userdata4), + userdata5(property.userdata5), + userdata6(property.userdata6), + userdata7(property.userdata7), + userdata8(property.userdata8), + userdata9(property.userdata9), + passiveNotifier(this), + disabledNotifier(this), + tariffNotifier(this), + cashNotifier(this), + ipNotifier(this) +{ +password = "*_EMPTY_PASSWORD_*"; +tariffName = NO_TARIFF_NAME; +ips = StrToIPS("*"); +lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); +lastWriteDetailedStat = stgTime; + +property.tariffName.AddBeforeNotifier(&tariffNotifier); +property.passive.AddBeforeNotifier(&passiveNotifier); +property.disabled.AddAfterNotifier(&disabledNotifier); +property.cash.AddBeforeNotifier(&cashNotifier); +ips.AddAfterNotifier(&ipNotifier); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutex, &attr); } +#endif //----------------------------------------------------------------------------- USER_IMPL::USER_IMPL(const USER_IMPL & u) - : users(u.users), + : USER(), + users(u.users), property(u.settings->GetScriptsDir()), WriteServLog(GetStgLogger()), + lastScanMessages(0), login(u.login), id(u.id), - __connected(u.__connected), + __connected(0), connected(__connected), + userIDGenerator(u.userIDGenerator), __currIP(u.__currIP), currIP(__currIP), lastIPForDisconnect(0), @@ -147,6 +242,14 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u) store(u.store), tariffs(u.tariffs), tariff(u.tariff), + traffStat(u.traffStat), + traffStatSaved(u.traffStatSaved), + settings(u.settings), + authorizedModificationTime(u.authorizedModificationTime), + messages(u.messages), + deleted(u.deleted), + lastWriteStat(u.lastWriteStat), + lastWriteDetailedStat(u.lastWriteDetailedStat), cash(property.cash), up(property.up), down(property.down), @@ -181,7 +284,10 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u) userdata7(property.userdata7), userdata8(property.userdata8), userdata9(property.userdata9), + sessionUpload(), + sessionDownload(), passiveNotifier(this), + disabledNotifier(this), tariffNotifier(this), cashNotifier(this), ipNotifier(this) @@ -189,22 +295,12 @@ USER_IMPL::USER_IMPL(const USER_IMPL & u) if (&u == this) return; -connected = 0; - -deleted = u.deleted; - -lastWriteStat = u.lastWriteStat; -lastWriteDetailedStat = u.lastWriteDetailedStat; - -settings = u.settings; - property.tariffName.AddBeforeNotifier(&tariffNotifier); property.passive.AddBeforeNotifier(&passiveNotifier); +property.disabled.AddAfterNotifier(&disabledNotifier); property.cash.AddBeforeNotifier(&cashNotifier); ips.AddAfterNotifier(&ipNotifier); -lastScanMessages = 0; - property.SetProperties(u.property); pthread_mutexattr_t attr; @@ -215,14 +311,16 @@ pthread_mutex_init(&mutex, &attr); //----------------------------------------------------------------------------- USER_IMPL::~USER_IMPL() { -property.passive.DelBeforeNotifier(&passiveNotifier); property.tariffName.DelBeforeNotifier(&tariffNotifier); +property.passive.DelBeforeNotifier(&passiveNotifier); +property.disabled.DelAfterNotifier(&disabledNotifier); +property.cash.DelBeforeNotifier(&cashNotifier); pthread_mutex_destroy(&mutex); } //----------------------------------------------------------------------------- -void USER_IMPL::SetLogin(string const & l) +void USER_IMPL::SetLogin(const std::string & l) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); assert(login.empty() && "Login is already set"); login = l; id = userIDGenerator.GetNextID(); @@ -230,7 +328,7 @@ id = userIDGenerator.GetNextID(); //----------------------------------------------------------------------------- int USER_IMPL::ReadConf() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_CONF conf; if (store->RestoreUserConf(&conf, login)) @@ -257,6 +355,9 @@ std::vector hdrsList; if (store->GetMessageHdrs(&hdrsList, login)) { printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str()); + WriteServLog("Cannot read user %s. Error reading message headers: %s.", + login.c_str(), + store->GetStrError().c_str()); return -1; } @@ -275,7 +376,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::ReadStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_STAT stat; if (store->RestoreUserStat(&stat, login)) @@ -294,7 +395,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteConf() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_CONF conf(property.GetConf()); printfd(__FILE__, "USER::WriteConf()\n"); @@ -313,7 +414,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); USER_STAT stat(property.GetStat()); if (store->SaveUserStat(stat, login)) @@ -332,7 +433,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::WriteMonthStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); time_t tt = stgTime - 3600; struct tm t1; localtime_r(&tt, &t1); @@ -352,7 +453,7 @@ return 0; //----------------------------------------------------------------------------- int USER_IMPL::Authorize(uint32_t ip, uint32_t dirs, const AUTH * auth) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); /* * Authorize user. It only means that user will be authorized. Nothing more. * User can be connected or disconnected while authorized. @@ -373,7 +474,7 @@ for (int i = 0; i < DIR_NUM; i++) enabledDirs[i] = dirs & (1 << i); } -if (authorizedBy.size()) +if (!authorizedBy.empty()) { if (currIP != ip) { @@ -416,6 +517,8 @@ else } } +if (authorizedBy.empty()) + authorizedModificationTime = stgTime; authorizedBy.insert(auth); ScanMessage(); @@ -423,9 +526,9 @@ ScanMessage(); return 0; } //----------------------------------------------------------------------------- -void USER_IMPL::Unauthorize(const AUTH * auth) +void USER_IMPL::Unauthorize(const AUTH * auth, const std::string & reason) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); /* * Authorizer tries to unauthorize user, that was not authorized by it */ @@ -434,6 +537,8 @@ if (!authorizedBy.erase(auth)) if (authorizedBy.empty()) { + authorizedModificationTime = stgTime; + lastDisconnectReason = reason; lastIPForDisconnect = currIP; currIP = 0; // DelUser in traffcounter return; @@ -442,22 +547,29 @@ if (authorizedBy.empty()) //----------------------------------------------------------------------------- bool USER_IMPL::IsAuthorizedBy(const AUTH * auth) const { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); // Is this user authorized by specified authorizer? return authorizedBy.find(auth) != authorizedBy.end(); } //----------------------------------------------------------------------------- +std::vector USER_IMPL::GetAuthorizers() const +{ + std::vector list; + std::transform(authorizedBy.begin(), authorizedBy.end(), std::back_inserter(list), std::mem_fun(&AUTH::GetVersion)); + return list; +} +//----------------------------------------------------------------------------- void USER_IMPL::Connect(bool fakeConnect) { /* * Connect user to Internet. This function is differ from Authorize() !!! */ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!fakeConnect) { - string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect"; + std::string scriptOnConnect = settings->GetScriptsDir() + "/OnConnect"; if (access(scriptOnConnect.c_str(), X_OK) == 0) { @@ -468,17 +580,25 @@ if (!fakeConnect) dirsStr[i] = enabledDirs[i] ? '1' : '0'; } - string scriptOnConnectParams; + std::string scriptOnConnectParams; + strprintf(&scriptOnConnectParams, "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", scriptOnConnect.c_str(), login.c_str(), inet_ntostring(currIP).c_str(), - (double)cash, + cash.ConstData(), id, dirsStr); - ScriptExec(scriptOnConnectParams); + std::vector::const_iterator it(settings->GetScriptParams().begin()); + while (it != settings->GetScriptParams().end()) + { + scriptOnConnectParams += " \"" + GetParamValue(it->c_str()) + "\""; + ++it; + } + + ScriptExec(scriptOnConnectParams.c_str()); } else { @@ -504,7 +624,7 @@ void USER_IMPL::Disconnect(bool fakeDisconnect, const std::string & reason) * Disconnect user from Internet. This function is differ from UnAuthorize() !!! */ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (!lastIPForDisconnect) { @@ -514,7 +634,8 @@ if (!lastIPForDisconnect) if (!fakeDisconnect) { - string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect"; + lastDisconnectReason = reason; + std::string scriptOnDisonnect = settings->GetScriptsDir() + "/OnDisconnect"; if (access(scriptOnDisonnect.c_str(), X_OK) == 0) { @@ -525,17 +646,24 @@ if (!fakeDisconnect) dirsStr[i] = enabledDirs[i] ? '1' : '0'; } - string scriptOnDisonnectParams; + std::string scriptOnDisonnectParams; strprintf(&scriptOnDisonnectParams, "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", scriptOnDisonnect.c_str(), login.c_str(), inet_ntostring(lastIPForDisconnect).c_str(), - (double)cash, + cash.ConstData(), id, dirsStr); - ScriptExec(scriptOnDisonnectParams); + std::vector::const_iterator it(settings->GetScriptParams().begin()); + while (it != settings->GetScriptParams().end()) + { + scriptOnDisonnectParams += " \"" + GetParamValue(it->c_str()) + "\""; + ++it; + } + + ScriptExec(scriptOnDisonnectParams.c_str()); } else { @@ -545,7 +673,12 @@ if (!fakeDisconnect) connected = false; } -if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason)) +std::string reasonMessage(reason); +if (!lastDisconnectReason.empty()) + reasonMessage += ": " + lastDisconnectReason; + +if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, + cash, freeMb, reasonMessage)) { WriteServLog("Cannot write disconnect for user %s.", login.c_str()); WriteServLog("%s", store->GetStrError().c_str()); @@ -558,48 +691,50 @@ DIR_TRAFF zeroSesssion; sessionUpload = zeroSesssion; sessionDownload = zeroSesssion; +sessionUploadModTime = stgTime; +sessionDownloadModTime = stgTime; } //----------------------------------------------------------------------------- void USER_IMPL::PrintUser() const { //return; -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -cout << "============================================================" << endl; -cout << "id=" << id << endl; -cout << "login=" << login << endl; -cout << "password=" << password << endl; -cout << "passive=" << passive << endl; -cout << "disabled=" << disabled << endl; -cout << "disabledDetailStat=" << disabledDetailStat << endl; -cout << "alwaysOnline=" << alwaysOnline << endl; -cout << "tariffName=" << tariffName << endl; -cout << "address=" << address << endl; -cout << "phone=" << phone << endl; -cout << "email=" << email << endl; -cout << "note=" << note << endl; -cout << "realName=" < static_cast(lastWriteStat + settings->GetStatWritePeriod())) { @@ -660,7 +795,7 @@ else //----------------------------------------------------------------------------- void USER_IMPL::UpdatePingTime(time_t t) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); //printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str()); if (t) pingTime = t; @@ -670,7 +805,7 @@ else //----------------------------------------------------------------------------- bool USER_IMPL::IsInetable() { -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//STG_LOCKER lock(&mutex); if (disabled || passive) return false; @@ -681,7 +816,7 @@ if (settings->GetFreeMbAllowInet()) return true; } -if (settings->GetShowFeeInCash()) +if (settings->GetShowFeeInCash() || tariff == NULL) { return (cash >= -credit); } @@ -689,11 +824,11 @@ if (settings->GetShowFeeInCash()) return (cash - tariff->GetFee() >= -credit); } //----------------------------------------------------------------------------- -string USER_IMPL::GetEnabledDirs() +std::string USER_IMPL::GetEnabledDirs() const { -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//STG_LOCKER lock(&mutex); -string dirs = ""; +std::string dirs = ""; for(int i = 0; i < DIR_NUM; i++) dirs += enabledDirs[i] ? "1" : "0"; return dirs; @@ -705,9 +840,9 @@ void USER_IMPL::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) void USER_IMPL::AddTraffStatU(int dir, uint32_t ip, uint32_t len) #endif { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); -if (!connected) +if (!connected || tariff == NULL) return; double cost = 0; @@ -719,10 +854,10 @@ int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; dt[dir] += len; int tt = tariff->GetTraffType(); -if (tt == TRAFF_UP || - tt == TRAFF_UP_DOWN || +if (tt == TARIFF::TRAFF_UP || + tt == TARIFF::TRAFF_UP_DOWN || // Check NEW traff data - (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir])) + (tt == TARIFF::TRAFF_MAX && dt[dir] > down.ConstData()[dir])) { double dc = 0; if (traff < threshold && @@ -763,6 +898,7 @@ if (tt == TRAFF_UP || up = dt; sessionUpload[dir] += len; +sessionUploadModTime = stgTime; //Add detailed stat @@ -776,13 +912,13 @@ IP_DIR_PAIR idp(ip, dir, port); IP_DIR_PAIR idp(ip, dir); #endif -map::iterator lb; +std::map::iterator lb; lb = traffStat.lower_bound(idp); if (lb == traffStat.end() || lb->first != idp) { traffStat.insert(lb, - pair(idp, - STAT_NODE(len, 0, cost))); + std::make_pair(idp, + STAT_NODE(len, 0, cost))); } else { @@ -797,9 +933,9 @@ void USER_IMPL::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) void USER_IMPL::AddTraffStatD(int dir, uint32_t ip, uint32_t len) #endif { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); -if (!connected) +if (!connected || tariff == NULL) return; double cost = 0; @@ -811,10 +947,10 @@ int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; dt[dir] += len; int tt = tariff->GetTraffType(); -if (tt == TRAFF_DOWN || - tt == TRAFF_UP_DOWN || +if (tt == TARIFF::TRAFF_DOWN || + tt == TARIFF::TRAFF_UP_DOWN || // Check NEW traff data - (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) + (tt == TARIFF::TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) { double dc = 0; if (traff < threshold && @@ -854,6 +990,7 @@ if (tt == TRAFF_DOWN || down = dt; sessionDownload[dir] += len; +sessionDownloadModTime = stgTime; //Add detailed stat @@ -867,13 +1004,13 @@ IP_DIR_PAIR idp(ip, dir, port); IP_DIR_PAIR idp(ip, dir); #endif -map::iterator lb; +std::map::iterator lb; lb = traffStat.lower_bound(idp); if (lb == traffStat.end() || lb->first != idp) { traffStat.insert(lb, - pair(idp, - STAT_NODE(0, len, cost))); + std::make_pair(idp, + STAT_NODE(0, len, cost))); } else { @@ -882,69 +1019,69 @@ else } } //----------------------------------------------------------------------------- -void USER_IMPL::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::AddCurrIPBeforeNotifier(CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.AddBeforeNotifier(n); +STG_LOCKER lock(&mutex); +currIP.AddBeforeNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::DelCurrIPBeforeNotifier(const CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.DelBeforeNotifier(n); +STG_LOCKER lock(&mutex); +currIP.DelBeforeNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::AddCurrIPAfterNotifier(CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.AddAfterNotifier(n); +STG_LOCKER lock(&mutex); +currIP.AddAfterNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::DelCurrIPAfterNotifier(const CURR_IP_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.DelAfterNotifier(n); +STG_LOCKER lock(&mutex); +currIP.DelAfterNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::AddConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::AddConnectedBeforeNotifier(CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -connected.AddBeforeNotifier(n); +STG_LOCKER lock(&mutex); +connected.AddBeforeNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::DelConnectedBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::DelConnectedBeforeNotifier(const CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -connected.DelBeforeNotifier(n); +STG_LOCKER lock(&mutex); +connected.DelBeforeNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::AddConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::AddConnectedAfterNotifier(CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -connected.AddAfterNotifier(n); +STG_LOCKER lock(&mutex); +connected.AddAfterNotifier(notifier); } //----------------------------------------------------------------------------- -void USER_IMPL::DelConnectedAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +void USER_IMPL::DelConnectedAfterNotifier(const CONNECTED_NOTIFIER * notifier) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -connected.DelAfterNotifier(n); +STG_LOCKER lock(&mutex); +connected.DelAfterNotifier(notifier); } //----------------------------------------------------------------------------- void USER_IMPL::OnAdd() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); -string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd"; +std::string scriptOnAdd = settings->GetScriptsDir() + "/OnUserAdd"; if (access(scriptOnAdd.c_str(), X_OK) == 0) { - string scriptOnAddParams; + std::string scriptOnAddParams; strprintf(&scriptOnAddParams, "%s \"%s\"", scriptOnAdd.c_str(), login.c_str()); - ScriptExec(scriptOnAddParams); + ScriptExec(scriptOnAddParams.c_str()); } else { @@ -954,19 +1091,19 @@ else //----------------------------------------------------------------------------- void USER_IMPL::OnDelete() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); -string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel"; +std::string scriptOnDel = settings->GetScriptsDir() + "/OnUserDel"; if (access(scriptOnDel.c_str(), X_OK) == 0) { - string scriptOnDelParams; + std::string scriptOnDelParams; strprintf(&scriptOnDelParams, "%s \"%s\"", scriptOnDel.c_str(), login.c_str()); - ScriptExec(scriptOnDelParams); + ScriptExec(scriptOnDelParams.c_str()); } else { @@ -995,7 +1132,7 @@ if (!traffStatSaved.second.empty()) TRAFF_STAT ts; { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); + STG_LOCKER lock(&mutex); ts.swap(traffStat); } @@ -1011,7 +1148,7 @@ if (ts.size() && !disabledDetailStat) if (!hard) { printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n"); - STG_LOCKER lock(&mutex, __FILE__, __LINE__); + STG_LOCKER lock(&mutex); traffStatSaved.second.swap(ts); traffStatSaved.first = lastWriteDetailedStat; } @@ -1024,7 +1161,7 @@ return 0; //----------------------------------------------------------------------------- double USER_IMPL::GetPassiveTimePart() const { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); static int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -1041,30 +1178,31 @@ if (tms.tm_year % 4 == 0 && tms.tm_mon == 1) secMonth += 24 * 3600; } -int dt = secMonth - passiveTime; +time_t dt = secMonth - passiveTime; if (dt < 0) dt = 0; -return double(dt) / (secMonth); +return static_cast(dt) / secMonth; } //----------------------------------------------------------------------------- void USER_IMPL::SetPassiveTimeAsNewUser() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); time_t t = stgTime; struct tm tm; localtime_r(&t, &tm); int daysCurrMon = DaysInCurrentMonth(); -double pt = (tm.tm_mday - 1) / (double)daysCurrMon; +double pt = tm.tm_mday - 1; +pt /= daysCurrMon; -passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon); +passiveTime = static_cast(pt * 24 * 3600 * daysCurrMon); } //----------------------------------------------------------------------------- void USER_IMPL::MidnightResetSessionStat() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (connected) { @@ -1075,7 +1213,7 @@ if (connected) //----------------------------------------------------------------------------- void USER_IMPL::ProcessNewMonth() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); // Reset traff if (connected) { @@ -1106,7 +1244,7 @@ if (nextTariff.ConstData() != "") else { property.tariffName.Set(nextTariff, sysAdmin, login, store); - tariff = nt; + //tariff = nt; } ResetNextTariff(); WriteConf(); @@ -1115,24 +1253,50 @@ if (nextTariff.ConstData() != "") //----------------------------------------------------------------------------- void USER_IMPL::ProcessDayFeeSpread() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); + +if (passive.ConstData() || tariff == NULL) + return; -if (passive.ConstData()) +if (tariff->GetPeriod() != TARIFF::MONTH) return; -double f = tariff->GetFee() / DaysInCurrentMonth(); +double fee = tariff->GetFee() / DaysInCurrentMonth(); -if (f == 0.0) +if (std::fabs(fee) < 1.0e-3) return; double c = cash; -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 1: + if (c + credit >= 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 2: + if (c + credit >= fee) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 3: + if (c >= 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + } ResetPassiveTime(); } //----------------------------------------------------------------------------- void USER_IMPL::ProcessDayFee() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); + +if (tariff == NULL) + return; + +if (tariff->GetPeriod() != TARIFF::MONTH) + return; double passiveTimePart = 1.0; if (!settings->GetFullFee()) @@ -1147,32 +1311,96 @@ else return; } } -double f = tariff->GetFee() * passiveTimePart; +double fee = tariff->GetFee() * passiveTimePart; ResetPassiveTime(); -if (f == 0.0) +if (std::fabs(fee) < 1.0e-3) + { + SetPrepaidTraff(); return; + } double c = cash; -printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n", +printfd(__FILE__, "login: %8s Cash=%f Credit=%f Fee=%f PassiveTimePart=%f fee=%f\n", login.c_str(), + cash.ConstData(), + credit.ConstData(), tariff->GetFee(), passiveTimePart, - f); -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); + fee); +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + break; + case 1: + if (c + credit >= 0) + { + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + } + break; + case 2: + if (c + credit >= fee) + { + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + } + break; + case 3: + if (c >= 0) + { + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + SetPrepaidTraff(); + } + break; + } } //----------------------------------------------------------------------------- -void USER_IMPL::SetPrepaidTraff() +void USER_IMPL::ProcessDailyFee() { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); + +if (passive.ConstData() || tariff == NULL) + return; + +if (tariff->GetPeriod() != TARIFF::DAY) + return; + +double fee = tariff->GetFee(); + +if (fee == 0.0) + return; -property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); +double c = cash; +switch (settings->GetFeeChargeType()) + { + case 0: + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 1: + if (c + credit >= 0) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + case 2: + if (c + credit >= fee) + property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge"); + break; + } +ResetPassiveTime(); +} +//----------------------------------------------------------------------------- +void USER_IMPL::SetPrepaidTraff() +{ +if (tariff != NULL) + property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); } //----------------------------------------------------------------------------- int USER_IMPL::AddMessage(STG_MSG * msg) { -STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex); if (SendMessage(*msg)) { @@ -1192,9 +1420,9 @@ else msg->header.repeat--; #ifndef DEBUG //TODO: gcc v. 4.x generate ICE on x86_64 - msg->header.lastSendTime = time(NULL); + msg->header.lastSendTime = static_cast(time(NULL)); #else - msg->header.lastSendTime = stgTime; + msg->header.lastSendTime = static_cast(stgTime); #endif if (store->AddMessage(msg, login)) { @@ -1213,7 +1441,7 @@ int USER_IMPL::SendMessage(STG_MSG & msg) const { // No lock `cause we are already locked from caller int ret = -1; -set::iterator it(authorizedBy.begin()); +std::set::iterator it(authorizedBy.begin()); while (it != authorizedBy.end()) { if (!(*it++)->SendMessage(msg, currIP)) @@ -1223,9 +1451,9 @@ if (!ret) { #ifndef DEBUG //TODO: gcc v. 4.x generate ICE on x86_64 - msg.header.lastSendTime = time(NULL); + msg.header.lastSendTime = static_cast(time(NULL)); #else - msg.header.lastSendTime = stgTime; + msg.header.lastSendTime = static_cast(stgTime); #endif msg.header.repeat--; } @@ -1286,11 +1514,33 @@ while (it != messages.end()) } } //----------------------------------------------------------------------------- +std::string USER_IMPL::GetParamValue(const std::string & name) const +{ + std::string lowerName = ToLower(name); + if (lowerName == "id") + { + std::ostringstream stream; + stream << id; + return stream.str(); + } + if (lowerName == "login") return login; + if (lowerName == "currip") return currIP.ToString(); + if (lowerName == "enableddirs") return GetEnabledDirs(); + if (lowerName == "tariff") return property.tariffName; + if (property.Exists(lowerName)) + return property.GetPropertyValue(lowerName); + else + { + WriteServLog("User’s parameter '%s' does not exist.", name.c_str()); + return ""; + } +} +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive) { -if (newPassive && !oldPassive) +if (newPassive && !oldPassive && user->tariff != NULL) user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(), user->sysAdmin, user->login, @@ -1298,9 +1548,28 @@ if (newPassive && !oldPassive) "Freeze"); } //----------------------------------------------------------------------------- -void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff) +void CHG_DISABLED_NOTIFIER::Notify(const int & oldValue, const int & newValue) +{ +if (oldValue && !newValue && user->GetConnected()) + { + user->Disconnect(false, "disabled"); + } +else if (!oldValue && newValue && user->IsInetable()) + { + user->Connect(false); + } + +} +//----------------------------------------------------------------------------- +void CHG_TARIFF_NOTIFIER::Notify(const std::string &, const std::string & newTariff) { +if (user->settings->GetReconnectOnTariffChange() && user->connected) + user->Disconnect(false, "Change tariff"); user->tariff = user->tariffs->FindByName(newTariff); +if (user->settings->GetReconnectOnTariffChange() && + !user->authorizedBy.empty() && + user->IsInetable()) + user->Connect(false); } //----------------------------------------------------------------------------- void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash) @@ -1313,8 +1582,8 @@ void CHG_IPS_NOTIFIER::Notify(const USER_IPS & from, const USER_IPS & to) { printfd(__FILE__, "Change IP from '%s' to '%s'\n", from.GetIpStr().c_str(), to.GetIpStr().c_str()); if (user->connected) - user->Disconnect(true, "Change IP"); - if (user->IsInetable()) - user->Connect(true); + user->Disconnect(false, "Change IP"); + if (!user->authorizedBy.empty() && user->IsInetable()) + user->Connect(false); } //-----------------------------------------------------------------------------