From: Maxim Mamontov Date: Thu, 17 Mar 2011 10:24:14 +0000 (+0200) Subject: Break internal classes to interface and implementation X-Git-Tag: 2.407-rc3~157 X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/becf6dfe4fe2ecd43792aa53a302c5866483f306?ds=sidebyside Break internal classes to interface and implementation --- diff --git a/include/admin.h b/include/admin.h new file mode 100644 index 00000000..7095bb62 --- /dev/null +++ b/include/admin.h @@ -0,0 +1,49 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef ADMIN_H +#define ADMIN_H + +#include + +#include "admin_conf.h" +#include "os_int.h" + +class ADMIN { +public: + virtual ADMIN & operator=(const ADMIN &) = 0; + virtual ADMIN & operator=(const ADMIN_CONF &) = 0; + virtual bool operator==(const ADMIN & rhs) const = 0; + virtual bool operator!=(const ADMIN & rhs) const = 0; + virtual bool operator<(const ADMIN & rhs) const = 0; + virtual bool operator<=(const ADMIN & rhs) const = 0; + + virtual const std::string & GetPassword() const = 0; + virtual const std::string & GetLogin() const = 0; + virtual PRIV const * GetPriv() const = 0; + virtual uint16_t GetPrivAsInt() const = 0; + virtual const ADMIN_CONF & GetConf() const = 0; + virtual uint32_t GetIP() const = 0; + virtual std::string GetIPStr() const = 0; + virtual void SetIP(uint32_t ip) = 0; + virtual const std::string GetLogStr() const = 0; +}; + +#endif diff --git a/include/admins.h b/include/admins.h new file mode 100644 index 00000000..48c02252 --- /dev/null +++ b/include/admins.h @@ -0,0 +1,48 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef ADMINS_H +#define ADMINS_H + +#include + +#include "admin.h" +#include "admin_conf.h" + +class ADMINS { +public: + virtual int Add(const std::string & login, const ADMIN & admin) = 0; + virtual int Del(const std::string & login, const ADMIN & admin) = 0; + virtual int Change(const ADMIN_CONF & ac, const ADMIN & admin) = 0; + virtual const ADMIN * GetSysAdmin() const = 0; + virtual const ADMIN * GetNoAdmin() const = 0; + virtual bool FindAdmin(const std::string & l, ADMIN ** admin) = 0; + virtual bool AdminExists(const std::string & login) const = 0; + virtual bool AdminCorrect(const std::string & login, + const std::string & password, + ADMIN * admin) const = 0; + virtual const std::string & GetStrError() const = 0; + + virtual int OpenSearch() const = 0; + virtual int SearchNext(int, ADMIN_CONF * ac) const = 0; + virtual int CloseSearch(int) const = 0; +}; + +#endif diff --git a/include/tariff.h b/include/tariff.h new file mode 100644 index 00000000..b19ec476 --- /dev/null +++ b/include/tariff.h @@ -0,0 +1,56 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef TARIFF_H +#define TARIFF_H + +#include + +#include + +#include "os_int.h" +#include "tariff_conf.h" + +class TARIFF { +public: + virtual double GetPriceWithTraffType(uint64_t up, + uint64_t down, + int dir, + time_t t) const = 0; + virtual double GetFreeMb() const = 0; + virtual double GetPassiveCost() const = 0; + virtual double GetFee() const = 0; + virtual double GetFree() const = 0; + + virtual const std::string & GetName() const = 0; + virtual void SetName(const std::string & name) = 0; + + virtual int GetTraffType() const = 0; + virtual int64_t GetTraffByType(uint64_t up, uint64_t down) const = 0; + virtual int GetThreshold(int dir) const = 0; + virtual const TARIFF_DATA & GetTariffData() const = 0; + + virtual TARIFF & operator=(const TARIFF_DATA & td) = 0; + virtual TARIFF & operator=(const TARIFF & t) = 0; + virtual bool operator==(const TARIFF & rhs) const = 0; + virtual bool operator!=(const TARIFF & rhs) const = 0; +}; + +#endif diff --git a/include/tariffs.h b/include/tariffs.h new file mode 100644 index 00000000..dfc47b48 --- /dev/null +++ b/include/tariffs.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef TARIFFS_H +#define TARIFFS_H + +#include +#include + +class ADMIN; +class TARIFF; +class TARIFF_DATA; + +class TARIFFS { +public: + virtual int ReadTariffs () = 0; + virtual const TARIFF * FindByName(const std::string & name) const = 0; + virtual const TARIFF * GetNoTariff() const = 0; + virtual int GetTariffsNum() const = 0; + virtual int Del(const std::string & name, const ADMIN & admin) = 0; + virtual int Add(const std::string & name, const ADMIN & admin) = 0; + virtual int Chg(const TARIFF_DATA & td, const ADMIN & admin) = 0; + + virtual void GetTariffsData(std::list * tdl) = 0; + + virtual const std::string & GetStrError() const = 0; +}; + +#endif diff --git a/include/user.h b/include/user.h new file mode 100644 index 00000000..cac12d57 --- /dev/null +++ b/include/user.h @@ -0,0 +1,106 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef USER_H +#define USER_H + +#include +#include + +#include "os_int.h" +#include "notifer.h" +#include "base_auth.h" +#include "stg_message.h" +#include "tariff.h" +#include "user_traff.h" + +class USER_PROPERTIES; + +class USER { +public: + virtual int WriteConf() = 0; + virtual int WriteStat() = 0; + + virtual const std::string & GetLogin() const = 0; + + virtual uint32_t GetCurrIP() const = 0; + virtual time_t GetCurrIPModificationTime() const = 0; + + virtual void AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * notifier) = 0; + virtual void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * notifier) = 0; + + virtual void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * notifier) = 0; + virtual void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * notifier) = 0; + + virtual int GetID() const = 0; + + virtual double GetPassiveTimePart() const = 0; + + virtual const TARIFF * GetTariff() const = 0; + virtual void ResetNextTariff() = 0; + + #ifdef TRAFF_STAT_WITH_PORTS + virtual void AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) = 0; + virtual void AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) = 0; + #else + virtual void AddTraffStatU(int dir, uint32_t ip, uint32_t len) = 0; + virtual void AddTraffStatD(int dir, uint32_t ip, uint32_t len) = 0; + #endif + + virtual const DIR_TRAFF & GetSessionUpload() const = 0; + virtual const DIR_TRAFF & GetSessionDownload() const = 0; + + virtual bool GetConnected() const = 0; + virtual time_t GetConnectedModificationTime() const = 0; + virtual int GetAuthorized() const = 0; + virtual int Authorize(uint32_t ip, + const std::string & iface, + uint32_t enabledDirs, + const BASE_AUTH * auth) = 0; + virtual void Unauthorize(const BASE_AUTH * auth) = 0; + virtual bool IsAuthorizedBy(const BASE_AUTH * auth) const = 0; + + virtual int AddMessage(STG_MSG * msg) = 0; + + virtual void UpdatePingTime(time_t t = 0) = 0; + virtual time_t GetPingTime() const = 0; + + virtual void Run() = 0; + + virtual const std::string & GetStrError() const = 0; + + virtual USER_PROPERTIES & GetProperty() = 0; + virtual const USER_PROPERTIES & GetProperty() const = 0; + + virtual bool GetDeleted() const = 0; + virtual void SetDeleted() = 0; + + virtual time_t GetLastWriteStatTime() const = 0; + + virtual bool IsInetable() = 0; + virtual std::string GetEnabledDirs() = 0; + + virtual void OnAdd() = 0; + virtual void OnDelete() = 0; +}; + +typedef USER * USER_PTR; + +#endif diff --git a/include/users.h b/include/users.h new file mode 100644 index 00000000..b9454ce4 --- /dev/null +++ b/include/users.h @@ -0,0 +1,60 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Maxim Mamontov + */ + +#ifndef USERS_H +#define USERS_H + +#include + +#include "notifer.h" +#include "user.h" + +class ADMIN; + +class USERS { +public: + virtual int FindByName(const std::string & login, USER_PTR * user) = 0; + + virtual bool TariffInUse(const std::string & tariffName) const = 0; + + virtual void AddNotifierUserAdd(NOTIFIER_BASE * notifier) = 0; + virtual void DelNotifierUserAdd(NOTIFIER_BASE * notifier) = 0; + + virtual void AddNotifierUserDel(NOTIFIER_BASE * notifier) = 0; + virtual void DelNotifierUserDel(NOTIFIER_BASE * notifier) = 0; + + virtual int Add(const std::string & login, const ADMIN & admin) = 0; + virtual void Del(const std::string & login, const ADMIN & admin) = 0; + + virtual int ReadUsers() = 0; + virtual int GetUserNum() const = 0; + + virtual int FindByIPIdx(uint32_t ip, USER_PTR * user) const = 0; + virtual bool IsIPInIndex(uint32_t ip) const = 0; + + virtual int OpenSearch() = 0; + virtual int SearchNext(int handle, USER_PTR * u) = 0; + virtual int CloseSearch(int handle) = 0; + + virtual int Start() = 0; + virtual int Stop() = 0; +}; + +#endif diff --git a/projects/stargazer/admin.cpp b/projects/stargazer/admin.cpp deleted file mode 100644 index 867717aa..00000000 --- a/projects/stargazer/admin.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - - /* - $Revision: 1.13 $ - $Date: 2010/10/04 20:16:09 $ - $Author: faust $ - */ - -#include "admin.h" -#include "common.h" - -//----------------------------------------------------------------------------- -ADMIN::ADMIN() - : conf(), - ip(0), - WriteServLog(GetStgLogger()) -{ -} -//----------------------------------------------------------------------------- -ADMIN::ADMIN(const ADMIN_CONF & ac) - : conf(ac), - ip(0), - WriteServLog(GetStgLogger()) -{ -} -//----------------------------------------------------------------------------- -ADMIN::ADMIN(const PRIV & priv, const std::string & login, const std::string & password) - : conf(priv, login, password), - ip(0), - WriteServLog(GetStgLogger()) -{ -} -//----------------------------------------------------------------------------- -ADMIN & ADMIN::operator=(const ADMIN & adm) -{ -if (&adm == this) - return *this; - -conf = adm.conf; -ip = adm.ip; -return *this; -} -//----------------------------------------------------------------------------- -ADMIN & ADMIN::operator=(const ADMIN_CONF & ac) -{ -conf = ac; -return *this; -} -//----------------------------------------------------------------------------- -bool ADMIN::operator==(const ADMIN & rhs) const -{ -return conf.login == rhs.GetLogin(); -} -//----------------------------------------------------------------------------- -bool ADMIN::operator!=(const ADMIN & rhs) const -{ -return conf.login != rhs.GetLogin(); -} -//----------------------------------------------------------------------------- -bool ADMIN::operator<(const ADMIN & rhs) const -{ -return conf.login < rhs.GetLogin(); -} -//----------------------------------------------------------------------------- -bool ADMIN::operator<=(const ADMIN & rhs) const -{ -return conf.login <= rhs.GetLogin(); -} -//----------------------------------------------------------------------------- -string ADMIN::GetAdminIPStr() const -{ -return inet_ntostring(ip); -} -//----------------------------------------------------------------------------- -void ADMIN::PrintAdmin() const -{ -printfd(__FILE__, "=======================================\n"); -printfd(__FILE__, "login %s\n", conf.login.c_str()); -printfd(__FILE__, "password %s\n", conf.password.c_str()); -printfd(__FILE__, "ChgConf %d\n", conf.priv.userConf); -printfd(__FILE__, "ChgStat %d\n", conf.priv.userStat); -printfd(__FILE__, "ChgCash %d\n", conf.priv.userCash); -printfd(__FILE__, "UsrAddDel %d\n", conf.priv.userAddDel); -printfd(__FILE__, "ChgAdmin %d\n", conf.priv.adminChg); -printfd(__FILE__, "ChgTariff %d\n", conf.priv.tariffChg); -printfd(__FILE__, "=======================================\n"); -} -//----------------------------------------------------------------------------- -const string ADMIN::GetLogStr() const -{ -return "Admin \'" + conf.login + "\', " + GetAdminIPStr() + ":"; -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/admin.h b/projects/stargazer/admin.h deleted file mode 100644 index 45979ab7..00000000 --- a/projects/stargazer/admin.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - - /* - $Revision: 1.14 $ - $Date: 2010/10/04 20:15:43 $ - $Author: faust $ - */ - -#ifndef ADMIN_H -#define ADMIN_H - -#include - -#include "os_int.h" -#include "admin_conf.h" -#include "stg_logger.h" - -using namespace std; - -//----------------------------------------------------------------------------- -class ADMIN -{ -public: - ADMIN(); - ADMIN(const ADMIN_CONF & ac); - ADMIN(const PRIV & priv, - const std::string & login, - const std::string & password); - ~ADMIN() {}; - - ADMIN & operator=(const ADMIN &); - ADMIN & operator=(const ADMIN_CONF &); - bool operator==(const ADMIN & rhs) const; - bool operator!=(const ADMIN & rhs) const; - bool operator<(const ADMIN & rhs) const; - bool operator<=(const ADMIN & rhs) const; - - const string & GetPassword() const { return conf.password; }; - const string & GetLogin() const { return conf.login; }; - PRIV const * GetPriv() const { return &conf.priv; }; - uint16_t GetPrivAsInt() const { return conf.priv.ToInt(); }; - const ADMIN_CONF & GetConf() const { return conf; }; - void PrintAdmin() const; - uint32_t GetAdminIP() const { return ip; }; - string GetAdminIPStr() const; - void SetAdminIP(uint32_t ip) { ADMIN::ip = ip; }; - const string GetLogStr() const; - -private: - ADMIN_CONF conf; - uint32_t ip; - STG_LOGGER & WriteServLog; -}; -//----------------------------------------------------------------------------- - -#endif diff --git a/projects/stargazer/admin_impl.cpp b/projects/stargazer/admin_impl.cpp new file mode 100644 index 00000000..867717aa --- /dev/null +++ b/projects/stargazer/admin_impl.cpp @@ -0,0 +1,115 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + + /* + $Revision: 1.13 $ + $Date: 2010/10/04 20:16:09 $ + $Author: faust $ + */ + +#include "admin.h" +#include "common.h" + +//----------------------------------------------------------------------------- +ADMIN::ADMIN() + : conf(), + ip(0), + WriteServLog(GetStgLogger()) +{ +} +//----------------------------------------------------------------------------- +ADMIN::ADMIN(const ADMIN_CONF & ac) + : conf(ac), + ip(0), + WriteServLog(GetStgLogger()) +{ +} +//----------------------------------------------------------------------------- +ADMIN::ADMIN(const PRIV & priv, const std::string & login, const std::string & password) + : conf(priv, login, password), + ip(0), + WriteServLog(GetStgLogger()) +{ +} +//----------------------------------------------------------------------------- +ADMIN & ADMIN::operator=(const ADMIN & adm) +{ +if (&adm == this) + return *this; + +conf = adm.conf; +ip = adm.ip; +return *this; +} +//----------------------------------------------------------------------------- +ADMIN & ADMIN::operator=(const ADMIN_CONF & ac) +{ +conf = ac; +return *this; +} +//----------------------------------------------------------------------------- +bool ADMIN::operator==(const ADMIN & rhs) const +{ +return conf.login == rhs.GetLogin(); +} +//----------------------------------------------------------------------------- +bool ADMIN::operator!=(const ADMIN & rhs) const +{ +return conf.login != rhs.GetLogin(); +} +//----------------------------------------------------------------------------- +bool ADMIN::operator<(const ADMIN & rhs) const +{ +return conf.login < rhs.GetLogin(); +} +//----------------------------------------------------------------------------- +bool ADMIN::operator<=(const ADMIN & rhs) const +{ +return conf.login <= rhs.GetLogin(); +} +//----------------------------------------------------------------------------- +string ADMIN::GetAdminIPStr() const +{ +return inet_ntostring(ip); +} +//----------------------------------------------------------------------------- +void ADMIN::PrintAdmin() const +{ +printfd(__FILE__, "=======================================\n"); +printfd(__FILE__, "login %s\n", conf.login.c_str()); +printfd(__FILE__, "password %s\n", conf.password.c_str()); +printfd(__FILE__, "ChgConf %d\n", conf.priv.userConf); +printfd(__FILE__, "ChgStat %d\n", conf.priv.userStat); +printfd(__FILE__, "ChgCash %d\n", conf.priv.userCash); +printfd(__FILE__, "UsrAddDel %d\n", conf.priv.userAddDel); +printfd(__FILE__, "ChgAdmin %d\n", conf.priv.adminChg); +printfd(__FILE__, "ChgTariff %d\n", conf.priv.tariffChg); +printfd(__FILE__, "=======================================\n"); +} +//----------------------------------------------------------------------------- +const string ADMIN::GetLogStr() const +{ +return "Admin \'" + conf.login + "\', " + GetAdminIPStr() + ":"; +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/admin_impl.h b/projects/stargazer/admin_impl.h new file mode 100644 index 00000000..45979ab7 --- /dev/null +++ b/projects/stargazer/admin_impl.h @@ -0,0 +1,78 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + + /* + $Revision: 1.14 $ + $Date: 2010/10/04 20:15:43 $ + $Author: faust $ + */ + +#ifndef ADMIN_H +#define ADMIN_H + +#include + +#include "os_int.h" +#include "admin_conf.h" +#include "stg_logger.h" + +using namespace std; + +//----------------------------------------------------------------------------- +class ADMIN +{ +public: + ADMIN(); + ADMIN(const ADMIN_CONF & ac); + ADMIN(const PRIV & priv, + const std::string & login, + const std::string & password); + ~ADMIN() {}; + + ADMIN & operator=(const ADMIN &); + ADMIN & operator=(const ADMIN_CONF &); + bool operator==(const ADMIN & rhs) const; + bool operator!=(const ADMIN & rhs) const; + bool operator<(const ADMIN & rhs) const; + bool operator<=(const ADMIN & rhs) const; + + const string & GetPassword() const { return conf.password; }; + const string & GetLogin() const { return conf.login; }; + PRIV const * GetPriv() const { return &conf.priv; }; + uint16_t GetPrivAsInt() const { return conf.priv.ToInt(); }; + const ADMIN_CONF & GetConf() const { return conf; }; + void PrintAdmin() const; + uint32_t GetAdminIP() const { return ip; }; + string GetAdminIPStr() const; + void SetAdminIP(uint32_t ip) { ADMIN::ip = ip; }; + const string GetLogStr() const; + +private: + ADMIN_CONF conf; + uint32_t ip; + STG_LOGGER & WriteServLog; +}; +//----------------------------------------------------------------------------- + +#endif diff --git a/projects/stargazer/admins.cpp b/projects/stargazer/admins.cpp deleted file mode 100644 index 4e89c9fd..00000000 --- a/projects/stargazer/admins.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - - /* - $Revision: 1.15 $ - $Date: 2010/10/04 20:17:12 $ - $Author: faust $ - */ - -#include -#include -#include - -#include "admins.h" -#include "admin.h" -#include "common.h" - -using namespace std; - -//----------------------------------------------------------------------------- -ADMINS::ADMINS(BASE_STORE * st) - : stg(0xFFFF, "@stargazer", ""), - noAdmin(0xFFFF, "NO-ADMIN", ""), - data(), - store(st), - WriteServLog(GetStgLogger()), - searchDescriptors(), - handle(0) -{ -pthread_mutex_init(&mutex, NULL); -ReadAdmins(); -} -//----------------------------------------------------------------------------- -int ADMINS::Add(const string & login, const ADMIN & admin) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -const PRIV * priv = admin.GetPriv(); - -if (!priv->adminChg) - { - string s = admin.GetLogStr() + " Add administrator \'" + login + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -ADMIN adm(0, login, ""); -admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai != data.end()) - { - strError = "Administrator \'" + login + "\' cannot not be added. Administrator alredy exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - - return -1; - } - -data.push_back(adm); -/*ADMIN_CONF ac; -ac.login = login;*/ -if (store->AddAdmin(login) == 0 /*&& store->SaveAdmin(ac) == 0*/) - { - WriteServLog("%s Administrator \'%s\' added.", - admin.GetLogStr().c_str(), login.c_str()); - return 0; - } - -strError = "Administrator \'" + login + "\' was not added. Error: " + store->GetStrError(); -WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - -return -1; -} -//----------------------------------------------------------------------------- -int ADMINS::Del(const string & login, const ADMIN & admin) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -ADMIN adm(0, login, ""); -const PRIV * priv = admin.GetPriv(); - -if (!priv->adminChg) - { - string s = admin.GetLogStr() + " Delete administrator \'" + login + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai == data.end()) - { - strError = "Administrator \'" + login + "\' cannot be deleted. Administrator does not exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - return -1; - } - -map::iterator si; -si = searchDescriptors.begin(); -while (si != searchDescriptors.end()) - { - if (si->second == ai) - (si->second)++; - si++; - } - -data.remove(*ai); -if (store->DelAdmin(login) < 0) - { - strError = "Administrator \'" + login + "\' was not deleted. Error: " + store->GetStrError(); - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - - return -1; - } - -WriteServLog("%s Administrator \'%s\' deleted.", admin.GetLogStr().c_str(), login.c_str()); -return 0; -} -//----------------------------------------------------------------------------- -int ADMINS::Change(const ADMIN_CONF & ac, const ADMIN & admin) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -const PRIV * priv = admin.GetPriv(); - -if (!priv->adminChg) - { - string s = admin.GetLogStr() + " Change administrator \'" + ac.login + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -ADMIN adm(0, ac.login, ""); -admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai == data.end()) - { - strError = "Administrator \'" + ac.login + "\' cannot be changed " + ". Administrator does not exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - return -1; - } - -*ai = ac; -if (store->SaveAdmin(ac)) - { - WriteServLog("Cannot write admin %s.", ac.login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - return -1; - } - -WriteServLog("%s Administrator \'%s\' changed.", - admin.GetLogStr().c_str(), ac.login.c_str()); - -return 0; -} -//----------------------------------------------------------------------------- -int ADMINS::ReadAdmins() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -vector adminsList; -if (store->GetAdminsList(&adminsList) < 0) - { - WriteServLog(store->GetStrError().c_str()); - return -1; - } - -for (unsigned int i = 0; i < adminsList.size(); i++) - { - ADMIN_CONF ac(0, adminsList[i], ""); - - if (store->RestoreAdmin(&ac, adminsList[i])) - { - WriteServLog(store->GetStrError().c_str()); - return -1; - } - - data.push_back(ADMIN(ac)); - } -return 0; -} -//----------------------------------------------------------------------------- -void ADMINS::PrintAdmins() const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -const_admin_iter ai(data.begin()); -while (ai != data.end()) - { - ai->PrintAdmin(); - ai++; - } -} -//----------------------------------------------------------------------------- -bool ADMINS::FindAdmin(const string & l, ADMIN * admin) const -{ -assert(admin != NULL && "Pointer to admin is not null"); - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (data.empty()) - { - printfd(__FILE__, "no admin in system!\n"); - *admin = noAdmin; - return false; - } - -ADMIN adm(0, l, ""); -const_admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai != data.end()) - { - *admin = *ai; - return false; - } - -return true; -} -//----------------------------------------------------------------------------- -bool ADMINS::AdminExists(const string & login) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (data.empty()) - { - printfd(__FILE__, "no admin in system!\n"); - return true; - } - -ADMIN adm(0, login, ""); -const_admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai != data.end()) - return true; - -return false; -} -//----------------------------------------------------------------------------- -bool ADMINS::AdminCorrect(const string & login, const std::string & password, ADMIN * admin) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (data.empty()) - { - printfd(__FILE__, "no admin in system!\n"); - return true; - } - -ADMIN adm(0, login, ""); -const_admin_iter ai(find(data.begin(), data.end(), adm)); - -if (ai == data.end()) - { - return false; - } - -if (ai->GetPassword() != password) - { - return false; - } - -*admin = *ai; - -return true; -} -//----------------------------------------------------------------------------- -int ADMINS::OpenSearch() const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -handle++; -searchDescriptors[handle] = data.begin(); -return handle; -} -//----------------------------------------------------------------------------- -int ADMINS::SearchNext(int h, ADMIN_CONF * ac) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (searchDescriptors.find(h) == searchDescriptors.end()) - { - WriteServLog("ADMINS. Incorrect search handle."); - return -1; - } - -if (searchDescriptors[h] == data.end()) - return -1; - -ADMIN a = *searchDescriptors[h]++; - -*ac = a.GetConf(); - -return 0; -} -//----------------------------------------------------------------------------- -int ADMINS::CloseSearch(int h) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (searchDescriptors.find(h) != searchDescriptors.end()) - { - searchDescriptors.erase(searchDescriptors.find(h)); - return 0; - } - -WriteServLog("ADMINS. Incorrect search handle."); -return -1; -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/admins.h b/projects/stargazer/admins.h deleted file mode 100644 index 09933230..00000000 --- a/projects/stargazer/admins.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - - /* - $Revision: 1.10 $ - $Date: 2010/10/04 20:17:12 $ - $Author: faust $ - */ - -#ifndef ADMINS_H -#define ADMINS_H - -#include -#include -#include - -#include "admin.h" -#include "stg_locker.h" -#include "base_store.h" -#include "noncopyable.h" - -using namespace std; - -//----------------------------------------------------------------------------- -class ADMINS : private NONCOPYABLE -{ -public: - ADMINS(BASE_STORE * st); - ~ADMINS() {}; - - int Add(const string & login, const ADMIN & admin); - int Del(const string & login, const ADMIN & admin); - int Change(const ADMIN_CONF & ac, const ADMIN & admin); - void PrintAdmins() const; - const ADMIN GetSysAdmin() const { return stg; }; - const ADMIN GetNoAdmin() const { return noAdmin; }; - bool FindAdmin(const string & l, ADMIN * admin) const; - bool AdminExists(const std::string & login) const; - bool AdminCorrect(const std::string & login, - const std::string & password, - ADMIN * admin) const; - const string & GetStrError() const { return strError; }; - - int OpenSearch() const; - int SearchNext(int, ADMIN_CONF * ac) const; - int CloseSearch(int) const; - -private: - typedef list::iterator admin_iter; - typedef list::const_iterator const_admin_iter; - - int ReadAdmins(); - - ADMIN stg; - ADMIN noAdmin; - list data; - BASE_STORE * store; - STG_LOGGER & WriteServLog; - mutable map searchDescriptors; - mutable unsigned int handle; - mutable pthread_mutex_t mutex; - string strError; -}; -//----------------------------------------------------------------------------- -#endif - - diff --git a/projects/stargazer/admins_impl.cpp b/projects/stargazer/admins_impl.cpp new file mode 100644 index 00000000..4e89c9fd --- /dev/null +++ b/projects/stargazer/admins_impl.cpp @@ -0,0 +1,321 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + + /* + $Revision: 1.15 $ + $Date: 2010/10/04 20:17:12 $ + $Author: faust $ + */ + +#include +#include +#include + +#include "admins.h" +#include "admin.h" +#include "common.h" + +using namespace std; + +//----------------------------------------------------------------------------- +ADMINS::ADMINS(BASE_STORE * st) + : stg(0xFFFF, "@stargazer", ""), + noAdmin(0xFFFF, "NO-ADMIN", ""), + data(), + store(st), + WriteServLog(GetStgLogger()), + searchDescriptors(), + handle(0) +{ +pthread_mutex_init(&mutex, NULL); +ReadAdmins(); +} +//----------------------------------------------------------------------------- +int ADMINS::Add(const string & login, const ADMIN & admin) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +const PRIV * priv = admin.GetPriv(); + +if (!priv->adminChg) + { + string s = admin.GetLogStr() + " Add administrator \'" + login + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +ADMIN adm(0, login, ""); +admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai != data.end()) + { + strError = "Administrator \'" + login + "\' cannot not be added. Administrator alredy exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + + return -1; + } + +data.push_back(adm); +/*ADMIN_CONF ac; +ac.login = login;*/ +if (store->AddAdmin(login) == 0 /*&& store->SaveAdmin(ac) == 0*/) + { + WriteServLog("%s Administrator \'%s\' added.", + admin.GetLogStr().c_str(), login.c_str()); + return 0; + } + +strError = "Administrator \'" + login + "\' was not added. Error: " + store->GetStrError(); +WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + +return -1; +} +//----------------------------------------------------------------------------- +int ADMINS::Del(const string & login, const ADMIN & admin) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +ADMIN adm(0, login, ""); +const PRIV * priv = admin.GetPriv(); + +if (!priv->adminChg) + { + string s = admin.GetLogStr() + " Delete administrator \'" + login + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai == data.end()) + { + strError = "Administrator \'" + login + "\' cannot be deleted. Administrator does not exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + return -1; + } + +map::iterator si; +si = searchDescriptors.begin(); +while (si != searchDescriptors.end()) + { + if (si->second == ai) + (si->second)++; + si++; + } + +data.remove(*ai); +if (store->DelAdmin(login) < 0) + { + strError = "Administrator \'" + login + "\' was not deleted. Error: " + store->GetStrError(); + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + + return -1; + } + +WriteServLog("%s Administrator \'%s\' deleted.", admin.GetLogStr().c_str(), login.c_str()); +return 0; +} +//----------------------------------------------------------------------------- +int ADMINS::Change(const ADMIN_CONF & ac, const ADMIN & admin) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +const PRIV * priv = admin.GetPriv(); + +if (!priv->adminChg) + { + string s = admin.GetLogStr() + " Change administrator \'" + ac.login + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +ADMIN adm(0, ac.login, ""); +admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai == data.end()) + { + strError = "Administrator \'" + ac.login + "\' cannot be changed " + ". Administrator does not exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + return -1; + } + +*ai = ac; +if (store->SaveAdmin(ac)) + { + WriteServLog("Cannot write admin %s.", ac.login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + return -1; + } + +WriteServLog("%s Administrator \'%s\' changed.", + admin.GetLogStr().c_str(), ac.login.c_str()); + +return 0; +} +//----------------------------------------------------------------------------- +int ADMINS::ReadAdmins() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +vector adminsList; +if (store->GetAdminsList(&adminsList) < 0) + { + WriteServLog(store->GetStrError().c_str()); + return -1; + } + +for (unsigned int i = 0; i < adminsList.size(); i++) + { + ADMIN_CONF ac(0, adminsList[i], ""); + + if (store->RestoreAdmin(&ac, adminsList[i])) + { + WriteServLog(store->GetStrError().c_str()); + return -1; + } + + data.push_back(ADMIN(ac)); + } +return 0; +} +//----------------------------------------------------------------------------- +void ADMINS::PrintAdmins() const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +const_admin_iter ai(data.begin()); +while (ai != data.end()) + { + ai->PrintAdmin(); + ai++; + } +} +//----------------------------------------------------------------------------- +bool ADMINS::FindAdmin(const string & l, ADMIN * admin) const +{ +assert(admin != NULL && "Pointer to admin is not null"); + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (data.empty()) + { + printfd(__FILE__, "no admin in system!\n"); + *admin = noAdmin; + return false; + } + +ADMIN adm(0, l, ""); +const_admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai != data.end()) + { + *admin = *ai; + return false; + } + +return true; +} +//----------------------------------------------------------------------------- +bool ADMINS::AdminExists(const string & login) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (data.empty()) + { + printfd(__FILE__, "no admin in system!\n"); + return true; + } + +ADMIN adm(0, login, ""); +const_admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai != data.end()) + return true; + +return false; +} +//----------------------------------------------------------------------------- +bool ADMINS::AdminCorrect(const string & login, const std::string & password, ADMIN * admin) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (data.empty()) + { + printfd(__FILE__, "no admin in system!\n"); + return true; + } + +ADMIN adm(0, login, ""); +const_admin_iter ai(find(data.begin(), data.end(), adm)); + +if (ai == data.end()) + { + return false; + } + +if (ai->GetPassword() != password) + { + return false; + } + +*admin = *ai; + +return true; +} +//----------------------------------------------------------------------------- +int ADMINS::OpenSearch() const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +handle++; +searchDescriptors[handle] = data.begin(); +return handle; +} +//----------------------------------------------------------------------------- +int ADMINS::SearchNext(int h, ADMIN_CONF * ac) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (searchDescriptors.find(h) == searchDescriptors.end()) + { + WriteServLog("ADMINS. Incorrect search handle."); + return -1; + } + +if (searchDescriptors[h] == data.end()) + return -1; + +ADMIN a = *searchDescriptors[h]++; + +*ac = a.GetConf(); + +return 0; +} +//----------------------------------------------------------------------------- +int ADMINS::CloseSearch(int h) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (searchDescriptors.find(h) != searchDescriptors.end()) + { + searchDescriptors.erase(searchDescriptors.find(h)); + return 0; + } + +WriteServLog("ADMINS. Incorrect search handle."); +return -1; +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/admins_impl.h b/projects/stargazer/admins_impl.h new file mode 100644 index 00000000..09933230 --- /dev/null +++ b/projects/stargazer/admins_impl.h @@ -0,0 +1,88 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + + /* + $Revision: 1.10 $ + $Date: 2010/10/04 20:17:12 $ + $Author: faust $ + */ + +#ifndef ADMINS_H +#define ADMINS_H + +#include +#include +#include + +#include "admin.h" +#include "stg_locker.h" +#include "base_store.h" +#include "noncopyable.h" + +using namespace std; + +//----------------------------------------------------------------------------- +class ADMINS : private NONCOPYABLE +{ +public: + ADMINS(BASE_STORE * st); + ~ADMINS() {}; + + int Add(const string & login, const ADMIN & admin); + int Del(const string & login, const ADMIN & admin); + int Change(const ADMIN_CONF & ac, const ADMIN & admin); + void PrintAdmins() const; + const ADMIN GetSysAdmin() const { return stg; }; + const ADMIN GetNoAdmin() const { return noAdmin; }; + bool FindAdmin(const string & l, ADMIN * admin) const; + bool AdminExists(const std::string & login) const; + bool AdminCorrect(const std::string & login, + const std::string & password, + ADMIN * admin) const; + const string & GetStrError() const { return strError; }; + + int OpenSearch() const; + int SearchNext(int, ADMIN_CONF * ac) const; + int CloseSearch(int) const; + +private: + typedef list::iterator admin_iter; + typedef list::const_iterator const_admin_iter; + + int ReadAdmins(); + + ADMIN stg; + ADMIN noAdmin; + list data; + BASE_STORE * store; + STG_LOGGER & WriteServLog; + mutable map searchDescriptors; + mutable unsigned int handle; + mutable pthread_mutex_t mutex; + string strError; +}; +//----------------------------------------------------------------------------- +#endif + + diff --git a/projects/stargazer/tariff.cpp b/projects/stargazer/tariff.cpp deleted file mode 100644 index 70b75576..00000000 --- a/projects/stargazer/tariff.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 07.11.2007 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.11 $ - $Date: 2010/10/07 16:57:21 $ - $Author: faust $ - */ - -#include -#include // std::max - -#include "tariff.h" -#include "stg_timer.h" - -//----------------------------------------------------------------------------- -TARIFF & TARIFF::operator=(const TARIFF_DATA & td) -{ -tariffData = td; -return *this; -} -//----------------------------------------------------------------------------- -TARIFF & TARIFF::operator=(const TARIFF & t) -{ -tariffData = t.tariffData; -return *this; -} -//----------------------------------------------------------------------------- -double TARIFF::GetPriceWithTraffType(uint64_t up, - uint64_t down, - int dir, - time_t t) const -{ -return GetPriceWithoutFreeMb(dir, GetTraffByType(up, down) / (1024 * 1024), t); -} -//----------------------------------------------------------------------------- -int64_t TARIFF::GetTraffByType(uint64_t up, uint64_t down) const -{ -switch (tariffData.tariffConf.traffType) - { - case TRAFF_UP: - return up; - - case TRAFF_DOWN: - return down; - - case TRAFF_MAX: - return std::max(up, down); - - default: //TRAFF_UP_DOWN: - return up + down; - } -} -//----------------------------------------------------------------------------- -int TARIFF::GetThreshold(int dir) const -{ - return tariffData.dirPrice[dir].threshold; -} -//----------------------------------------------------------------------------- -void TARIFF::PrintTariff() const -{ -//printfd(__FILE__, "Traiff name: %s\n", tariffConf.name.c_str()); -//printfd(__FILE__, "Price: %8.3f %8.3f \n", dirPrice[0].GetPrice(0, 0), dirPrice[0].GetPrice(1, 0)); -//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[1].GetPrice(0), dirPrice[1].GetPrice(1), dirPrice[1].GetThreshold()); -//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[2].GetPrice(0), dirPrice[2].GetPrice(1), dirPrice[2].GetThreshold()); -//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[3].GetPrice(0), dirPrice[3].GetPrice(1), dirPrice[3].GetThreshold()); -//printfd(__FILE__, "Free: %8.3f\n", tariffConf.free); -} -//----------------------------------------------------------------------------- -void TARIFF::GetTariffData(TARIFF_DATA * td) const -{ -*td = tariffData; -} -//----------------------------------------------------------------------------- -int TARIFF::Interval(int dir, time_t t) const -{ -// Start of the day (and end of the night) in sec from 00:00:00 -int s1 = tariffData.dirPrice[dir].hDay * 3600 + - tariffData.dirPrice[dir].mDay * 60; -// Start of the night (and end of the day) in sec from 00:00:00 -int s2 = tariffData.dirPrice[dir].hNight * 3600 + - tariffData.dirPrice[dir].mNight * 60; - -struct tm * lt; - -lt = localtime(&t); - -// Position of time t in sec from 00:00:00 -// Ignoring seconds due to minute precision -int lts = lt->tm_hour * 3600 + lt->tm_min * 60; - -if (s1 < s2) - { - // Normal situation (00:00:00 is a night) - if (lts > s1 && lts < s2) - return TARIFF_DAY; - else - return TARIFF_NIGHT; - } -else - { - // Not so common but possible situation (00:00:00 is a day) - if (lts < s1 && lts > s2) - return TARIFF_NIGHT; - else - return TARIFF_DAY; - } -} -//----------------------------------------------------------------------------- -double TARIFF::GetPriceWithoutFreeMb(int dir, int mb, time_t t) const -{ -int interval = Interval(dir, t); - -/* - * 0011 - NB - * *01* - NA - * 0**1 - DB - * **** - DA - */ - -bool nd = tariffData.dirPrice[dir].noDiscount; -bool sp = tariffData.dirPrice[dir].singlePrice; -bool th = (interval == TARIFF_NIGHT); -bool tr = (mb > tariffData.dirPrice[dir].threshold); - -if (!nd && !sp && th && tr) - return tariffData.dirPrice[dir].priceNightB; -else if (!nd && tr) - return tariffData.dirPrice[dir].priceDayB; -else if (!sp && th) - return tariffData.dirPrice[dir].priceNightA; -else - return tariffData.dirPrice[dir].priceDayA; - -/*if (tariffData.dirPrice[dir].noDiscount && tariffData.dirPrice[dir].singlePrice) - { - return tariffData.dirPrice[dir].priceDayA; - } -else - { - if (tariffData.dirPrice[dir].noDiscount) - { - // Without threshold - if (interval == TARIFF_DAY) - return tariffData.dirPrice[dir].priceDayA; - else - return tariffData.dirPrice[dir].priceNightA; - } - - if (tariffData.dirPrice[dir].singlePrice) - { - // Without day/night - if (mb < tariffData.dirPrice[dir].threshold) - return tariffData.dirPrice[dir].priceDayA; - else - return tariffData.dirPrice[dir].priceDayB; - } - - if (mb < tariffData.dirPrice[dir].threshold) - { - if (interval == TARIFF_DAY) - return tariffData.dirPrice[dir].priceDayA; - else - return tariffData.dirPrice[dir].priceNightA; - } - else - { - if (interval == TARIFF_DAY) - return tariffData.dirPrice[dir].priceDayB; - else - return tariffData.dirPrice[dir].priceNightB; - } - }*/ -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/tariff.h b/projects/stargazer/tariff.h deleted file mode 100644 index 2086b488..00000000 --- a/projects/stargazer/tariff.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 07.11.2007 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.9 $ - $Date: 2010/10/07 17:53:39 $ - $Author: faust $ - */ - -#ifndef TARIFF_H -#define TARIFF_H - -#include - -#include -#include - -#include "os_int.h" -#include "tariff_conf.h" - -#define TARIFF_DAY 0 -#define TARIFF_NIGHT 1 - -class TARIFF -{ -public: - TARIFF() - : tariffData() - {}; - TARIFF(const std::string & name) - : tariffData(name) - {}; - TARIFF(const TARIFF_DATA & td) - : tariffData(td) - {}; - TARIFF(const TARIFF & t) - : tariffData(t.tariffData) - {}; - ~TARIFF() {}; - - double GetPriceWithTraffType(uint64_t up, - uint64_t down, - int dir, - time_t t) const; - double GetFreeMb() const { return tariffData.tariffConf.free; }; - double GetPassiveCost() const { return tariffData.tariffConf.passiveCost; }; - double GetFee() const { return tariffData.tariffConf.fee; }; - double GetFree() const { return tariffData.tariffConf.free; }; - - void PrintTariff() const; - - const std::string & GetName() const { return tariffData.tariffConf.name; }; - void SetName(const std::string & name) { tariffData.tariffConf.name = name; }; - - int GetTraffType() const { return tariffData.tariffConf.traffType; }; - int64_t GetTraffByType(uint64_t up, uint64_t down) const; - int GetThreshold(int dir) const; - void GetTariffData(TARIFF_DATA * td) const; - - TARIFF & operator=(const TARIFF_DATA & td); - TARIFF & operator=(const TARIFF & t); - bool operator==(const TARIFF & rhs) const { return GetName() == rhs.GetName(); }; - bool operator!=(const TARIFF & rhs) const { return GetName() != rhs.GetName(); }; - -private: - TARIFF_DATA tariffData; - - double GetPriceWithoutFreeMb(int dir, int mb, time_t t) const; - int Interval(int dir, time_t t) const; -}; -//----------------------------------------------------------------------------- - -#endif diff --git a/projects/stargazer/tariff_impl.cpp b/projects/stargazer/tariff_impl.cpp new file mode 100644 index 00000000..70b75576 --- /dev/null +++ b/projects/stargazer/tariff_impl.cpp @@ -0,0 +1,196 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 07.11.2007 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.11 $ + $Date: 2010/10/07 16:57:21 $ + $Author: faust $ + */ + +#include +#include // std::max + +#include "tariff.h" +#include "stg_timer.h" + +//----------------------------------------------------------------------------- +TARIFF & TARIFF::operator=(const TARIFF_DATA & td) +{ +tariffData = td; +return *this; +} +//----------------------------------------------------------------------------- +TARIFF & TARIFF::operator=(const TARIFF & t) +{ +tariffData = t.tariffData; +return *this; +} +//----------------------------------------------------------------------------- +double TARIFF::GetPriceWithTraffType(uint64_t up, + uint64_t down, + int dir, + time_t t) const +{ +return GetPriceWithoutFreeMb(dir, GetTraffByType(up, down) / (1024 * 1024), t); +} +//----------------------------------------------------------------------------- +int64_t TARIFF::GetTraffByType(uint64_t up, uint64_t down) const +{ +switch (tariffData.tariffConf.traffType) + { + case TRAFF_UP: + return up; + + case TRAFF_DOWN: + return down; + + case TRAFF_MAX: + return std::max(up, down); + + default: //TRAFF_UP_DOWN: + return up + down; + } +} +//----------------------------------------------------------------------------- +int TARIFF::GetThreshold(int dir) const +{ + return tariffData.dirPrice[dir].threshold; +} +//----------------------------------------------------------------------------- +void TARIFF::PrintTariff() const +{ +//printfd(__FILE__, "Traiff name: %s\n", tariffConf.name.c_str()); +//printfd(__FILE__, "Price: %8.3f %8.3f \n", dirPrice[0].GetPrice(0, 0), dirPrice[0].GetPrice(1, 0)); +//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[1].GetPrice(0), dirPrice[1].GetPrice(1), dirPrice[1].GetThreshold()); +//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[2].GetPrice(0), dirPrice[2].GetPrice(1), dirPrice[2].GetThreshold()); +//printfd(__FILE__, "Price: %8.3f %8.3f Thr:%d\n", dirPrice[3].GetPrice(0), dirPrice[3].GetPrice(1), dirPrice[3].GetThreshold()); +//printfd(__FILE__, "Free: %8.3f\n", tariffConf.free); +} +//----------------------------------------------------------------------------- +void TARIFF::GetTariffData(TARIFF_DATA * td) const +{ +*td = tariffData; +} +//----------------------------------------------------------------------------- +int TARIFF::Interval(int dir, time_t t) const +{ +// Start of the day (and end of the night) in sec from 00:00:00 +int s1 = tariffData.dirPrice[dir].hDay * 3600 + + tariffData.dirPrice[dir].mDay * 60; +// Start of the night (and end of the day) in sec from 00:00:00 +int s2 = tariffData.dirPrice[dir].hNight * 3600 + + tariffData.dirPrice[dir].mNight * 60; + +struct tm * lt; + +lt = localtime(&t); + +// Position of time t in sec from 00:00:00 +// Ignoring seconds due to minute precision +int lts = lt->tm_hour * 3600 + lt->tm_min * 60; + +if (s1 < s2) + { + // Normal situation (00:00:00 is a night) + if (lts > s1 && lts < s2) + return TARIFF_DAY; + else + return TARIFF_NIGHT; + } +else + { + // Not so common but possible situation (00:00:00 is a day) + if (lts < s1 && lts > s2) + return TARIFF_NIGHT; + else + return TARIFF_DAY; + } +} +//----------------------------------------------------------------------------- +double TARIFF::GetPriceWithoutFreeMb(int dir, int mb, time_t t) const +{ +int interval = Interval(dir, t); + +/* + * 0011 - NB + * *01* - NA + * 0**1 - DB + * **** - DA + */ + +bool nd = tariffData.dirPrice[dir].noDiscount; +bool sp = tariffData.dirPrice[dir].singlePrice; +bool th = (interval == TARIFF_NIGHT); +bool tr = (mb > tariffData.dirPrice[dir].threshold); + +if (!nd && !sp && th && tr) + return tariffData.dirPrice[dir].priceNightB; +else if (!nd && tr) + return tariffData.dirPrice[dir].priceDayB; +else if (!sp && th) + return tariffData.dirPrice[dir].priceNightA; +else + return tariffData.dirPrice[dir].priceDayA; + +/*if (tariffData.dirPrice[dir].noDiscount && tariffData.dirPrice[dir].singlePrice) + { + return tariffData.dirPrice[dir].priceDayA; + } +else + { + if (tariffData.dirPrice[dir].noDiscount) + { + // Without threshold + if (interval == TARIFF_DAY) + return tariffData.dirPrice[dir].priceDayA; + else + return tariffData.dirPrice[dir].priceNightA; + } + + if (tariffData.dirPrice[dir].singlePrice) + { + // Without day/night + if (mb < tariffData.dirPrice[dir].threshold) + return tariffData.dirPrice[dir].priceDayA; + else + return tariffData.dirPrice[dir].priceDayB; + } + + if (mb < tariffData.dirPrice[dir].threshold) + { + if (interval == TARIFF_DAY) + return tariffData.dirPrice[dir].priceDayA; + else + return tariffData.dirPrice[dir].priceNightA; + } + else + { + if (interval == TARIFF_DAY) + return tariffData.dirPrice[dir].priceDayB; + else + return tariffData.dirPrice[dir].priceNightB; + } + }*/ +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/tariff_impl.h b/projects/stargazer/tariff_impl.h new file mode 100644 index 00000000..2086b488 --- /dev/null +++ b/projects/stargazer/tariff_impl.h @@ -0,0 +1,94 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 07.11.2007 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.9 $ + $Date: 2010/10/07 17:53:39 $ + $Author: faust $ + */ + +#ifndef TARIFF_H +#define TARIFF_H + +#include + +#include +#include + +#include "os_int.h" +#include "tariff_conf.h" + +#define TARIFF_DAY 0 +#define TARIFF_NIGHT 1 + +class TARIFF +{ +public: + TARIFF() + : tariffData() + {}; + TARIFF(const std::string & name) + : tariffData(name) + {}; + TARIFF(const TARIFF_DATA & td) + : tariffData(td) + {}; + TARIFF(const TARIFF & t) + : tariffData(t.tariffData) + {}; + ~TARIFF() {}; + + double GetPriceWithTraffType(uint64_t up, + uint64_t down, + int dir, + time_t t) const; + double GetFreeMb() const { return tariffData.tariffConf.free; }; + double GetPassiveCost() const { return tariffData.tariffConf.passiveCost; }; + double GetFee() const { return tariffData.tariffConf.fee; }; + double GetFree() const { return tariffData.tariffConf.free; }; + + void PrintTariff() const; + + const std::string & GetName() const { return tariffData.tariffConf.name; }; + void SetName(const std::string & name) { tariffData.tariffConf.name = name; }; + + int GetTraffType() const { return tariffData.tariffConf.traffType; }; + int64_t GetTraffByType(uint64_t up, uint64_t down) const; + int GetThreshold(int dir) const; + void GetTariffData(TARIFF_DATA * td) const; + + TARIFF & operator=(const TARIFF_DATA & td); + TARIFF & operator=(const TARIFF & t); + bool operator==(const TARIFF & rhs) const { return GetName() == rhs.GetName(); }; + bool operator!=(const TARIFF & rhs) const { return GetName() != rhs.GetName(); }; + +private: + TARIFF_DATA tariffData; + + double GetPriceWithoutFreeMb(int dir, int mb, time_t t) const; + int Interval(int dir, time_t t) const; +}; +//----------------------------------------------------------------------------- + +#endif diff --git a/projects/stargazer/tariffs.cpp b/projects/stargazer/tariffs.cpp deleted file mode 100644 index 1f8a4230..00000000 --- a/projects/stargazer/tariffs.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 07.11.2007 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.9 $ - $Date: 2010/10/07 18:43:21 $ - $Author: faust $ - */ - -#include -#include -#include - -#include "tariffs.h" -#include "stg_locker.h" -#include "stg_logger.h" -#include "base_store.h" -#include "admin.h" - -using namespace std; - -//----------------------------------------------------------------------------- -TARIFFS::TARIFFS(BASE_STORE * st) - : tariffs(), - store(st), - WriteServLog(GetStgLogger()), - strError(), - noTariff(NO_TARIFF_NAME) -{ -pthread_mutex_init(&mutex, NULL); -ReadTariffs(); -} -//----------------------------------------------------------------------------- -TARIFFS::~TARIFFS() -{ -pthread_mutex_destroy(&mutex); -} -//----------------------------------------------------------------------------- -int TARIFFS::ReadTariffs() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -vector tariffsList; -if (store->GetTariffsList(&tariffsList)) - { - WriteServLog("Cannot get tariffs list."); - WriteServLog("%s", store->GetStrError().c_str()); - } - -int tariffsNum = tariffsList.size(); - -for (int i = 0; i < tariffsNum; i++) - { - TARIFF_DATA td; - if (store->RestoreTariff(&td, tariffsList[i])) - { - WriteServLog("Cannot read tariff %s.", tariffsList[i].c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - return -1; - } - tariffs.push_back(TARIFF(td)); - } - -return 0; -} -//----------------------------------------------------------------------------- -int TARIFFS::GetTariffsNum() const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -return tariffs.size(); -} -//----------------------------------------------------------------------------- -const TARIFF * TARIFFS::FindByName(const string & name) const -{ -if (name == NO_TARIFF_NAME) - return &noTariff; - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -list::const_iterator ti; -ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); - -if (ti != tariffs.end()) - return &(*ti); - -return NULL; -} -//----------------------------------------------------------------------------- -int TARIFFS::Chg(const TARIFF_DATA & td, const ADMIN & admin) -{ -const PRIV * priv = admin.GetPriv(); - -if (!priv->tariffChg) - { - string s = admin.GetLogStr() + " Change tariff \'" - + td.tariffConf.name + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -list::iterator ti; -ti = find(tariffs.begin(), tariffs.end(), TARIFF(td.tariffConf.name)); - -if (ti == tariffs.end()) - { - strError = "Tariff \'" + td.tariffConf.name + "\' cannot be changed. Tariff does not exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - return -1; - } - -*ti = td; - -if (store->SaveTariff(td, td.tariffConf.name)) - { - string error = "Tariff " + td.tariffConf.name + " writing error. " + store->GetStrError(); - WriteServLog(error.c_str()); - return -1; - } - -WriteServLog("%s Tariff \'%s\' changed.", - admin.GetLogStr().c_str(), td.tariffConf.name.c_str()); - -return 0; -} -//----------------------------------------------------------------------------- -int TARIFFS::Del(const string & name, const ADMIN & admin) -{ -const PRIV * priv = admin.GetPriv(); - -if (!priv->tariffChg) - { - string s = admin.GetLogStr() + " Delete tariff \'" - + name + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -list::iterator ti; -ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); - -if (ti == tariffs.end()) - { - strError = "Tariff \'" + name + "\' cannot be deleted. Tariff does not exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - return -1; - } - -if (store->DelTariff(name)) - { - WriteServLog("Cannot delete tariff %s.", name.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - return -1; - } - -tariffs.erase(ti); - -WriteServLog("%s Tariff \'%s\' deleted.", - admin.GetLogStr().c_str(), - name.c_str()); -return 0; -} -//----------------------------------------------------------------------------- -int TARIFFS::Add(const string & name, const ADMIN & admin) -{ -const PRIV * priv = admin.GetPriv(); - -if (!priv->tariffChg) - { - string s = admin.GetLogStr() + " Add tariff \'" - + name + "\'. Access denied."; - strError = "Access denied."; - WriteServLog(s.c_str()); - return -1; - } - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -list::iterator ti; -ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); - -if (ti != tariffs.end()) - { - strError = "Tariff \'" + name + "\' cannot be added. Tariff alredy exist."; - WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); - return -1; - } - -tariffs.push_back(TARIFF(name)); - -if (store->AddTariff(name) < 0) - { - strError = "Tariff " + name + " adding error. " + store->GetStrError(); - WriteServLog(strError.c_str()); - return -1; - } - -WriteServLog("%s Tariff \'%s\' added.", - admin.GetLogStr().c_str(), name.c_str()); - -return 0; -} -//----------------------------------------------------------------------------- -void TARIFFS::GetTariffsData(std::list * tdl) -{ -assert(tdl != NULL && "Tariffs data list is not null"); -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -std::list::const_iterator it = tariffs.begin(); -TARIFF_DATA td; -for (; it != tariffs.end(); ++it) - { - it->GetTariffData(&td); - tdl->push_back(td); - } -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/tariffs.h b/projects/stargazer/tariffs.h deleted file mode 100644 index 5fce068e..00000000 --- a/projects/stargazer/tariffs.h +++ /dev/null @@ -1,81 +0,0 @@ - /* - $Revision: 1.7 $ - $Date: 2010/10/07 18:43:21 $ - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 07.11.2007 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.7 $ - $Date: 2010/10/07 18:43:21 $ - $Author: faust $ - */ - -#ifndef TARIFFS_H -#define TARIFFS_H - -#include - -#include -#include - -#include "tariff.h" -#include "tariff_conf.h" - -#define TARIFF_DAY 0 -#define TARIFF_NIGHT 1 - -class BASE_STORE; -class STG_LOGGER; -class ADMIN; - -//----------------------------------------------------------------------------- -class TARIFFS -{ -public: - TARIFFS(BASE_STORE * store); - ~TARIFFS(); - int ReadTariffs (); - const TARIFF * FindByName(const std::string & name) const; - const TARIFF * GetNoTariff() const { return &noTariff; }; - int GetTariffsNum() const; - int Del(const std::string & name, const ADMIN & admin); - int Add(const std::string & name, const ADMIN & admin); - int Chg(const TARIFF_DATA & td, const ADMIN & admin); - - void GetTariffsData(std::list * tdl); - - const std::string & GetStrError() const { return strError; }; -private: - std::list tariffs; - BASE_STORE * store; - STG_LOGGER & WriteServLog; - mutable pthread_mutex_t mutex; - std::string strError; - TARIFF noTariff; -}; -//----------------------------------------------------------------------------- - -#endif diff --git a/projects/stargazer/tariffs_impl.cpp b/projects/stargazer/tariffs_impl.cpp new file mode 100644 index 00000000..1f8a4230 --- /dev/null +++ b/projects/stargazer/tariffs_impl.cpp @@ -0,0 +1,242 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 07.11.2007 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.9 $ + $Date: 2010/10/07 18:43:21 $ + $Author: faust $ + */ + +#include +#include +#include + +#include "tariffs.h" +#include "stg_locker.h" +#include "stg_logger.h" +#include "base_store.h" +#include "admin.h" + +using namespace std; + +//----------------------------------------------------------------------------- +TARIFFS::TARIFFS(BASE_STORE * st) + : tariffs(), + store(st), + WriteServLog(GetStgLogger()), + strError(), + noTariff(NO_TARIFF_NAME) +{ +pthread_mutex_init(&mutex, NULL); +ReadTariffs(); +} +//----------------------------------------------------------------------------- +TARIFFS::~TARIFFS() +{ +pthread_mutex_destroy(&mutex); +} +//----------------------------------------------------------------------------- +int TARIFFS::ReadTariffs() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +vector tariffsList; +if (store->GetTariffsList(&tariffsList)) + { + WriteServLog("Cannot get tariffs list."); + WriteServLog("%s", store->GetStrError().c_str()); + } + +int tariffsNum = tariffsList.size(); + +for (int i = 0; i < tariffsNum; i++) + { + TARIFF_DATA td; + if (store->RestoreTariff(&td, tariffsList[i])) + { + WriteServLog("Cannot read tariff %s.", tariffsList[i].c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + return -1; + } + tariffs.push_back(TARIFF(td)); + } + +return 0; +} +//----------------------------------------------------------------------------- +int TARIFFS::GetTariffsNum() const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +return tariffs.size(); +} +//----------------------------------------------------------------------------- +const TARIFF * TARIFFS::FindByName(const string & name) const +{ +if (name == NO_TARIFF_NAME) + return &noTariff; + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +list::const_iterator ti; +ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); + +if (ti != tariffs.end()) + return &(*ti); + +return NULL; +} +//----------------------------------------------------------------------------- +int TARIFFS::Chg(const TARIFF_DATA & td, const ADMIN & admin) +{ +const PRIV * priv = admin.GetPriv(); + +if (!priv->tariffChg) + { + string s = admin.GetLogStr() + " Change tariff \'" + + td.tariffConf.name + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +list::iterator ti; +ti = find(tariffs.begin(), tariffs.end(), TARIFF(td.tariffConf.name)); + +if (ti == tariffs.end()) + { + strError = "Tariff \'" + td.tariffConf.name + "\' cannot be changed. Tariff does not exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + return -1; + } + +*ti = td; + +if (store->SaveTariff(td, td.tariffConf.name)) + { + string error = "Tariff " + td.tariffConf.name + " writing error. " + store->GetStrError(); + WriteServLog(error.c_str()); + return -1; + } + +WriteServLog("%s Tariff \'%s\' changed.", + admin.GetLogStr().c_str(), td.tariffConf.name.c_str()); + +return 0; +} +//----------------------------------------------------------------------------- +int TARIFFS::Del(const string & name, const ADMIN & admin) +{ +const PRIV * priv = admin.GetPriv(); + +if (!priv->tariffChg) + { + string s = admin.GetLogStr() + " Delete tariff \'" + + name + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +list::iterator ti; +ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); + +if (ti == tariffs.end()) + { + strError = "Tariff \'" + name + "\' cannot be deleted. Tariff does not exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + return -1; + } + +if (store->DelTariff(name)) + { + WriteServLog("Cannot delete tariff %s.", name.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + return -1; + } + +tariffs.erase(ti); + +WriteServLog("%s Tariff \'%s\' deleted.", + admin.GetLogStr().c_str(), + name.c_str()); +return 0; +} +//----------------------------------------------------------------------------- +int TARIFFS::Add(const string & name, const ADMIN & admin) +{ +const PRIV * priv = admin.GetPriv(); + +if (!priv->tariffChg) + { + string s = admin.GetLogStr() + " Add tariff \'" + + name + "\'. Access denied."; + strError = "Access denied."; + WriteServLog(s.c_str()); + return -1; + } + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +list::iterator ti; +ti = find(tariffs.begin(), tariffs.end(), TARIFF(name)); + +if (ti != tariffs.end()) + { + strError = "Tariff \'" + name + "\' cannot be added. Tariff alredy exist."; + WriteServLog("%s %s", admin.GetLogStr().c_str(), strError.c_str()); + return -1; + } + +tariffs.push_back(TARIFF(name)); + +if (store->AddTariff(name) < 0) + { + strError = "Tariff " + name + " adding error. " + store->GetStrError(); + WriteServLog(strError.c_str()); + return -1; + } + +WriteServLog("%s Tariff \'%s\' added.", + admin.GetLogStr().c_str(), name.c_str()); + +return 0; +} +//----------------------------------------------------------------------------- +void TARIFFS::GetTariffsData(std::list * tdl) +{ +assert(tdl != NULL && "Tariffs data list is not null"); +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +std::list::const_iterator it = tariffs.begin(); +TARIFF_DATA td; +for (; it != tariffs.end(); ++it) + { + it->GetTariffData(&td); + tdl->push_back(td); + } +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/tariffs_impl.h b/projects/stargazer/tariffs_impl.h new file mode 100644 index 00000000..5fce068e --- /dev/null +++ b/projects/stargazer/tariffs_impl.h @@ -0,0 +1,81 @@ + /* + $Revision: 1.7 $ + $Date: 2010/10/07 18:43:21 $ + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 07.11.2007 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.7 $ + $Date: 2010/10/07 18:43:21 $ + $Author: faust $ + */ + +#ifndef TARIFFS_H +#define TARIFFS_H + +#include + +#include +#include + +#include "tariff.h" +#include "tariff_conf.h" + +#define TARIFF_DAY 0 +#define TARIFF_NIGHT 1 + +class BASE_STORE; +class STG_LOGGER; +class ADMIN; + +//----------------------------------------------------------------------------- +class TARIFFS +{ +public: + TARIFFS(BASE_STORE * store); + ~TARIFFS(); + int ReadTariffs (); + const TARIFF * FindByName(const std::string & name) const; + const TARIFF * GetNoTariff() const { return &noTariff; }; + int GetTariffsNum() const; + int Del(const std::string & name, const ADMIN & admin); + int Add(const std::string & name, const ADMIN & admin); + int Chg(const TARIFF_DATA & td, const ADMIN & admin); + + void GetTariffsData(std::list * tdl); + + const std::string & GetStrError() const { return strError; }; +private: + std::list tariffs; + BASE_STORE * store; + STG_LOGGER & WriteServLog; + mutable pthread_mutex_t mutex; + std::string strError; + TARIFF noTariff; +}; +//----------------------------------------------------------------------------- + +#endif diff --git a/projects/stargazer/user.cpp b/projects/stargazer/user.cpp deleted file mode 100644 index d8368c4d..00000000 --- a/projects/stargazer/user.cpp +++ /dev/null @@ -1,1295 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.101 $ - $Date: 2010/11/03 10:50:03 $ - $Author: faust $ - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include // access - -#include - -#include "user.h" -#include "common.h" -#include "settings.h" -#include "script_executer.h" -#include "tariff.h" -#include "tariffs.h" -#include "admin.h" - -USER::USER(const SETTINGS * s, - const BASE_STORE * st, - const TARIFFS * t, - const ADMIN & a, - const map * ipIdx) - : property(s), - WriteServLog(GetStgLogger()), - login(), - id(0), - __connected(0), - connected(__connected), - userIDGenerator(), - __currIP(0), - currIP(__currIP), - lastIPForDisconnect(0), - pingTime(0), - sysAdmin(a), - store(st), - tariffs(t), - tariff(tariffs->GetNoTariff()), - 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), - tariffNotifier(this), - cashNotifier(this), - ipNotifier(this) -{ -settings = s; -ipIndex = ipIdx; - -password = "*_EMPTY_PASSWORD_*"; -tariffName = NO_TARIFF_NAME; -connected = 0; -tariff = tariffs->GetNoTariff(); -ips = StrToIPS("*"); -deleted = false; -lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); -lastWriteDeatiledStat = stgTime; - -property.tariffName.AddBeforeNotifier(&tariffNotifier); -property.passive.AddBeforeNotifier(&passiveNotifier); -property.cash.AddBeforeNotifier(&cashNotifier); -currIP.AddAfterNotifier(&ipNotifier); - -lastScanMessages = 0; - -pthread_mutexattr_t attr; -pthread_mutexattr_init(&attr); -pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -pthread_mutex_init(&mutex, &attr); -} -//----------------------------------------------------------------------------- -USER::USER(const USER & u) - : property(u.settings), - WriteServLog(GetStgLogger()), - login(u.login), - id(u.id), - __connected(u.__connected), - connected(__connected), - __currIP(u.__currIP), - currIP(__currIP), - lastIPForDisconnect(0), - pingTime(u.pingTime), - sysAdmin(u.sysAdmin), - store(u.store), - tariffs(u.tariffs), - tariff(u.tariff), - 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), - tariffNotifier(this), - cashNotifier(this), - ipNotifier(this) -{ -if (&u == this) - return; - -connected = 0; - -ipIndex = u.ipIndex; - -deleted = u.deleted; - -lastWriteStat = u.lastWriteStat; -lastWriteDeatiledStat = u.lastWriteDeatiledStat; - -settings = u.settings; - -property.tariffName.AddBeforeNotifier(&tariffNotifier); -property.passive.AddBeforeNotifier(&passiveNotifier); -property.cash.AddBeforeNotifier(&cashNotifier); -currIP.AddAfterNotifier(&ipNotifier); - -lastScanMessages = 0; - -property.SetProperties(u.property); - -pthread_mutexattr_t attr; -pthread_mutexattr_init(&attr); -pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -pthread_mutex_init(&mutex, &attr); -} -//----------------------------------------------------------------------------- -USER::~USER() -{ -property.passive.DelBeforeNotifier(&passiveNotifier); -property.tariffName.DelBeforeNotifier(&tariffNotifier); -pthread_mutex_destroy(&mutex); -} -//----------------------------------------------------------------------------- -void USER::SetLogin(string const & l) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -assert(login.empty() && "Login is already set"); -login = l; -id = userIDGenerator.GetNextID(); -} -//----------------------------------------------------------------------------- -int USER::ReadConf() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -USER_CONF conf; - -if (store->RestoreUserConf(&conf, login)) - { - WriteServLog("Cannot read conf for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str()); - printfd(__FILE__, "%s\n", store->GetStrError().c_str()); - return -1; - } - -property.SetConf(conf); - -tariff = tariffs->FindByName(tariffName); -if (tariff == NULL) - { - WriteServLog("Cannot read user %s. Tariff %s not exist.", - login.c_str(), property.tariffName.Get().c_str()); - return -1; - } - -std::vector hdrsList; - -if (store->GetMessageHdrs(&hdrsList, login)) - { - printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str()); - return -1; - } - -std::vector::const_iterator it; -for (it = hdrsList.begin(); it != hdrsList.end(); ++it) - { - STG_MSG msg; - if (store->GetMessage(it->id, &msg, login) == 0) - { - messages.push_back(msg); - } - } - -return 0; -} -//----------------------------------------------------------------------------- -int USER::ReadStat() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -USER_STAT stat; - -if (store->RestoreUserStat(&stat, login)) - { - WriteServLog("Cannot read stat for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str()); - printfd(__FILE__, "%s\n", store->GetStrError().c_str()); - return -1; - } - -property.SetStat(stat); - -return 0; -} -//----------------------------------------------------------------------------- -int USER::WriteConf() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -USER_CONF conf(property.GetConf()); - -printfd(__FILE__, "USER::WriteConf()\n"); - -if (store->SaveUserConf(conf, login)) - { - WriteServLog("Cannot write conf for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str()); - printfd(__FILE__, "%s\n", store->GetStrError().c_str()); - return -1; - } - -return 0; -} -//----------------------------------------------------------------------------- -int USER::WriteStat() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -USER_STAT stat(property.GetStat()); - -printfd(__FILE__, "USER::WriteStat()\n"); - -if (store->SaveUserStat(stat, login)) - { - WriteServLog("Cannot write stat for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str()); - printfd(__FILE__, "%s\n", store->GetStrError().c_str()); - return -1; - } - -lastWriteStat = stgTime; - -return 0; -} -//----------------------------------------------------------------------------- -int USER::WriteMonthStat() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -time_t tt = stgTime - 3600; -struct tm t1; -localtime_r(&tt, &t1); - -USER_STAT stat(property.GetStat()); -if (store->SaveMonthStat(stat, t1.tm_mon, t1.tm_year, login)) - { - WriteServLog("Cannot write month stat for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str()); - printfd(__FILE__, "%s\n", store->GetStrError().c_str()); - return -1; - } - -return 0; -} -//----------------------------------------------------------------------------- -int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -/* - * Authorize user. It only means that user will be authorized. Nothing more. - * User can be connected or disconnected while authorized. - * Example: user is authorized but disconnected due to 0 money or blocking - */ - -/* - * Prevent double authorization by identical authorizers - */ -if (authorizedBy.find(auth) != authorizedBy.end()) - return 0; - -if (!ip) - return -1; - -for (int i = 0; i < DIR_NUM; i++) - { - enabledDirs[i] = dirs & (1 << i); - } - -if (authorizedBy.size()) - { - if (currIP != ip) - { - // We are already authorized, but with different IP address - errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip); - return -1; - } - - map::const_iterator ci = ipIndex->find(ip); - if (ci != ipIndex->end()) - { - // Address is already present in IP-index - // If it's not our IP - throw an error - if (&(*ci->second) != this) - { - errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; - return -1; - } - } - } -else - { - if (ipIndex->find(ip) != ipIndex->end()) - { - // Address is already present in IP-index - errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; - return -1; - } - - if (ips.ConstData().IsIPInIPS(ip)) - { - currIP = ip; - lastIPForDisconnect = currIP; - } - else - { - printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str()); - errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login; - return -1; - } - } - -authorizedBy.insert(auth); - -ScanMessage(); - -return 0; -} -//----------------------------------------------------------------------------- -void USER::Unauthorize(const BASE_AUTH * auth) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -/* - * Authorizer tries to unauthorize user, that was not authorized by it - */ -if (!authorizedBy.erase(auth)) - return; - -if (authorizedBy.empty()) - { - lastIPForDisconnect = currIP; - currIP = 0; // DelUser in traffcounter - return; - } -} -//----------------------------------------------------------------------------- -bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -// Is this user authorized by specified authorizer? -return authorizedBy.find(auth) != authorizedBy.end(); -} -//----------------------------------------------------------------------------- -void USER::Connect(bool fakeConnect) -{ -/* - * Connect user to Internet. This function is differ from Authorize() !!! - */ - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (!fakeConnect) - { - string scriptOnConnect = settings->GetScriptDir() + "/OnConnect"; - - if (access(scriptOnConnect.c_str(), X_OK) == 0) - { - char dirsStr[DIR_NUM + 1]; - dirsStr[DIR_NUM] = 0; - for (int i = 0; i < DIR_NUM; i++) - { - dirsStr[i] = enabledDirs[i] ? '1' : '0'; - } - - string scriptOnConnectParams; - strprintf(&scriptOnConnectParams, - "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", - scriptOnConnect.c_str(), - login.c_str(), - inet_ntostring(currIP).c_str(), - (double)cash, - id, - dirsStr); - - ScriptExec(scriptOnConnectParams); - } - else - { - WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str()); - } - - connected = true; - } - -if (store->WriteUserConnect(login, currIP)) - { - WriteServLog("Cannot write connect for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - } - -if (!fakeConnect) - lastIPForDisconnect = currIP; -} -//----------------------------------------------------------------------------- -void USER::Disconnect(bool fakeDisconnect, const std::string & reason) -{ -/* - * Disconnect user from Internet. This function is differ from UnAuthorize() !!! - */ - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (!lastIPForDisconnect) - { - printfd(__FILE__, "lastIPForDisconnect\n"); - return; - } - -if (!fakeDisconnect) - { - string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect"; - - if (access(scriptOnDisonnect.c_str(), X_OK) == 0) - { - char dirsStr[DIR_NUM + 1]; - dirsStr[DIR_NUM] = 0; - for (int i = 0; i < DIR_NUM; i++) - { - dirsStr[i] = enabledDirs[i] ? '1' : '0'; - } - - string scriptOnDisonnectParams; - strprintf(&scriptOnDisonnectParams, - "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", - scriptOnDisonnect.c_str(), - login.c_str(), - inet_ntostring(lastIPForDisconnect).c_str(), - (double)cash, - id, - dirsStr); - - ScriptExec(scriptOnDisonnectParams); - } - else - { - WriteServLog("Script OnDisconnect cannot be executed. File not found."); - } - - connected = false; - } - -if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason)) - { - WriteServLog("Cannot write disconnect for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - } - -if (!fakeDisconnect) - lastIPForDisconnect = 0; - -DIR_TRAFF zeroSesssion; - -sessionUpload = zeroSesssion; -sessionDownload = zeroSesssion; -} -//----------------------------------------------------------------------------- -void USER::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())) - { - printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str()); - WriteStat(); - } -if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime) - { - WriteServLog("User: %s. Credit expired.", login.c_str()); - credit = 0; - creditExpire = 0; - WriteConf(); - } - -if (passive.ConstData() - && (stgTime % 30 == 0) - && (passiveTime.ModificationTime() != stgTime)) - { - passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime()); - printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData()); - } - -if (!authorizedBy.empty()) - { - if (connected) - { - lastActivityTime = *const_cast(&stgTime); - } - if (!connected && IsInetable()) - { - Connect(); - } - if (connected && !IsInetable()) - { - if (disabled) - Disconnect(false, "disabled"); - else if (passive) - Disconnect(false, "passive"); - else - Disconnect(false, "no cash"); - } - - if (stgTime - lastScanMessages > 10) - { - ScanMessage(); - lastScanMessages = stgTime; - } - } -else - { - if (connected) - { - Disconnect(false, "not authorized"); - } - } - -} -//----------------------------------------------------------------------------- -void USER::UpdatePingTime(time_t t) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -//printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str()); -if (t) - pingTime = t; -else - pingTime = stgTime; -} -//----------------------------------------------------------------------------- -bool USER::IsInetable() -{ -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (disabled || passive) - return false; - -if (settings->GetFreeMbAllowInet()) - { - if (freeMb >= 0) - return true; - } - -if (settings->GetShowFeeInCash()) - { - return (cash >= -credit); - } - -return (cash - tariff->GetFee() >= -credit); -} -//----------------------------------------------------------------------------- -string USER::GetEnabledDirs() -{ -//STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -string dirs = ""; -for(int i = 0; i < DIR_NUM; i++) - dirs += enabledDirs[i] ? "1" : "0"; -return dirs; -} -//----------------------------------------------------------------------------- -#ifdef TRAFF_STAT_WITH_PORTS -void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) -#else -void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len) -#endif -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (!connected) - return; - -double cost = 0; -DIR_TRAFF dt(up); - -int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]); -int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; - -dt[dir] += len; - -int tt = tariff->GetTraffType(); -if (tt == TRAFF_UP || - tt == TRAFF_UP_DOWN || - // Check NEW traff data - (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir])) - { - double dc = 0; - if (traff < threshold && - traff + len >= threshold) - { - // cash = partBeforeThreshold * priceBeforeThreshold + - // partAfterThreshold * priceAfterThreshold - int64_t before = threshold - traff; // Chunk part before threshold - int64_t after = len - before; // Chunk part after threshold - dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk - down.ConstData()[dir], - dir, - stgTime) * before + - tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk - down.ConstData()[dir], - dir, - stgTime) * after; - } - else - { - dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], - down.ConstData()[dir], - dir, - stgTime) * len; - } - - if (freeMb.ConstData() <= 0) // FreeMb is exhausted - cost = dc; - else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted - cost = dc - freeMb.ConstData(); - - // Direct access to internal data structures via friend-specifier - property.stat.freeMb -= dc; - property.stat.cash -= cost; - cash.ModifyTime(); - freeMb.ModifyTime(); - } - -up = dt; -sessionUpload[dir] += len; - -//Add detailed stat - -if (!settings->GetWriteFreeMbTraffCost() && - freeMb.ConstData() >= 0) - cost = 0; - -#ifdef TRAFF_STAT_WITH_PORTS -IP_DIR_PAIR idp(ip, dir, port); -#else -IP_DIR_PAIR idp(ip, dir); -#endif - -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))); - } -else - { - lb->second.cash += cost; - lb->second.up += len; - } -} -//----------------------------------------------------------------------------- -#ifdef TRAFF_STAT_WITH_PORTS -void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) -#else -void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len) -#endif -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (!connected) - return; - -double cost = 0; -DIR_TRAFF dt(down); - -int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]); -int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; - -dt[dir] += len; - -int tt = tariff->GetTraffType(); -if (tt == TRAFF_DOWN || - tt == TRAFF_UP_DOWN || - // Check NEW traff data - (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) - { - double dc = 0; - if (traff < threshold && - traff + len >= threshold) - { - // cash = partBeforeThreshold * priceBeforeThreshold + - // partAfterThreshold * priceAfterThreshold - int64_t before = threshold - traff; // Chunk part before threshold - int64_t after = len - before; // Chunk part after threshold - dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], - down.ConstData()[dir], // Traff before chunk - dir, - stgTime) * before + - tariff->GetPriceWithTraffType(up.ConstData()[dir], - dt[dir], // Traff after chunk - dir, - stgTime) * after; - } - else - { - dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], - down.ConstData()[dir], - dir, - stgTime) * len; - } - - if (freeMb.ConstData() <= 0) // FreeMb is exhausted - cost = dc; - else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted - cost = dc - freeMb.ConstData(); - - property.stat.freeMb -= dc; - property.stat.cash -= cost; - cash.ModifyTime(); - freeMb.ModifyTime(); - } - -down = dt; -sessionDownload[dir] += len; - -//Add detailed stat - -if (!settings->GetWriteFreeMbTraffCost() && - freeMb.ConstData() >= 0) - cost = 0; - -#ifdef TRAFF_STAT_WITH_PORTS -IP_DIR_PAIR idp(ip, dir, port); -#else -IP_DIR_PAIR idp(ip, dir); -#endif - -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))); - } -else - { - lb->second.cash += cost; - lb->second.down += len; - } -} -//----------------------------------------------------------------------------- -void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.AddBeforeNotifier(n); -} -//----------------------------------------------------------------------------- -void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.DelBeforeNotifier(n); -} -//----------------------------------------------------------------------------- -void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.AddAfterNotifier(n); -} -//----------------------------------------------------------------------------- -void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -currIP.DelAfterNotifier(n); -} -//----------------------------------------------------------------------------- -void USER::OnAdd() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd"; - -if (access(scriptOnAdd.c_str(), X_OK) == 0) - { - string scriptOnAddParams; - strprintf(&scriptOnAddParams, - "%s \"%s\"", - scriptOnAdd.c_str(), - login.c_str()); - - ScriptExec(scriptOnAddParams); - } -else - { - WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str()); - } -} -//----------------------------------------------------------------------------- -void USER::OnDelete() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -string scriptOnDel = settings->GetScriptDir() + "/OnUserDel"; - -if (access(scriptOnDel.c_str(), X_OK) == 0) - { - string scriptOnDelParams; - strprintf(&scriptOnDelParams, - "%s \"%s\"", - scriptOnDel.c_str(), - login.c_str()); - - ScriptExec(scriptOnDelParams); - } -else - { - WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str()); - } - -Run(); -} -//----------------------------------------------------------------------------- -int USER::WriteDetailStat(bool hard) -{ -printfd(__FILE__, "USER::WriteDetailedStat() - saved size = %d\n", traffStatSaved.second.size()); - -if (!traffStatSaved.second.empty()) - { - if (store->WriteDetailedStat(traffStatSaved.second, traffStatSaved.first, login)) - { - printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n"); - WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatSaved.second.size(), login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - return -1; - } - traffStatSaved.second.erase(traffStatSaved.second.begin(), traffStatSaved.second.end()); - } - -TRAFF_STAT ts; - - { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - ts.swap(traffStat); - } - -printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size()); - -if (ts.size() && !disabledDetailStat) - { - if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login)) - { - printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n"); - WriteServLog("Cannot write detail stat for user %s.", login.c_str()); - WriteServLog("%s", store->GetStrError().c_str()); - if (!hard) - { - printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n"); - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - traffStatSaved.second.swap(ts); - traffStatSaved.first = lastWriteDeatiledStat; - } - return -1; - } - } -lastWriteDeatiledStat = stgTime; -return 0; -} -//----------------------------------------------------------------------------- -double USER::GetPassiveTimePart() const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -static int daysInMonth[12] = -{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -struct tm tms; -time_t t = stgTime; -localtime_r(&t, &tms); - -time_t secMonth = daysInMonth[(tms.tm_mon + 11) % 12] * 24 * 3600; // Previous month - -if (tms.tm_year % 4 == 0 && tms.tm_mon == 1) - { - // Leap year - secMonth += 24 * 3600; - } - -int dt = secMonth - passiveTime; - -if (dt < 0) - dt = 0; - -return double(dt) / (secMonth); -} -//----------------------------------------------------------------------------- -void USER::SetPassiveTimeAsNewUser() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -time_t t = stgTime; -struct tm tm; -localtime_r(&t, &tm); -int daysCurrMon = DaysInCurrentMonth(); -double pt = (tm.tm_mday - 1) / (double)daysCurrMon; - -passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon); -} -//----------------------------------------------------------------------------- -void USER::MidnightResetSessionStat() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (connected) - { - Disconnect(true, "fake"); - Connect(true); - } -} -//----------------------------------------------------------------------------- -void USER::ProcessNewMonth() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -// Reset traff -if (connected) - { - Disconnect(true, "fake"); - } -DIR_TRAFF zeroTarff; - -WriteMonthStat(); - -up = zeroTarff; -down = zeroTarff; - -if (connected) - { - Connect(true); - } - -// Set new tariff -if (nextTariff.ConstData() != "") - { - const TARIFF * nt; - nt = tariffs->FindByName(nextTariff); - if (nt == NULL) - { - WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.", - login.c_str(), property.tariffName.Get().c_str()); - } - else - { - property.tariffName.Set(nextTariff, sysAdmin, login, store); - tariff = nt; - } - ResetNextTariff(); - WriteConf(); - } -} -//----------------------------------------------------------------------------- -void USER::ProcessDayFeeSpread() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (passive.ConstData()) - return; - -double f = tariff->GetFee() / DaysInCurrentMonth(); - -if (f == 0.0) - return; - -double c = cash; -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); -ResetPassiveTime(); -} -//----------------------------------------------------------------------------- -void USER::ProcessDayFee() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -double passiveTimePart = 1.0; -if (!settings->GetFullFee()) - { - passiveTimePart = GetPassiveTimePart(); - } -else - { - if (passive.ConstData()) - { - printfd(__FILE__, "Don't charge fee `cause we are passive\n"); - return; - } - } -double f = tariff->GetFee() * passiveTimePart; - -ResetPassiveTime(); - -if (f == 0.0) - return; - -double c = cash; -printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n", - login.c_str(), - tariff->GetFee(), - passiveTimePart, - f); -property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); -} -//----------------------------------------------------------------------------- -void USER::SetPrepaidTraff() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); -} -//----------------------------------------------------------------------------- -int USER::AddMessage(STG_MSG * msg) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (SendMessage(*msg)) - { - if (store->AddMessage(msg, login)) - { - errorStr = store->GetStrError(); - WriteServLog("Error adding message: '%s'", errorStr.c_str()); - printfd(__FILE__, "Error adding message: '%s'\n", errorStr.c_str()); - return -1; - } - messages.push_back(*msg); - } -else - { - if (msg->header.repeat > 0) - { - msg->header.repeat--; - #ifndef DEBUG - //TODO: gcc v. 4.x generate ICE on x86_64 - msg->header.lastSendTime = time(NULL); - #else - msg->header.lastSendTime = stgTime; - #endif - if (store->AddMessage(msg, login)) - { - errorStr = store->GetStrError(); - WriteServLog("Error adding repeatable message: '%s'", errorStr.c_str()); - printfd(__FILE__, "Error adding repeatable message: '%s'\n", errorStr.c_str()); - return -1; - } - messages.push_back(*msg); - } - } -return 0; -} -//----------------------------------------------------------------------------- -int USER::SendMessage(STG_MSG & msg) const -{ -// No lock `cause we are already locked from caller -int ret = -1; -set::iterator it(authorizedBy.begin()); -while (it != authorizedBy.end()) - { - if (!(*it++)->SendMessage(msg, currIP)) - ret = 0; - } -if (!ret) - { -#ifndef DEBUG - //TODO: gcc v. 4.x generate ICE on x86_64 - msg.header.lastSendTime = time(NULL); -#else - msg.header.lastSendTime = stgTime; -#endif - msg.header.repeat--; - } -return ret; -} -//----------------------------------------------------------------------------- -void USER::ScanMessage() -{ -// No lock `cause we are already locked from caller -// We need not check for the authorizedBy `cause it has already checked by caller - -std::list::iterator it(messages.begin()); -while (it != messages.end()) - { - if (settings->GetMessageTimeout() > 0 && - difftime(stgTime, it->header.creationTime) > settings->GetMessageTimeout()) - { - // Timeout exceeded - if (store->DelMessage(it->header.id, login)) - { - WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str()); - printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str()); - } - messages.erase(it++); - continue; - } - if (it->GetNextSendTime() <= stgTime) - { - if (SendMessage(*it)) - { - // We need to check all messages in queue for timeout - ++it; - continue; - } - if (it->header.repeat < 0) - { - if (store->DelMessage(it->header.id, login)) - { - WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str()); - printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str()); - } - messages.erase(it++); - } - else - { - if (store->EditMessage(*it, login)) - { - WriteServLog("Error modifying message: '%s'", store->GetStrError().c_str()); - printfd(__FILE__, "Error modifying message: '%s'\n", store->GetStrError().c_str()); - } - ++it; - } - } - } -} -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive) -{ -if (newPassive && !oldPassive) - user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(), - user->sysAdmin, - user->login, - user->store, - "Freeze"); -} -//----------------------------------------------------------------------------- -void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff) -{ -user->tariff = user->tariffs->FindByName(newTariff); -} -//----------------------------------------------------------------------------- -void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash) -{ -user->lastCashAddTime = *const_cast(&stgTime); -user->lastCashAdd = newCash - oldCash; -} -//----------------------------------------------------------------------------- -void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to) -{ - printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str()); - if (from != 0) - if (user->connected) - user->Disconnect(false, "Change IP"); - if (to != 0) - if (user->IsInetable()) - user->Connect(false); -} -//----------------------------------------------------------------------------- diff --git a/projects/stargazer/user.h b/projects/stargazer/user.h deleted file mode 100644 index 1c84ba1c..00000000 --- a/projects/stargazer/user.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.48 $ - $Date: 2010/11/03 10:50:03 $ - $Author: faust $ - */ - -#ifndef USER_H -#define USER_H - -#include -#include -#include -#include -#include - -#include "os_int.h" -#include "stg_const.h" -#include "user_stat.h" -#include "user_conf.h" -#include "user_ips.h" -#include "user_property.h" -#include "base_auth.h" -#include "stg_message.h" -#include "noncopyable.h" - -using namespace std; - -//----------------------------------------------------------------------------- -class USER; -class TARIFF; -class TARIFFS; -class ADMIN; -typedef list::iterator user_iter; -typedef list::const_iterator const_user_iter; -//----------------------------------------------------------------------------- -class USER_ID_GENERATOR -{ -friend class USER; -private: - USER_ID_GENERATOR() {} - int GetNextID() { static int id = 0; return id++; } -}; -//----------------------------------------------------------------------------- -class CHG_PASSIVE_NOTIFIER : public PROPERTY_NOTIFIER_BASE, - private NONCOPYABLE -{ -public: - CHG_PASSIVE_NOTIFIER(USER * u) : user(u) {} - void Notify(const int & oldPassive, const int & newPassive); - -private: - USER * user; -}; -//----------------------------------------------------------------------------- -class CHG_TARIFF_NOTIFIER : public PROPERTY_NOTIFIER_BASE, - private NONCOPYABLE -{ -public: - CHG_TARIFF_NOTIFIER(USER * u) : user(u) {} - void Notify(const string & oldTariff, const string & newTariff); - -private: - USER * user; -}; -//----------------------------------------------------------------------------- -class CHG_CASH_NOTIFIER : public PROPERTY_NOTIFIER_BASE, - private NONCOPYABLE -{ -public: - CHG_CASH_NOTIFIER(USER * u) : user(u) {} - void Notify(const double & oldCash, const double & newCash); - -private: - USER * user; -}; -//----------------------------------------------------------------------------- -class CHG_IP_NOTIFIER : public PROPERTY_NOTIFIER_BASE, - private NONCOPYABLE -{ -public: - CHG_IP_NOTIFIER(USER * u) : user(u) {} - void Notify(const uint32_t & oldCash, const uint32_t & newCash); - -private: - USER * user; -}; -//----------------------------------------------------------------------------- -class USER -{ -friend class CHG_PASSIVE_NOTIFIER; -friend class CHG_TARIFF_NOTIFIER; -friend class CHG_CASH_NOTIFIER; -friend class CHG_IP_NOTIFIER; -public: - USER(const SETTINGS * settings, - const BASE_STORE * store, - const TARIFFS * tariffs, - const ADMIN & sysAdmin, - const map * ipIndex); - USER(const USER & u); - ~USER(); - - int ReadConf(); - int ReadStat(); - int WriteConf(); - int WriteStat(); - int WriteMonthStat(); - - string const & GetLogin() const { return login; } - void SetLogin(string const & l); - - uint32_t GetCurrIP() const { return currIP; } - time_t GetCurrIPModificationTime() const { return currIP.ModificationTime(); } - - void AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE *); - void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE *); - - void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE *); - void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE *); - - int GetID() const { return id; } - - double GetPassiveTimePart() const; - void ResetPassiveTime() { passiveTime = 0; } - void SetPassiveTimeAsNewUser(); - - int WriteDetailStat(bool hard = false); - - const TARIFF * GetTariff() const { return tariff; } - void ResetNextTariff() { nextTariff = ""; } - - #ifdef TRAFF_STAT_WITH_PORTS - void AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len); - void AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len); - #else - void AddTraffStatU(int dir, uint32_t ip, uint32_t len); - void AddTraffStatD(int dir, uint32_t ip, uint32_t len); - #endif - - const DIR_TRAFF & GetSessionUpload() const { return sessionUpload; } - const DIR_TRAFF & GetSessionDownload() const { return sessionDownload; } - - bool GetConnected() const { return connected; } - time_t GetConnectedModificationTime() const { return connected.ModificationTime(); } - int GetAuthorized() const { return authorizedBy.size(); } - int Authorize(uint32_t ip, const string & iface, uint32_t enabledDirs, const BASE_AUTH * auth); - void Unauthorize(const BASE_AUTH * auth); - bool IsAuthorizedBy(const BASE_AUTH * auth) const; - void OnAdd(); - void OnDelete(); - - int AddMessage(STG_MSG * msg); - - void UpdatePingTime(time_t t = 0); - time_t GetPingTime() const { return pingTime; } - - void PrintUser() const; - void Run(); - - const string & GetStrError() const { return errorStr; } - - USER_PROPERTIES property; - - void SetDeleted() { deleted = true; } - bool GetDeleted() const { return deleted; } - - time_t GetLastWriteStatTime() const { return lastWriteStat; } - - void MidnightResetSessionStat(); - void ProcessDayFee(); - void SetPrepaidTraff(); - void ProcessDayFeeSpread(); - void ProcessNewMonth(); - - bool IsInetable(); - string GetEnabledDirs(); - -private: - STG_LOGGER & WriteServLog; - - void Connect(bool fakeConnect = false); - void Disconnect(bool fakeDisconnect, const std::string & reason); - int SaveMonthStat(int month, int year); - - int SendMessage(STG_MSG & msg) const; - void ScanMessage(); - time_t lastScanMessages; - - string login; - int id; - bool __connected; - USER_PROPERTY connected; - - bool enabledDirs[DIR_NUM]; - - USER_ID_GENERATOR userIDGenerator; - - uint32_t __currIP; // ôÅËÕÝÉÊ ÁÄÒÅÓ ÐÏÌØÚÏ×ÁÔÅÌÑ - USER_PROPERTY currIP; - - /* - ë ÔÏÍÕ ÍÏÍÅÎÔÕ ËÁË ÍÙ ÕÖÅ ÎÅ Á×ÔÏÒÉÚÏ×ÁÎÉÙ, ÎÏ ÅÝÅ ÎÅ ×ÙÐÏÌÎÅÎ Disconnect, - currIP ÕÖÅ ÓÂÒÏÛÅÎ. ðÏÓÌÅÄÎÅÅ ÚÎÁÞÅÎÉÅ currIP ÓÏÈÒÁÎÑÅÍ × lastIPForDisconnect - */ - uint32_t lastIPForDisconnect; - - time_t pingTime; - - const ADMIN sysAdmin; - const BASE_STORE * store; - - const TARIFFS * tariffs; - const TARIFF * tariff; - - TRAFF_STAT traffStat; - std::pair traffStatSaved; - - const SETTINGS * settings; - - set authorizedBy; - - const map * ipIndex; - - list messages; - - bool deleted; - - time_t lastWriteStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÓÔÁÔÉÓÔÉËÉ - time_t lastWriteDeatiledStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÄÅÔÁÌØÎÏÊ ÓÔÁÔÉÓÔÉËÉ - - // Properties - USER_PROPERTY & cash; - USER_PROPERTY & up; - USER_PROPERTY & down; - USER_PROPERTY & lastCashAdd; - USER_PROPERTY & passiveTime; - USER_PROPERTY & lastCashAddTime; - USER_PROPERTY & freeMb; - USER_PROPERTY & lastActivityTime; - USER_PROPERTY & password; - USER_PROPERTY & passive; - USER_PROPERTY & disabled; - USER_PROPERTY & disabledDetailStat; - USER_PROPERTY & alwaysOnline; - USER_PROPERTY & tariffName; - USER_PROPERTY & nextTariff; - USER_PROPERTY & address; - USER_PROPERTY & note; - USER_PROPERTY & group; - USER_PROPERTY & email; - USER_PROPERTY & phone; - USER_PROPERTY & realName; - USER_PROPERTY & credit; - USER_PROPERTY & creditExpire; - USER_PROPERTY & ips; - USER_PROPERTY & userdata0; - USER_PROPERTY & userdata1; - USER_PROPERTY & userdata2; - USER_PROPERTY & userdata3; - USER_PROPERTY & userdata4; - USER_PROPERTY & userdata5; - USER_PROPERTY & userdata6; - USER_PROPERTY & userdata7; - USER_PROPERTY & userdata8; - USER_PROPERTY & userdata9; - - // End properties - - DIR_TRAFF sessionUpload; - DIR_TRAFF sessionDownload; - - CHG_PASSIVE_NOTIFIER passiveNotifier; - CHG_TARIFF_NOTIFIER tariffNotifier; - CHG_CASH_NOTIFIER cashNotifier; - CHG_IP_NOTIFIER ipNotifier; - - mutable pthread_mutex_t mutex; - - string errorStr; -}; -//----------------------------------------------------------------------------- - -#endif //USER_H diff --git a/projects/stargazer/user_impl.cpp b/projects/stargazer/user_impl.cpp new file mode 100644 index 00000000..d8368c4d --- /dev/null +++ b/projects/stargazer/user_impl.cpp @@ -0,0 +1,1295 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.101 $ + $Date: 2010/11/03 10:50:03 $ + $Author: faust $ + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include // access + +#include + +#include "user.h" +#include "common.h" +#include "settings.h" +#include "script_executer.h" +#include "tariff.h" +#include "tariffs.h" +#include "admin.h" + +USER::USER(const SETTINGS * s, + const BASE_STORE * st, + const TARIFFS * t, + const ADMIN & a, + const map * ipIdx) + : property(s), + WriteServLog(GetStgLogger()), + login(), + id(0), + __connected(0), + connected(__connected), + userIDGenerator(), + __currIP(0), + currIP(__currIP), + lastIPForDisconnect(0), + pingTime(0), + sysAdmin(a), + store(st), + tariffs(t), + tariff(tariffs->GetNoTariff()), + 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), + tariffNotifier(this), + cashNotifier(this), + ipNotifier(this) +{ +settings = s; +ipIndex = ipIdx; + +password = "*_EMPTY_PASSWORD_*"; +tariffName = NO_TARIFF_NAME; +connected = 0; +tariff = tariffs->GetNoTariff(); +ips = StrToIPS("*"); +deleted = false; +lastWriteStat = stgTime + random() % settings->GetStatWritePeriod(); +lastWriteDeatiledStat = stgTime; + +property.tariffName.AddBeforeNotifier(&tariffNotifier); +property.passive.AddBeforeNotifier(&passiveNotifier); +property.cash.AddBeforeNotifier(&cashNotifier); +currIP.AddAfterNotifier(&ipNotifier); + +lastScanMessages = 0; + +pthread_mutexattr_t attr; +pthread_mutexattr_init(&attr); +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +pthread_mutex_init(&mutex, &attr); +} +//----------------------------------------------------------------------------- +USER::USER(const USER & u) + : property(u.settings), + WriteServLog(GetStgLogger()), + login(u.login), + id(u.id), + __connected(u.__connected), + connected(__connected), + __currIP(u.__currIP), + currIP(__currIP), + lastIPForDisconnect(0), + pingTime(u.pingTime), + sysAdmin(u.sysAdmin), + store(u.store), + tariffs(u.tariffs), + tariff(u.tariff), + 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), + tariffNotifier(this), + cashNotifier(this), + ipNotifier(this) +{ +if (&u == this) + return; + +connected = 0; + +ipIndex = u.ipIndex; + +deleted = u.deleted; + +lastWriteStat = u.lastWriteStat; +lastWriteDeatiledStat = u.lastWriteDeatiledStat; + +settings = u.settings; + +property.tariffName.AddBeforeNotifier(&tariffNotifier); +property.passive.AddBeforeNotifier(&passiveNotifier); +property.cash.AddBeforeNotifier(&cashNotifier); +currIP.AddAfterNotifier(&ipNotifier); + +lastScanMessages = 0; + +property.SetProperties(u.property); + +pthread_mutexattr_t attr; +pthread_mutexattr_init(&attr); +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +pthread_mutex_init(&mutex, &attr); +} +//----------------------------------------------------------------------------- +USER::~USER() +{ +property.passive.DelBeforeNotifier(&passiveNotifier); +property.tariffName.DelBeforeNotifier(&tariffNotifier); +pthread_mutex_destroy(&mutex); +} +//----------------------------------------------------------------------------- +void USER::SetLogin(string const & l) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +assert(login.empty() && "Login is already set"); +login = l; +id = userIDGenerator.GetNextID(); +} +//----------------------------------------------------------------------------- +int USER::ReadConf() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +USER_CONF conf; + +if (store->RestoreUserConf(&conf, login)) + { + WriteServLog("Cannot read conf for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + printfd(__FILE__, "Cannot read conf for user %s.\n", login.c_str()); + printfd(__FILE__, "%s\n", store->GetStrError().c_str()); + return -1; + } + +property.SetConf(conf); + +tariff = tariffs->FindByName(tariffName); +if (tariff == NULL) + { + WriteServLog("Cannot read user %s. Tariff %s not exist.", + login.c_str(), property.tariffName.Get().c_str()); + return -1; + } + +std::vector hdrsList; + +if (store->GetMessageHdrs(&hdrsList, login)) + { + printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str()); + return -1; + } + +std::vector::const_iterator it; +for (it = hdrsList.begin(); it != hdrsList.end(); ++it) + { + STG_MSG msg; + if (store->GetMessage(it->id, &msg, login) == 0) + { + messages.push_back(msg); + } + } + +return 0; +} +//----------------------------------------------------------------------------- +int USER::ReadStat() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +USER_STAT stat; + +if (store->RestoreUserStat(&stat, login)) + { + WriteServLog("Cannot read stat for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + printfd(__FILE__, "Cannot read stat for user %s.\n", login.c_str()); + printfd(__FILE__, "%s\n", store->GetStrError().c_str()); + return -1; + } + +property.SetStat(stat); + +return 0; +} +//----------------------------------------------------------------------------- +int USER::WriteConf() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +USER_CONF conf(property.GetConf()); + +printfd(__FILE__, "USER::WriteConf()\n"); + +if (store->SaveUserConf(conf, login)) + { + WriteServLog("Cannot write conf for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + printfd(__FILE__, "Cannot write conf for user %s.\n", login.c_str()); + printfd(__FILE__, "%s\n", store->GetStrError().c_str()); + return -1; + } + +return 0; +} +//----------------------------------------------------------------------------- +int USER::WriteStat() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +USER_STAT stat(property.GetStat()); + +printfd(__FILE__, "USER::WriteStat()\n"); + +if (store->SaveUserStat(stat, login)) + { + WriteServLog("Cannot write stat for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + printfd(__FILE__, "Cannot write stat for user %s.\n", login.c_str()); + printfd(__FILE__, "%s\n", store->GetStrError().c_str()); + return -1; + } + +lastWriteStat = stgTime; + +return 0; +} +//----------------------------------------------------------------------------- +int USER::WriteMonthStat() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +time_t tt = stgTime - 3600; +struct tm t1; +localtime_r(&tt, &t1); + +USER_STAT stat(property.GetStat()); +if (store->SaveMonthStat(stat, t1.tm_mon, t1.tm_year, login)) + { + WriteServLog("Cannot write month stat for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + printfd(__FILE__, "Cannot write month stat for user %s.\n", login.c_str()); + printfd(__FILE__, "%s\n", store->GetStrError().c_str()); + return -1; + } + +return 0; +} +//----------------------------------------------------------------------------- +int USER::Authorize(uint32_t ip, const string &, uint32_t dirs, const BASE_AUTH * auth) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +/* + * Authorize user. It only means that user will be authorized. Nothing more. + * User can be connected or disconnected while authorized. + * Example: user is authorized but disconnected due to 0 money or blocking + */ + +/* + * Prevent double authorization by identical authorizers + */ +if (authorizedBy.find(auth) != authorizedBy.end()) + return 0; + +if (!ip) + return -1; + +for (int i = 0; i < DIR_NUM; i++) + { + enabledDirs[i] = dirs & (1 << i); + } + +if (authorizedBy.size()) + { + if (currIP != ip) + { + // We are already authorized, but with different IP address + errorStr = "User " + login + " alredy authorized with IP address " + inet_ntostring(ip); + return -1; + } + + map::const_iterator ci = ipIndex->find(ip); + if (ci != ipIndex->end()) + { + // Address is already present in IP-index + // If it's not our IP - throw an error + if (&(*ci->second) != this) + { + errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; + return -1; + } + } + } +else + { + if (ipIndex->find(ip) != ipIndex->end()) + { + // Address is already present in IP-index + errorStr = "IP address " + inet_ntostring(ip) + " alredy in use"; + return -1; + } + + if (ips.ConstData().IsIPInIPS(ip)) + { + currIP = ip; + lastIPForDisconnect = currIP; + } + else + { + printfd(__FILE__, " user %s: ips = %s\n", login.c_str(), ips.ConstData().GetIpStr().c_str()); + errorStr = "IP address " + inet_ntostring(ip) + " not belong user " + login; + return -1; + } + } + +authorizedBy.insert(auth); + +ScanMessage(); + +return 0; +} +//----------------------------------------------------------------------------- +void USER::Unauthorize(const BASE_AUTH * auth) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +/* + * Authorizer tries to unauthorize user, that was not authorized by it + */ +if (!authorizedBy.erase(auth)) + return; + +if (authorizedBy.empty()) + { + lastIPForDisconnect = currIP; + currIP = 0; // DelUser in traffcounter + return; + } +} +//----------------------------------------------------------------------------- +bool USER::IsAuthorizedBy(const BASE_AUTH * auth) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +// Is this user authorized by specified authorizer? +return authorizedBy.find(auth) != authorizedBy.end(); +} +//----------------------------------------------------------------------------- +void USER::Connect(bool fakeConnect) +{ +/* + * Connect user to Internet. This function is differ from Authorize() !!! + */ + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (!fakeConnect) + { + string scriptOnConnect = settings->GetScriptDir() + "/OnConnect"; + + if (access(scriptOnConnect.c_str(), X_OK) == 0) + { + char dirsStr[DIR_NUM + 1]; + dirsStr[DIR_NUM] = 0; + for (int i = 0; i < DIR_NUM; i++) + { + dirsStr[i] = enabledDirs[i] ? '1' : '0'; + } + + string scriptOnConnectParams; + strprintf(&scriptOnConnectParams, + "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", + scriptOnConnect.c_str(), + login.c_str(), + inet_ntostring(currIP).c_str(), + (double)cash, + id, + dirsStr); + + ScriptExec(scriptOnConnectParams); + } + else + { + WriteServLog("Script %s cannot be executed. File not found.", scriptOnConnect.c_str()); + } + + connected = true; + } + +if (store->WriteUserConnect(login, currIP)) + { + WriteServLog("Cannot write connect for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + } + +if (!fakeConnect) + lastIPForDisconnect = currIP; +} +//----------------------------------------------------------------------------- +void USER::Disconnect(bool fakeDisconnect, const std::string & reason) +{ +/* + * Disconnect user from Internet. This function is differ from UnAuthorize() !!! + */ + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (!lastIPForDisconnect) + { + printfd(__FILE__, "lastIPForDisconnect\n"); + return; + } + +if (!fakeDisconnect) + { + string scriptOnDisonnect = settings->GetScriptDir() + "/OnDisconnect"; + + if (access(scriptOnDisonnect.c_str(), X_OK) == 0) + { + char dirsStr[DIR_NUM + 1]; + dirsStr[DIR_NUM] = 0; + for (int i = 0; i < DIR_NUM; i++) + { + dirsStr[i] = enabledDirs[i] ? '1' : '0'; + } + + string scriptOnDisonnectParams; + strprintf(&scriptOnDisonnectParams, + "%s \"%s\" \"%s\" \"%f\" \"%d\" \"%s\"", + scriptOnDisonnect.c_str(), + login.c_str(), + inet_ntostring(lastIPForDisconnect).c_str(), + (double)cash, + id, + dirsStr); + + ScriptExec(scriptOnDisonnectParams); + } + else + { + WriteServLog("Script OnDisconnect cannot be executed. File not found."); + } + + connected = false; + } + +if (store->WriteUserDisconnect(login, up, down, sessionUpload, sessionDownload, cash, freeMb, reason)) + { + WriteServLog("Cannot write disconnect for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + } + +if (!fakeDisconnect) + lastIPForDisconnect = 0; + +DIR_TRAFF zeroSesssion; + +sessionUpload = zeroSesssion; +sessionDownload = zeroSesssion; +} +//----------------------------------------------------------------------------- +void USER::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())) + { + printfd(__FILE__, "USER::WriteStat user=%s\n", GetLogin().c_str()); + WriteStat(); + } +if (creditExpire.ConstData() && creditExpire.ConstData() < stgTime) + { + WriteServLog("User: %s. Credit expired.", login.c_str()); + credit = 0; + creditExpire = 0; + WriteConf(); + } + +if (passive.ConstData() + && (stgTime % 30 == 0) + && (passiveTime.ModificationTime() != stgTime)) + { + passiveTime = passiveTime + (stgTime - passiveTime.ModificationTime()); + printfd(__FILE__, "===== %s: passiveTime=%d =====\n", login.c_str(), passiveTime.ConstData()); + } + +if (!authorizedBy.empty()) + { + if (connected) + { + lastActivityTime = *const_cast(&stgTime); + } + if (!connected && IsInetable()) + { + Connect(); + } + if (connected && !IsInetable()) + { + if (disabled) + Disconnect(false, "disabled"); + else if (passive) + Disconnect(false, "passive"); + else + Disconnect(false, "no cash"); + } + + if (stgTime - lastScanMessages > 10) + { + ScanMessage(); + lastScanMessages = stgTime; + } + } +else + { + if (connected) + { + Disconnect(false, "not authorized"); + } + } + +} +//----------------------------------------------------------------------------- +void USER::UpdatePingTime(time_t t) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//printfd(__FILE__, "UpdatePingTime(%d) %s\n", t, login.c_str()); +if (t) + pingTime = t; +else + pingTime = stgTime; +} +//----------------------------------------------------------------------------- +bool USER::IsInetable() +{ +//STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (disabled || passive) + return false; + +if (settings->GetFreeMbAllowInet()) + { + if (freeMb >= 0) + return true; + } + +if (settings->GetShowFeeInCash()) + { + return (cash >= -credit); + } + +return (cash - tariff->GetFee() >= -credit); +} +//----------------------------------------------------------------------------- +string USER::GetEnabledDirs() +{ +//STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +string dirs = ""; +for(int i = 0; i < DIR_NUM; i++) + dirs += enabledDirs[i] ? "1" : "0"; +return dirs; +} +//----------------------------------------------------------------------------- +#ifdef TRAFF_STAT_WITH_PORTS +void USER::AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len) +#else +void USER::AddTraffStatU(int dir, uint32_t ip, uint32_t len) +#endif +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (!connected) + return; + +double cost = 0; +DIR_TRAFF dt(up); + +int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]); +int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; + +dt[dir] += len; + +int tt = tariff->GetTraffType(); +if (tt == TRAFF_UP || + tt == TRAFF_UP_DOWN || + // Check NEW traff data + (tt == TRAFF_MAX && dt[dir] > down.ConstData()[dir])) + { + double dc = 0; + if (traff < threshold && + traff + len >= threshold) + { + // cash = partBeforeThreshold * priceBeforeThreshold + + // partAfterThreshold * priceAfterThreshold + int64_t before = threshold - traff; // Chunk part before threshold + int64_t after = len - before; // Chunk part after threshold + dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], // Traff before chunk + down.ConstData()[dir], + dir, + stgTime) * before + + tariff->GetPriceWithTraffType(dt[dir], // Traff after chunk + down.ConstData()[dir], + dir, + stgTime) * after; + } + else + { + dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], + down.ConstData()[dir], + dir, + stgTime) * len; + } + + if (freeMb.ConstData() <= 0) // FreeMb is exhausted + cost = dc; + else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted + cost = dc - freeMb.ConstData(); + + // Direct access to internal data structures via friend-specifier + property.stat.freeMb -= dc; + property.stat.cash -= cost; + cash.ModifyTime(); + freeMb.ModifyTime(); + } + +up = dt; +sessionUpload[dir] += len; + +//Add detailed stat + +if (!settings->GetWriteFreeMbTraffCost() && + freeMb.ConstData() >= 0) + cost = 0; + +#ifdef TRAFF_STAT_WITH_PORTS +IP_DIR_PAIR idp(ip, dir, port); +#else +IP_DIR_PAIR idp(ip, dir); +#endif + +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))); + } +else + { + lb->second.cash += cost; + lb->second.up += len; + } +} +//----------------------------------------------------------------------------- +#ifdef TRAFF_STAT_WITH_PORTS +void USER::AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len) +#else +void USER::AddTraffStatD(int dir, uint32_t ip, uint32_t len) +#endif +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (!connected) + return; + +double cost = 0; +DIR_TRAFF dt(down); + +int64_t traff = tariff->GetTraffByType(up.ConstData()[dir], down.ConstData()[dir]); +int64_t threshold = tariff->GetThreshold(dir) * 1024 * 1024; + +dt[dir] += len; + +int tt = tariff->GetTraffType(); +if (tt == TRAFF_DOWN || + tt == TRAFF_UP_DOWN || + // Check NEW traff data + (tt == TRAFF_MAX && up.ConstData()[dir] <= dt[dir])) + { + double dc = 0; + if (traff < threshold && + traff + len >= threshold) + { + // cash = partBeforeThreshold * priceBeforeThreshold + + // partAfterThreshold * priceAfterThreshold + int64_t before = threshold - traff; // Chunk part before threshold + int64_t after = len - before; // Chunk part after threshold + dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], + down.ConstData()[dir], // Traff before chunk + dir, + stgTime) * before + + tariff->GetPriceWithTraffType(up.ConstData()[dir], + dt[dir], // Traff after chunk + dir, + stgTime) * after; + } + else + { + dc = tariff->GetPriceWithTraffType(up.ConstData()[dir], + down.ConstData()[dir], + dir, + stgTime) * len; + } + + if (freeMb.ConstData() <= 0) // FreeMb is exhausted + cost = dc; + else if (freeMb.ConstData() < dc) // FreeMb is partially exhausted + cost = dc - freeMb.ConstData(); + + property.stat.freeMb -= dc; + property.stat.cash -= cost; + cash.ModifyTime(); + freeMb.ModifyTime(); + } + +down = dt; +sessionDownload[dir] += len; + +//Add detailed stat + +if (!settings->GetWriteFreeMbTraffCost() && + freeMb.ConstData() >= 0) + cost = 0; + +#ifdef TRAFF_STAT_WITH_PORTS +IP_DIR_PAIR idp(ip, dir, port); +#else +IP_DIR_PAIR idp(ip, dir); +#endif + +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))); + } +else + { + lb->second.cash += cost; + lb->second.down += len; + } +} +//----------------------------------------------------------------------------- +void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +currIP.AddBeforeNotifier(n); +} +//----------------------------------------------------------------------------- +void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +currIP.DelBeforeNotifier(n); +} +//----------------------------------------------------------------------------- +void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +currIP.AddAfterNotifier(n); +} +//----------------------------------------------------------------------------- +void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +currIP.DelAfterNotifier(n); +} +//----------------------------------------------------------------------------- +void USER::OnAdd() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +string scriptOnAdd = settings->GetScriptDir() + "/OnUserAdd"; + +if (access(scriptOnAdd.c_str(), X_OK) == 0) + { + string scriptOnAddParams; + strprintf(&scriptOnAddParams, + "%s \"%s\"", + scriptOnAdd.c_str(), + login.c_str()); + + ScriptExec(scriptOnAddParams); + } +else + { + WriteServLog("Script %s cannot be executed. File not found.", scriptOnAdd.c_str()); + } +} +//----------------------------------------------------------------------------- +void USER::OnDelete() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +string scriptOnDel = settings->GetScriptDir() + "/OnUserDel"; + +if (access(scriptOnDel.c_str(), X_OK) == 0) + { + string scriptOnDelParams; + strprintf(&scriptOnDelParams, + "%s \"%s\"", + scriptOnDel.c_str(), + login.c_str()); + + ScriptExec(scriptOnDelParams); + } +else + { + WriteServLog("Script %s cannot be executed. File not found.", scriptOnDel.c_str()); + } + +Run(); +} +//----------------------------------------------------------------------------- +int USER::WriteDetailStat(bool hard) +{ +printfd(__FILE__, "USER::WriteDetailedStat() - saved size = %d\n", traffStatSaved.second.size()); + +if (!traffStatSaved.second.empty()) + { + if (store->WriteDetailedStat(traffStatSaved.second, traffStatSaved.first, login)) + { + printfd(__FILE__, "USER::WriteDetailStat() - failed to write detail stat from queue\n"); + WriteServLog("Cannot write detail stat from queue (of size %d recs) for user %s.", traffStatSaved.second.size(), login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + return -1; + } + traffStatSaved.second.erase(traffStatSaved.second.begin(), traffStatSaved.second.end()); + } + +TRAFF_STAT ts; + + { + STG_LOCKER lock(&mutex, __FILE__, __LINE__); + ts.swap(traffStat); + } + +printfd(__FILE__, "USER::WriteDetailedStat() - size = %d\n", ts.size()); + +if (ts.size() && !disabledDetailStat) + { + if (store->WriteDetailedStat(ts, lastWriteDeatiledStat, login)) + { + printfd(__FILE__, "USER::WriteDetailStat() - failed to write current detail stat\n"); + WriteServLog("Cannot write detail stat for user %s.", login.c_str()); + WriteServLog("%s", store->GetStrError().c_str()); + if (!hard) + { + printfd(__FILE__, "USER::WriteDetailStat() - pushing detail stat to queue\n"); + STG_LOCKER lock(&mutex, __FILE__, __LINE__); + traffStatSaved.second.swap(ts); + traffStatSaved.first = lastWriteDeatiledStat; + } + return -1; + } + } +lastWriteDeatiledStat = stgTime; +return 0; +} +//----------------------------------------------------------------------------- +double USER::GetPassiveTimePart() const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +static int daysInMonth[12] = +{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +struct tm tms; +time_t t = stgTime; +localtime_r(&t, &tms); + +time_t secMonth = daysInMonth[(tms.tm_mon + 11) % 12] * 24 * 3600; // Previous month + +if (tms.tm_year % 4 == 0 && tms.tm_mon == 1) + { + // Leap year + secMonth += 24 * 3600; + } + +int dt = secMonth - passiveTime; + +if (dt < 0) + dt = 0; + +return double(dt) / (secMonth); +} +//----------------------------------------------------------------------------- +void USER::SetPassiveTimeAsNewUser() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +time_t t = stgTime; +struct tm tm; +localtime_r(&t, &tm); +int daysCurrMon = DaysInCurrentMonth(); +double pt = (tm.tm_mday - 1) / (double)daysCurrMon; + +passiveTime = (time_t)(pt * 24 * 3600 * daysCurrMon); +} +//----------------------------------------------------------------------------- +void USER::MidnightResetSessionStat() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (connected) + { + Disconnect(true, "fake"); + Connect(true); + } +} +//----------------------------------------------------------------------------- +void USER::ProcessNewMonth() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +// Reset traff +if (connected) + { + Disconnect(true, "fake"); + } +DIR_TRAFF zeroTarff; + +WriteMonthStat(); + +up = zeroTarff; +down = zeroTarff; + +if (connected) + { + Connect(true); + } + +// Set new tariff +if (nextTariff.ConstData() != "") + { + const TARIFF * nt; + nt = tariffs->FindByName(nextTariff); + if (nt == NULL) + { + WriteServLog("Cannot change tariff for user %s. Tariff %s not exist.", + login.c_str(), property.tariffName.Get().c_str()); + } + else + { + property.tariffName.Set(nextTariff, sysAdmin, login, store); + tariff = nt; + } + ResetNextTariff(); + WriteConf(); + } +} +//----------------------------------------------------------------------------- +void USER::ProcessDayFeeSpread() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (passive.ConstData()) + return; + +double f = tariff->GetFee() / DaysInCurrentMonth(); + +if (f == 0.0) + return; + +double c = cash; +property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); +ResetPassiveTime(); +} +//----------------------------------------------------------------------------- +void USER::ProcessDayFee() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +double passiveTimePart = 1.0; +if (!settings->GetFullFee()) + { + passiveTimePart = GetPassiveTimePart(); + } +else + { + if (passive.ConstData()) + { + printfd(__FILE__, "Don't charge fee `cause we are passive\n"); + return; + } + } +double f = tariff->GetFee() * passiveTimePart; + +ResetPassiveTime(); + +if (f == 0.0) + return; + +double c = cash; +printfd(__FILE__, "login: %8s Fee=%f PassiveTimePart=%f fee=%f\n", + login.c_str(), + tariff->GetFee(), + passiveTimePart, + f); +property.cash.Set(c - f, sysAdmin, login, store, "Subscriber fee charge"); +} +//----------------------------------------------------------------------------- +void USER::SetPrepaidTraff() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +property.freeMb.Set(tariff->GetFree(), sysAdmin, login, store, "Prepaid traffic"); +} +//----------------------------------------------------------------------------- +int USER::AddMessage(STG_MSG * msg) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (SendMessage(*msg)) + { + if (store->AddMessage(msg, login)) + { + errorStr = store->GetStrError(); + WriteServLog("Error adding message: '%s'", errorStr.c_str()); + printfd(__FILE__, "Error adding message: '%s'\n", errorStr.c_str()); + return -1; + } + messages.push_back(*msg); + } +else + { + if (msg->header.repeat > 0) + { + msg->header.repeat--; + #ifndef DEBUG + //TODO: gcc v. 4.x generate ICE on x86_64 + msg->header.lastSendTime = time(NULL); + #else + msg->header.lastSendTime = stgTime; + #endif + if (store->AddMessage(msg, login)) + { + errorStr = store->GetStrError(); + WriteServLog("Error adding repeatable message: '%s'", errorStr.c_str()); + printfd(__FILE__, "Error adding repeatable message: '%s'\n", errorStr.c_str()); + return -1; + } + messages.push_back(*msg); + } + } +return 0; +} +//----------------------------------------------------------------------------- +int USER::SendMessage(STG_MSG & msg) const +{ +// No lock `cause we are already locked from caller +int ret = -1; +set::iterator it(authorizedBy.begin()); +while (it != authorizedBy.end()) + { + if (!(*it++)->SendMessage(msg, currIP)) + ret = 0; + } +if (!ret) + { +#ifndef DEBUG + //TODO: gcc v. 4.x generate ICE on x86_64 + msg.header.lastSendTime = time(NULL); +#else + msg.header.lastSendTime = stgTime; +#endif + msg.header.repeat--; + } +return ret; +} +//----------------------------------------------------------------------------- +void USER::ScanMessage() +{ +// No lock `cause we are already locked from caller +// We need not check for the authorizedBy `cause it has already checked by caller + +std::list::iterator it(messages.begin()); +while (it != messages.end()) + { + if (settings->GetMessageTimeout() > 0 && + difftime(stgTime, it->header.creationTime) > settings->GetMessageTimeout()) + { + // Timeout exceeded + if (store->DelMessage(it->header.id, login)) + { + WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str()); + printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str()); + } + messages.erase(it++); + continue; + } + if (it->GetNextSendTime() <= stgTime) + { + if (SendMessage(*it)) + { + // We need to check all messages in queue for timeout + ++it; + continue; + } + if (it->header.repeat < 0) + { + if (store->DelMessage(it->header.id, login)) + { + WriteServLog("Error deleting message: '%s'", store->GetStrError().c_str()); + printfd(__FILE__, "Error deleting message: '%s'\n", store->GetStrError().c_str()); + } + messages.erase(it++); + } + else + { + if (store->EditMessage(*it, login)) + { + WriteServLog("Error modifying message: '%s'", store->GetStrError().c_str()); + printfd(__FILE__, "Error modifying message: '%s'\n", store->GetStrError().c_str()); + } + ++it; + } + } + } +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CHG_PASSIVE_NOTIFIER::Notify(const int & oldPassive, const int & newPassive) +{ +if (newPassive && !oldPassive) + user->property.cash.Set(user->cash - user->tariff->GetPassiveCost(), + user->sysAdmin, + user->login, + user->store, + "Freeze"); +} +//----------------------------------------------------------------------------- +void CHG_TARIFF_NOTIFIER::Notify(const string &, const string & newTariff) +{ +user->tariff = user->tariffs->FindByName(newTariff); +} +//----------------------------------------------------------------------------- +void CHG_CASH_NOTIFIER::Notify(const double & oldCash, const double & newCash) +{ +user->lastCashAddTime = *const_cast(&stgTime); +user->lastCashAdd = newCash - oldCash; +} +//----------------------------------------------------------------------------- +void CHG_IP_NOTIFIER::Notify(const uint32_t & from, const uint32_t & to) +{ + printfd(__FILE__, "Change IP from %s to %s\n", inet_ntostring(from).c_str(), inet_ntostring(to).c_str()); + if (from != 0) + if (user->connected) + user->Disconnect(false, "Change IP"); + if (to != 0) + if (user->IsInetable()) + user->Connect(false); +} +//----------------------------------------------------------------------------- diff --git a/projects/stargazer/user_impl.h b/projects/stargazer/user_impl.h new file mode 100644 index 00000000..1c84ba1c --- /dev/null +++ b/projects/stargazer/user_impl.h @@ -0,0 +1,303 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.48 $ + $Date: 2010/11/03 10:50:03 $ + $Author: faust $ + */ + +#ifndef USER_H +#define USER_H + +#include +#include +#include +#include +#include + +#include "os_int.h" +#include "stg_const.h" +#include "user_stat.h" +#include "user_conf.h" +#include "user_ips.h" +#include "user_property.h" +#include "base_auth.h" +#include "stg_message.h" +#include "noncopyable.h" + +using namespace std; + +//----------------------------------------------------------------------------- +class USER; +class TARIFF; +class TARIFFS; +class ADMIN; +typedef list::iterator user_iter; +typedef list::const_iterator const_user_iter; +//----------------------------------------------------------------------------- +class USER_ID_GENERATOR +{ +friend class USER; +private: + USER_ID_GENERATOR() {} + int GetNextID() { static int id = 0; return id++; } +}; +//----------------------------------------------------------------------------- +class CHG_PASSIVE_NOTIFIER : public PROPERTY_NOTIFIER_BASE, + private NONCOPYABLE +{ +public: + CHG_PASSIVE_NOTIFIER(USER * u) : user(u) {} + void Notify(const int & oldPassive, const int & newPassive); + +private: + USER * user; +}; +//----------------------------------------------------------------------------- +class CHG_TARIFF_NOTIFIER : public PROPERTY_NOTIFIER_BASE, + private NONCOPYABLE +{ +public: + CHG_TARIFF_NOTIFIER(USER * u) : user(u) {} + void Notify(const string & oldTariff, const string & newTariff); + +private: + USER * user; +}; +//----------------------------------------------------------------------------- +class CHG_CASH_NOTIFIER : public PROPERTY_NOTIFIER_BASE, + private NONCOPYABLE +{ +public: + CHG_CASH_NOTIFIER(USER * u) : user(u) {} + void Notify(const double & oldCash, const double & newCash); + +private: + USER * user; +}; +//----------------------------------------------------------------------------- +class CHG_IP_NOTIFIER : public PROPERTY_NOTIFIER_BASE, + private NONCOPYABLE +{ +public: + CHG_IP_NOTIFIER(USER * u) : user(u) {} + void Notify(const uint32_t & oldCash, const uint32_t & newCash); + +private: + USER * user; +}; +//----------------------------------------------------------------------------- +class USER +{ +friend class CHG_PASSIVE_NOTIFIER; +friend class CHG_TARIFF_NOTIFIER; +friend class CHG_CASH_NOTIFIER; +friend class CHG_IP_NOTIFIER; +public: + USER(const SETTINGS * settings, + const BASE_STORE * store, + const TARIFFS * tariffs, + const ADMIN & sysAdmin, + const map * ipIndex); + USER(const USER & u); + ~USER(); + + int ReadConf(); + int ReadStat(); + int WriteConf(); + int WriteStat(); + int WriteMonthStat(); + + string const & GetLogin() const { return login; } + void SetLogin(string const & l); + + uint32_t GetCurrIP() const { return currIP; } + time_t GetCurrIPModificationTime() const { return currIP.ModificationTime(); } + + void AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE *); + void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE *); + + void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE *); + void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE *); + + int GetID() const { return id; } + + double GetPassiveTimePart() const; + void ResetPassiveTime() { passiveTime = 0; } + void SetPassiveTimeAsNewUser(); + + int WriteDetailStat(bool hard = false); + + const TARIFF * GetTariff() const { return tariff; } + void ResetNextTariff() { nextTariff = ""; } + + #ifdef TRAFF_STAT_WITH_PORTS + void AddTraffStatU(int dir, uint32_t ip, uint16_t port, uint32_t len); + void AddTraffStatD(int dir, uint32_t ip, uint16_t port, uint32_t len); + #else + void AddTraffStatU(int dir, uint32_t ip, uint32_t len); + void AddTraffStatD(int dir, uint32_t ip, uint32_t len); + #endif + + const DIR_TRAFF & GetSessionUpload() const { return sessionUpload; } + const DIR_TRAFF & GetSessionDownload() const { return sessionDownload; } + + bool GetConnected() const { return connected; } + time_t GetConnectedModificationTime() const { return connected.ModificationTime(); } + int GetAuthorized() const { return authorizedBy.size(); } + int Authorize(uint32_t ip, const string & iface, uint32_t enabledDirs, const BASE_AUTH * auth); + void Unauthorize(const BASE_AUTH * auth); + bool IsAuthorizedBy(const BASE_AUTH * auth) const; + void OnAdd(); + void OnDelete(); + + int AddMessage(STG_MSG * msg); + + void UpdatePingTime(time_t t = 0); + time_t GetPingTime() const { return pingTime; } + + void PrintUser() const; + void Run(); + + const string & GetStrError() const { return errorStr; } + + USER_PROPERTIES property; + + void SetDeleted() { deleted = true; } + bool GetDeleted() const { return deleted; } + + time_t GetLastWriteStatTime() const { return lastWriteStat; } + + void MidnightResetSessionStat(); + void ProcessDayFee(); + void SetPrepaidTraff(); + void ProcessDayFeeSpread(); + void ProcessNewMonth(); + + bool IsInetable(); + string GetEnabledDirs(); + +private: + STG_LOGGER & WriteServLog; + + void Connect(bool fakeConnect = false); + void Disconnect(bool fakeDisconnect, const std::string & reason); + int SaveMonthStat(int month, int year); + + int SendMessage(STG_MSG & msg) const; + void ScanMessage(); + time_t lastScanMessages; + + string login; + int id; + bool __connected; + USER_PROPERTY connected; + + bool enabledDirs[DIR_NUM]; + + USER_ID_GENERATOR userIDGenerator; + + uint32_t __currIP; // ôÅËÕÝÉÊ ÁÄÒÅÓ ÐÏÌØÚÏ×ÁÔÅÌÑ + USER_PROPERTY currIP; + + /* + ë ÔÏÍÕ ÍÏÍÅÎÔÕ ËÁË ÍÙ ÕÖÅ ÎÅ Á×ÔÏÒÉÚÏ×ÁÎÉÙ, ÎÏ ÅÝÅ ÎÅ ×ÙÐÏÌÎÅÎ Disconnect, + currIP ÕÖÅ ÓÂÒÏÛÅÎ. ðÏÓÌÅÄÎÅÅ ÚÎÁÞÅÎÉÅ currIP ÓÏÈÒÁÎÑÅÍ × lastIPForDisconnect + */ + uint32_t lastIPForDisconnect; + + time_t pingTime; + + const ADMIN sysAdmin; + const BASE_STORE * store; + + const TARIFFS * tariffs; + const TARIFF * tariff; + + TRAFF_STAT traffStat; + std::pair traffStatSaved; + + const SETTINGS * settings; + + set authorizedBy; + + const map * ipIndex; + + list messages; + + bool deleted; + + time_t lastWriteStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÓÔÁÔÉÓÔÉËÉ + time_t lastWriteDeatiledStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÄÅÔÁÌØÎÏÊ ÓÔÁÔÉÓÔÉËÉ + + // Properties + USER_PROPERTY & cash; + USER_PROPERTY & up; + USER_PROPERTY & down; + USER_PROPERTY & lastCashAdd; + USER_PROPERTY & passiveTime; + USER_PROPERTY & lastCashAddTime; + USER_PROPERTY & freeMb; + USER_PROPERTY & lastActivityTime; + USER_PROPERTY & password; + USER_PROPERTY & passive; + USER_PROPERTY & disabled; + USER_PROPERTY & disabledDetailStat; + USER_PROPERTY & alwaysOnline; + USER_PROPERTY & tariffName; + USER_PROPERTY & nextTariff; + USER_PROPERTY & address; + USER_PROPERTY & note; + USER_PROPERTY & group; + USER_PROPERTY & email; + USER_PROPERTY & phone; + USER_PROPERTY & realName; + USER_PROPERTY & credit; + USER_PROPERTY & creditExpire; + USER_PROPERTY & ips; + USER_PROPERTY & userdata0; + USER_PROPERTY & userdata1; + USER_PROPERTY & userdata2; + USER_PROPERTY & userdata3; + USER_PROPERTY & userdata4; + USER_PROPERTY & userdata5; + USER_PROPERTY & userdata6; + USER_PROPERTY & userdata7; + USER_PROPERTY & userdata8; + USER_PROPERTY & userdata9; + + // End properties + + DIR_TRAFF sessionUpload; + DIR_TRAFF sessionDownload; + + CHG_PASSIVE_NOTIFIER passiveNotifier; + CHG_TARIFF_NOTIFIER tariffNotifier; + CHG_CASH_NOTIFIER cashNotifier; + CHG_IP_NOTIFIER ipNotifier; + + mutable pthread_mutex_t mutex; + + string errorStr; +}; +//----------------------------------------------------------------------------- + +#endif //USER_H diff --git a/projects/stargazer/users.cpp b/projects/stargazer/users.cpp deleted file mode 100644 index 84a10227..00000000 --- a/projects/stargazer/users.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Date: 27.10.2002 - */ - -/* - * Author : Boris Mikhailenko - */ - -/* - $Revision: 1.61 $ - $Date: 2010/09/13 05:56:42 $ - $Author: faust $ - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "settings.h" -#include "users.h" -#include "user.h" -#include "common.h" -#include "stg_timer.h" - -using namespace std; - -extern const volatile time_t stgTime; - -//#define USERS_DEBUG 1 - -//----------------------------------------------------------------------------- -USERS::USERS(SETTINGS * s, BASE_STORE * st, TARIFFS * t, const ADMIN & sa) - : users(), - usersToDelete(), - userIPNotifiersBefore(), - userIPNotifiersAfter(), - ipIndex(), - loginIndex(), - settings(s), - tariffs(t), - store(st), - sysAdmin(sa), - WriteServLog(GetStgLogger()), - nonstop(false), - isRunning(false), - mutex(), - thread(), - handle(0), - searchDescriptors(), - onAddNotifiers(), - onDelNotifiers() -{ -pthread_mutexattr_t attr; -pthread_mutexattr_init(&attr); -pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -pthread_mutex_init(&mutex, &attr); -} -//----------------------------------------------------------------------------- -USERS::~USERS() -{ -pthread_mutex_destroy(&mutex); -} -//----------------------------------------------------------------------------- -int USERS::FindByNameNonLock(const string & login, user_iter * user) const -{ -map::const_iterator iter; -iter = loginIndex.find(login); -if (iter != loginIndex.end()) - { - if (user) - *user = iter->second; - return 0; - } -return -1; -} -//----------------------------------------------------------------------------- -int USERS::FindByName(const string & login, user_iter * user) const -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -return FindByNameNonLock(login, user); -} -//----------------------------------------------------------------------------- -bool USERS::TariffInUse(const string & tariffName) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -list::iterator iter; -iter = users.begin(); -while (iter != users.end()) - { - if (iter->property.tariffName.Get() == tariffName) - return true; - ++iter; - } -return false; -} -//----------------------------------------------------------------------------- -int USERS::Add(const string & login, const ADMIN & admin) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -const PRIV * priv = admin.GetPriv(); - -if (!priv->userAddDel) - { - WriteServLog("%s tried to add user \'%s\'. Access denied.", - admin.GetLogStr().c_str(), login.c_str()); - /*errorStr = "Admin \'" + admin.GetLogin() + - "\': tried to add user \'" + ud->login + "\'. Access denied.";*/ - return -1; - } - -////// -if (store->AddUser(login)) - { - //TODO - //WriteServLog("Admin \'%s\': tried to add user \'%s\'. Access denied.", - // admin.GetLogin().c_str(), ud->login.c_str()); - return -1; - } -////// - -USER u(settings, store, tariffs, sysAdmin, &ipIndex); - -/*struct tm * tms; -time_t t = stgTime; - -tms = localtime(&t); - -tms->tm_hour = 0; -tms->tm_min = 0; -tms->tm_sec = 0; - -if (settings->GetDayResetTraff() > tms->tm_mday) - tms->tm_mon -= 1; - -tms->tm_mday = settings->GetDayResetTraff();*/ - -u.SetLogin(login); - -u.SetPassiveTimeAsNewUser(); - -u.WriteConf(); -u.WriteStat(); - -WriteServLog("%s User \'%s\' added.", - admin.GetLogStr().c_str(), login.c_str()); - -u.OnAdd(); - -users.push_front(u); - -AddUserIntoIndexes(users.begin()); -SetUserNotifiers(users.begin()); - -// õ×ÅÄÏÍÌÑÅÍ ×ÓÅÈ ÖÅÌÁÀÝÉÈ, ÞÔÏ ÄÏÂÁ×ÌÅÎ ÎÏ×ÙÊ ÐÏÌØÚÏ×ÁÔÅÌØ -set *>::iterator ni = onAddNotifiers.begin(); -while (ni != onAddNotifiers.end()) - { - (*ni)->Notify(users.begin()); - ++ni; - } - -return 0; -} -//----------------------------------------------------------------------------- -void USERS::Del(const string & login, const ADMIN & admin) -{ -const PRIV * priv = admin.GetPriv(); -user_iter u; - -if (!priv->userAddDel) - { - WriteServLog("%s tried to remove user \'%s\'. Access denied.", - admin.GetLogStr().c_str(), login.c_str()); - return; - } - - - { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - - if (FindByNameNonLock(login, &u)) - { - WriteServLog("%s tried to delete user \'%s\': not found.", - admin.GetLogStr().c_str(), - login.c_str()); - return; - } - } - -set *>::iterator ni = onDelNotifiers.begin(); -while (ni != onDelNotifiers.end()) - { - (*ni)->Notify(u); - ++ni; - } - - { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - - u->OnDelete(); - u->SetDeleted(); - - USER_TO_DEL utd; - utd.iter = u; - utd.delTime = stgTime; - usersToDelete.push_back(utd); - - UnSetUserNotifiers(u); - DelUserFromIndexes(u); - - WriteServLog("%s User \'%s\' deleted.", - admin.GetLogStr().c_str(), login.c_str()); - - } -} -//----------------------------------------------------------------------------- -int USERS::ReadUsers() -{ -vector usersList; -usersList.clear(); -if (store->GetUsersList(&usersList) < 0) - { - WriteServLog(store->GetStrError().c_str()); - exit(1); - } - -user_iter ui; - -for (unsigned int i = 0; i < usersList.size(); i++) - { - USER u(settings, store, tariffs, sysAdmin, &ipIndex); - - u.SetLogin(usersList[i]); - users.push_front(u); - ui = users.begin(); - - AddUserIntoIndexes(ui); - SetUserNotifiers(ui); - - if (ui->ReadConf() < 0) - return -1; - - if (ui->ReadStat() < 0) - return -1; - } - -return 0; -} -//----------------------------------------------------------------------------- -void * USERS::Run(void * d) -{ -printfd(__FILE__, "=====================| pid: %d |===================== \n", getpid()); -USERS * us = (USERS*) d; - -struct tm t; -time_t tt = stgTime; -localtime_r(&tt, &t); - -int min = t.tm_min; -int day = t.tm_mday; - -printfd(__FILE__,"Day = %d Min = %d\n", day, min); - -time_t touchTime = stgTime - MONITOR_TIME_DELAY_SEC; -string monFile = us->settings->GetMonitorDir() + "/users_r"; -printfd(__FILE__, "Monitor=%d file USERS %s\n", us->settings->GetMonitoring(), monFile.c_str()); - -us->isRunning = true; -while (us->nonstop) - { - //printfd(__FILE__,"New Minute. old = %02d current = %02d\n", min, t->tm_min); - //printfd(__FILE__,"New Day. old = %2d current = %2d\n", day, t->tm_mday); - - for_each(us->users.begin(), us->users.end(), mem_fun_ref(&USER::Run)); - - tt = stgTime; - localtime_r(&tt, &t); - - if (min != t.tm_min) - { - printfd(__FILE__,"Sec = %d\n", stgTime); - printfd(__FILE__,"New Minute. old = %d current = %d\n", min, t.tm_min); - min = t.tm_min; - - us->NewMinute(t); - } - - if (day != t.tm_mday) - { - printfd(__FILE__,"Sec = %d\n", stgTime); - printfd(__FILE__,"New Day. old = %d current = %d\n", day, t.tm_mday); - day = t.tm_mday; - us->NewDay(t); - } - - if (us->settings->GetMonitoring() && (touchTime + MONITOR_TIME_DELAY_SEC <= stgTime)) - { - //printfd(__FILE__, "Monitor=%d file TRAFFCOUNTER %s\n", tc->monitoring, monFile.c_str()); - touchTime = stgTime; - TouchFile(monFile.c_str()); - } - - stgUsleep(100000); - } //while (us->nonstop) - -user_iter ui = us->users.begin(); -while (ui != us->users.end()) - { - us->UnSetUserNotifiers(ui); - us->DelUserFromIndexes(ui); - ui++; - } - -list::iterator iter; -iter = us->usersToDelete.begin(); -while (iter != us->usersToDelete.end()) - { - iter->delTime -= 2 * userDeleteDelayTime; - ++iter; - } -us->RealDelUser(); - -us->isRunning = false; - -return NULL; -} -//----------------------------------------------------------------------------- -void USERS::NewMinute(const struct tm & t) -{ -//Write traff, reset session traff. Fake disconnect-connect -if (t.tm_hour == 23 && t.tm_min == 59) - { - printfd(__FILE__,"MidnightResetSessionStat\n"); - for_each(users.begin(), users.end(), mem_fun_ref(&USER::MidnightResetSessionStat)); - } - -if (TimeToWriteDetailStat(t)) - { - //printfd(__FILE__, "USER::WriteInetStat\n"); - int usersCnt = 0; - - // ðÉÛÅÍ ÀÚÅÒÏ× ÞÁÓÔÑÍÉ. ÷ ÐÅÒÅÒÙ×ÁÈ ×ÙÚÙ×ÁÅÍ USER::Run - list::iterator usr = users.begin(); - while (usr != users.end()) - { - usersCnt++; - usr->WriteDetailStat(); - usr++; - if (usersCnt % 10 == 0) - for_each(users.begin(), users.end(), mem_fun_ref(&USER::Run)); - } - } - -RealDelUser(); -} -//----------------------------------------------------------------------------- -void USERS::NewDay(const struct tm & t) -{ -struct tm t1; -time_t tt = stgTime; -localtime_r(&tt, &t1); -int dayFee = settings->GetDayFee(); - -if (dayFee == 0) - dayFee = DaysInCurrentMonth(); - -printfd(__FILE__, "DayFee = %d\n", dayFee); -printfd(__FILE__, "Today = %d DayResetTraff = %d\n", t1.tm_mday, settings->GetDayResetTraff()); -printfd(__FILE__, "DayFeeIsLastDay = %d\n", settings->GetDayFeeIsLastDay()); - -if (!settings->GetDayFeeIsLastDay()) - { - printfd(__FILE__, "DayResetTraff - 1 -\n"); - DayResetTraff(t1); - //printfd(__FILE__, "DayResetTraff - 1 - 1 -\n"); - } - -if (settings->GetSpreadFee()) - { - printfd(__FILE__, "Spread DayFee\n"); - for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessDayFeeSpread)); - } -else - { - if (t.tm_mday == dayFee) - { - printfd(__FILE__, "DayFee\n"); - for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessDayFee)); - } - } - -if (settings->GetDayFeeIsLastDay()) - { - printfd(__FILE__, "DayResetTraff - 2 -\n"); - DayResetTraff(t1); - } -} -//----------------------------------------------------------------------------- -void USERS::DayResetTraff(const struct tm & t1) -{ -int dayResetTraff = settings->GetDayResetTraff(); -if (dayResetTraff == 0) - dayResetTraff = DaysInCurrentMonth(); -if (t1.tm_mday == dayResetTraff) - { - printfd(__FILE__, "ResetTraff\n"); - for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessNewMonth)); - for_each(users.begin(), users.end(), mem_fun_ref(&USER::SetPrepaidTraff)); - } -} -//----------------------------------------------------------------------------- -int USERS::Start() -{ -if (ReadUsers()) - { - WriteServLog("USERS: Error: Cannot read users!"); - return -1; - } - -nonstop = true; -if (pthread_create(&thread, NULL, Run, this)) - { - WriteServLog("USERS: Error: Cannot start thread!"); - return -1; - } -return 0; -} -//----------------------------------------------------------------------------- -int USERS::Stop() -{ -printfd(__FILE__, "USERS::Stop()\n"); - -if (!isRunning) - { - //printfd(__FILE__, "Alredy stopped\n"); - return 0; - } - -nonstop = false; - -//5 seconds to thread stops itself -unsigned i; -for (i = 0; i < 25 * (users.size() / 50 + 1); i++) - { - if (!isRunning) - break; - - usleep(200000); - } - -//after 5 seconds waiting thread still running. now kill it -if (isRunning) - { - printfd(__FILE__, "kill USERS thread.\n"); - //TODO pthread_cancel() - if (pthread_kill(thread, SIGINT)) - { - //errorStr = "Cannot kill USERS thread."; - //printfd(__FILE__, "Cannot kill USERS thread.\n"); - //return 0; - } - printfd(__FILE__, "USERS killed\n"); - } - -printfd(__FILE__, "Before USERS::Run()\n"); -for_each(users.begin(), users.end(), mem_fun_ref(&USER::Run)); - -// 'cause bind2st accepts only constant first param -for (list::iterator it = users.begin(); - it != users.end(); - ++it) - it->WriteDetailStat(true); - -for_each(users.begin(), users.end(), mem_fun_ref(&USER::WriteStat)); -for_each(users.begin(), users.end(), mem_fun_ref(&USER::WriteConf)); - -printfd(__FILE__, "USERS::Stop()\n"); -return 0; -} -//----------------------------------------------------------------------------- -void USERS::RealDelUser() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -printfd(__FILE__, "RealDelUser() users to del: %d\n", usersToDelete.size()); - -list::iterator iter; -iter = usersToDelete.begin(); -while (iter != usersToDelete.end()) - { - printfd(__FILE__, "RealDelUser() user=%s\n", iter->iter->GetLogin().c_str()); - if (iter->delTime + userDeleteDelayTime < stgTime) - { - printfd(__FILE__, "RealDelUser() user=%s removed from DB\n", iter->iter->GetLogin().c_str()); - if (store->DelUser(iter->iter->GetLogin())) - { - WriteServLog("Error removing user \'%s\' from database.", iter->iter->GetLogin().c_str()); - } - users.erase(iter->iter); - usersToDelete.erase(iter++); - } - else - { - ++iter; - } - } -return; -} -//----------------------------------------------------------------------------- -int USERS::GetUserNum() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -return users.size(); -} -//----------------------------------------------------------------------------- -void USERS::AddToIPIdx(user_iter user) -{ -printfd(__FILE__, "USERS: Add IP Idx\n"); -uint32_t ip = user->GetCurrIP(); -//assert(ip && "User has non-null ip"); -if (!ip) - return; // User has disconnected - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -const map::iterator it( - ipIndex.lower_bound(ip) -); - -assert((it == ipIndex.end() || it->first != ip) && "User is not in index"); - -ipIndex.insert(it, std::make_pair(ip, user)); -} -//----------------------------------------------------------------------------- -void USERS::DelFromIPIdx(uint32_t ip) -{ -printfd(__FILE__, "USERS: Del IP Idx\n"); -assert(ip && "User has non-null ip"); - -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -const map::iterator it( - ipIndex.find(ip) -); - -//assert(it != ipIndex.end() && "User is in index"); -if (it == ipIndex.end()) - return; // User has not been added - -ipIndex.erase(it); -} -//----------------------------------------------------------------------------- -int USERS::FindByIPIdx(uint32_t ip, user_iter * usr) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -map::iterator it; -it = ipIndex.find(ip); - -if (it == ipIndex.end()) - { - //printfd(__FILE__, "User NOT found in IP_Index!!!\n"); - return -1; - } -*usr = it->second; -//printfd(__FILE__, "User found in IP_Index\n"); -return 0; -} -//----------------------------------------------------------------------------- -void USERS::AddNotifierUserAdd(NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -onAddNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -void USERS::DelNotifierUserAdd(NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -//printfd(__FILE__, "DelNotifierUserAdd\n"); -onAddNotifiers.erase(n); -} -//----------------------------------------------------------------------------- -void USERS::AddNotifierUserDel(NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -onDelNotifiers.insert(n); -} -//----------------------------------------------------------------------------- -void USERS::DelNotifierUserDel(NOTIFIER_BASE * n) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -onDelNotifiers.erase(n); -} -//----------------------------------------------------------------------------- -int USERS::OpenSearch() -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -handle++; -searchDescriptors[handle] = users.begin(); -return handle; -} -//----------------------------------------------------------------------------- -int USERS::SearchNext(int h, user_iter * u) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -if (searchDescriptors.find(h) == searchDescriptors.end()) - { - WriteServLog("USERS. Incorrect search handle."); - return -1; - } - -if (searchDescriptors[h] == users.end()) - return -1; - -while (searchDescriptors[h]->GetDeleted()) - { - ++searchDescriptors[h]; - if (searchDescriptors[h] == users.end()) - { - return -1; - } - } - -*u = searchDescriptors[h]; - -++searchDescriptors[h]; - -return 0; -} -//----------------------------------------------------------------------------- -int USERS::CloseSearch(int h) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -if (searchDescriptors.find(h) != searchDescriptors.end()) - { - searchDescriptors.erase(searchDescriptors.find(h)); - return 0; - } - -WriteServLog("USERS. Incorrect search handle."); -return -1; -} -//----------------------------------------------------------------------------- -void USERS::SetUserNotifiers(user_iter user) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -PROPERTY_NOTIFER_IP_BEFORE nb(*this, user); -PROPERTY_NOTIFER_IP_AFTER na(*this, user); - -userIPNotifiersBefore.push_front(nb); -userIPNotifiersAfter.push_front(na); - -user->AddCurrIPBeforeNotifier(&(*userIPNotifiersBefore.begin())); -user->AddCurrIPAfterNotifier(&(*userIPNotifiersAfter.begin())); -} -//----------------------------------------------------------------------------- -void USERS::UnSetUserNotifiers(user_iter user) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); - -list::iterator bi; -list::iterator ai; - -bi = userIPNotifiersBefore.begin(); -while (bi != userIPNotifiersBefore.end()) - { - if (bi->GetUser() == user) - { - bi->GetUser()->DelCurrIPBeforeNotifier(&(*bi)); - userIPNotifiersBefore.erase(bi); - //printfd(__FILE__, "Notifier Before removed. User %s\n", bi->GetUser()->GetLogin().c_str()); - break; - } - bi++; - } - -ai = userIPNotifiersAfter.begin(); -while (ai != userIPNotifiersAfter.end()) - { - if (ai->GetUser() == user) - { - ai->GetUser()->DelCurrIPAfterNotifier(&(*ai)); - userIPNotifiersAfter.erase(ai); - //printfd(__FILE__, "Notifier After removed. User %s\n", ai->GetUser()->GetLogin().c_str()); - break; - } - ai++; - } -} -//----------------------------------------------------------------------------- -void USERS::AddUserIntoIndexes(user_iter user) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -loginIndex.insert(pair(user->GetLogin(), user)); -} -//----------------------------------------------------------------------------- -void USERS::DelUserFromIndexes(user_iter user) -{ -STG_LOCKER lock(&mutex, __FILE__, __LINE__); -loginIndex.erase(user->GetLogin()); -} -//----------------------------------------------------------------------------- -bool USERS::TimeToWriteDetailStat(const struct tm & t) -{ -int statTime = settings->GetDetailStatWritePeriod(); - -switch (statTime) - { - case dsPeriod_1: - if (t.tm_min == 0) - return true; - break; - case dsPeriod_1_2: - if (t.tm_min % 30 == 0) - return true; - break; - case dsPeriod_1_4: - if (t.tm_min % 15 == 0) - return true; - break; - case dsPeriod_1_6: - if (t.tm_min % 10 == 0) - return true; - break; - } -return false; -} diff --git a/projects/stargazer/users.h b/projects/stargazer/users.h deleted file mode 100644 index 424958da..00000000 --- a/projects/stargazer/users.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * Author : Boris Mikhailenko - */ - -/* -$Revision: 1.31 $ -$Date: 2010/10/07 20:04:48 $ -$Author: faust $ -*/ - - -#ifndef USERS_H -#define USERS_H - -#include - -#include -#include -#include -#include -#include - -#include "os_int.h" - -#include "settings.h" -#include "user.h" -#include "tariffs.h" -#include "stg_logger.h" -#include "notifer.h" -#include "actions.h" -#include "noncopyable.h" -#include "eventloop.h" - -const int userDeleteDelayTime = 120; - -using namespace std; -class USERS; -//----------------------------------------------------------------------------- -class PROPERTY_NOTIFER_IP_BEFORE: public PROPERTY_NOTIFIER_BASE -{ -public: - PROPERTY_NOTIFER_IP_BEFORE(USERS & us, user_iter u) : users(us), user(u) {}; - void Notify(const uint32_t & oldValue, const uint32_t & newValue); - user_iter GetUser() const { return user; }; -private: - USERS & users; - user_iter user; -}; -//----------------------------------------------------------------------------- -class PROPERTY_NOTIFER_IP_AFTER: public PROPERTY_NOTIFIER_BASE -{ -public: - PROPERTY_NOTIFER_IP_AFTER(USERS & us, user_iter u) : users(us), user(u) {}; - void Notify(const uint32_t & oldValue, const uint32_t & newValue); - user_iter GetUser() const { return user; }; -private: - USERS & users; - user_iter user; -}; -//----------------------------------------------------------------------------- -struct USER_TO_DEL -{ -USER_TO_DEL() - : iter(), - delTime(0) -{}; - -list::iterator iter; -time_t delTime; -}; -//----------------------------------------------------------------------------- -class USERS : private NONCOPYABLE - { - friend class PROPERTY_NOTIFER_IP_BEFORE; - friend class PROPERTY_NOTIFER_IP_AFTER; - -public: - USERS(SETTINGS * s, BASE_STORE * store, TARIFFS * tariffs, const ADMIN & sysAdmin); - ~USERS(); - - int FindByName(const string & login, user_iter * user) const; - int FindByID(int id, user_iter * user); - - bool TariffInUse(const string & tariffName); - - void AddNotifierUserAdd(NOTIFIER_BASE *); - void DelNotifierUserAdd(NOTIFIER_BASE *); - - void AddNotifierUserDel(NOTIFIER_BASE *); - void DelNotifierUserDel(NOTIFIER_BASE *); - - int Add(const string & login, const ADMIN & admin); - void Del(const string & login, const ADMIN & admin); - - int ReadUsers(); - int GetUserNum(); - - int FindByIPIdx(uint32_t ip, user_iter * user); - - int OpenSearch(); - int SearchNext(int handler, user_iter * u); - int CloseSearch(int handler); - - int Start(); - int Stop(); - -private: - void AddToIPIdx(user_iter); - void DelFromIPIdx(uint32_t ip); - - int FindByNameNonLock(const string & login, user_iter * user) const; - int FindByIDNonLock(int id, user_iter * user); - - void RealDelUser(); - void ProcessActions(); - - void SetUserNotifiers(user_iter user); - void UnSetUserNotifiers(user_iter user); - - void AddUserIntoIndexes(user_iter user); - void DelUserFromIndexes(user_iter user); - - static void * Run(void *); - void NewMinute(const struct tm & t); - void NewDay(const struct tm & t); - void DayResetTraff(const struct tm & t); - - bool TimeToWriteDetailStat(const struct tm & t); - - list users; - list usersToDelete; - list userIPNotifiersBefore; - list userIPNotifiersAfter; - - map ipIndex; - map loginIndex; - - SETTINGS * settings; - TARIFFS * tariffs; - BASE_STORE * store; - const ADMIN sysAdmin; - STG_LOGGER & WriteServLog; - - bool nonstop; - bool isRunning; - - mutable pthread_mutex_t mutex; - pthread_t thread; - mutable unsigned int handle; - - mutable map searchDescriptors; - - set *> onAddNotifiers; - set *> onDelNotifiers; - }; -//----------------------------------------------------------------------------- -inline -void PROPERTY_NOTIFER_IP_BEFORE::Notify(const uint32_t & oldValue, - const uint32_t &) -{ -if (!oldValue) - return; - -//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(users, &USERS::DelFromIPIdx, oldValue); -// Using explicit call to assure that index is valid, because fast reconnect with delayed call can result in authorization error -users.DelFromIPIdx(oldValue); -} -//----------------------------------------------------------------------------- -inline -void PROPERTY_NOTIFER_IP_AFTER::Notify(const uint32_t &, - const uint32_t & newValue) -{ -if (!newValue) - return; - -//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(users, &USERS::AddToIPIdx, user); -// Using explicit call to assure that index is valid, because fast reconnect with delayed call can result in authorization error -users.AddToIPIdx(user); -} -//----------------------------------------------------------------------------- -#endif - diff --git a/projects/stargazer/users_impl.cpp b/projects/stargazer/users_impl.cpp new file mode 100644 index 00000000..84a10227 --- /dev/null +++ b/projects/stargazer/users_impl.cpp @@ -0,0 +1,753 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Date: 27.10.2002 + */ + +/* + * Author : Boris Mikhailenko + */ + +/* + $Revision: 1.61 $ + $Date: 2010/09/13 05:56:42 $ + $Author: faust $ + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "settings.h" +#include "users.h" +#include "user.h" +#include "common.h" +#include "stg_timer.h" + +using namespace std; + +extern const volatile time_t stgTime; + +//#define USERS_DEBUG 1 + +//----------------------------------------------------------------------------- +USERS::USERS(SETTINGS * s, BASE_STORE * st, TARIFFS * t, const ADMIN & sa) + : users(), + usersToDelete(), + userIPNotifiersBefore(), + userIPNotifiersAfter(), + ipIndex(), + loginIndex(), + settings(s), + tariffs(t), + store(st), + sysAdmin(sa), + WriteServLog(GetStgLogger()), + nonstop(false), + isRunning(false), + mutex(), + thread(), + handle(0), + searchDescriptors(), + onAddNotifiers(), + onDelNotifiers() +{ +pthread_mutexattr_t attr; +pthread_mutexattr_init(&attr); +pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +pthread_mutex_init(&mutex, &attr); +} +//----------------------------------------------------------------------------- +USERS::~USERS() +{ +pthread_mutex_destroy(&mutex); +} +//----------------------------------------------------------------------------- +int USERS::FindByNameNonLock(const string & login, user_iter * user) const +{ +map::const_iterator iter; +iter = loginIndex.find(login); +if (iter != loginIndex.end()) + { + if (user) + *user = iter->second; + return 0; + } +return -1; +} +//----------------------------------------------------------------------------- +int USERS::FindByName(const string & login, user_iter * user) const +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +return FindByNameNonLock(login, user); +} +//----------------------------------------------------------------------------- +bool USERS::TariffInUse(const string & tariffName) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +list::iterator iter; +iter = users.begin(); +while (iter != users.end()) + { + if (iter->property.tariffName.Get() == tariffName) + return true; + ++iter; + } +return false; +} +//----------------------------------------------------------------------------- +int USERS::Add(const string & login, const ADMIN & admin) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +const PRIV * priv = admin.GetPriv(); + +if (!priv->userAddDel) + { + WriteServLog("%s tried to add user \'%s\'. Access denied.", + admin.GetLogStr().c_str(), login.c_str()); + /*errorStr = "Admin \'" + admin.GetLogin() + + "\': tried to add user \'" + ud->login + "\'. Access denied.";*/ + return -1; + } + +////// +if (store->AddUser(login)) + { + //TODO + //WriteServLog("Admin \'%s\': tried to add user \'%s\'. Access denied.", + // admin.GetLogin().c_str(), ud->login.c_str()); + return -1; + } +////// + +USER u(settings, store, tariffs, sysAdmin, &ipIndex); + +/*struct tm * tms; +time_t t = stgTime; + +tms = localtime(&t); + +tms->tm_hour = 0; +tms->tm_min = 0; +tms->tm_sec = 0; + +if (settings->GetDayResetTraff() > tms->tm_mday) + tms->tm_mon -= 1; + +tms->tm_mday = settings->GetDayResetTraff();*/ + +u.SetLogin(login); + +u.SetPassiveTimeAsNewUser(); + +u.WriteConf(); +u.WriteStat(); + +WriteServLog("%s User \'%s\' added.", + admin.GetLogStr().c_str(), login.c_str()); + +u.OnAdd(); + +users.push_front(u); + +AddUserIntoIndexes(users.begin()); +SetUserNotifiers(users.begin()); + +// õ×ÅÄÏÍÌÑÅÍ ×ÓÅÈ ÖÅÌÁÀÝÉÈ, ÞÔÏ ÄÏÂÁ×ÌÅÎ ÎÏ×ÙÊ ÐÏÌØÚÏ×ÁÔÅÌØ +set *>::iterator ni = onAddNotifiers.begin(); +while (ni != onAddNotifiers.end()) + { + (*ni)->Notify(users.begin()); + ++ni; + } + +return 0; +} +//----------------------------------------------------------------------------- +void USERS::Del(const string & login, const ADMIN & admin) +{ +const PRIV * priv = admin.GetPriv(); +user_iter u; + +if (!priv->userAddDel) + { + WriteServLog("%s tried to remove user \'%s\'. Access denied.", + admin.GetLogStr().c_str(), login.c_str()); + return; + } + + + { + STG_LOCKER lock(&mutex, __FILE__, __LINE__); + + if (FindByNameNonLock(login, &u)) + { + WriteServLog("%s tried to delete user \'%s\': not found.", + admin.GetLogStr().c_str(), + login.c_str()); + return; + } + } + +set *>::iterator ni = onDelNotifiers.begin(); +while (ni != onDelNotifiers.end()) + { + (*ni)->Notify(u); + ++ni; + } + + { + STG_LOCKER lock(&mutex, __FILE__, __LINE__); + + u->OnDelete(); + u->SetDeleted(); + + USER_TO_DEL utd; + utd.iter = u; + utd.delTime = stgTime; + usersToDelete.push_back(utd); + + UnSetUserNotifiers(u); + DelUserFromIndexes(u); + + WriteServLog("%s User \'%s\' deleted.", + admin.GetLogStr().c_str(), login.c_str()); + + } +} +//----------------------------------------------------------------------------- +int USERS::ReadUsers() +{ +vector usersList; +usersList.clear(); +if (store->GetUsersList(&usersList) < 0) + { + WriteServLog(store->GetStrError().c_str()); + exit(1); + } + +user_iter ui; + +for (unsigned int i = 0; i < usersList.size(); i++) + { + USER u(settings, store, tariffs, sysAdmin, &ipIndex); + + u.SetLogin(usersList[i]); + users.push_front(u); + ui = users.begin(); + + AddUserIntoIndexes(ui); + SetUserNotifiers(ui); + + if (ui->ReadConf() < 0) + return -1; + + if (ui->ReadStat() < 0) + return -1; + } + +return 0; +} +//----------------------------------------------------------------------------- +void * USERS::Run(void * d) +{ +printfd(__FILE__, "=====================| pid: %d |===================== \n", getpid()); +USERS * us = (USERS*) d; + +struct tm t; +time_t tt = stgTime; +localtime_r(&tt, &t); + +int min = t.tm_min; +int day = t.tm_mday; + +printfd(__FILE__,"Day = %d Min = %d\n", day, min); + +time_t touchTime = stgTime - MONITOR_TIME_DELAY_SEC; +string monFile = us->settings->GetMonitorDir() + "/users_r"; +printfd(__FILE__, "Monitor=%d file USERS %s\n", us->settings->GetMonitoring(), monFile.c_str()); + +us->isRunning = true; +while (us->nonstop) + { + //printfd(__FILE__,"New Minute. old = %02d current = %02d\n", min, t->tm_min); + //printfd(__FILE__,"New Day. old = %2d current = %2d\n", day, t->tm_mday); + + for_each(us->users.begin(), us->users.end(), mem_fun_ref(&USER::Run)); + + tt = stgTime; + localtime_r(&tt, &t); + + if (min != t.tm_min) + { + printfd(__FILE__,"Sec = %d\n", stgTime); + printfd(__FILE__,"New Minute. old = %d current = %d\n", min, t.tm_min); + min = t.tm_min; + + us->NewMinute(t); + } + + if (day != t.tm_mday) + { + printfd(__FILE__,"Sec = %d\n", stgTime); + printfd(__FILE__,"New Day. old = %d current = %d\n", day, t.tm_mday); + day = t.tm_mday; + us->NewDay(t); + } + + if (us->settings->GetMonitoring() && (touchTime + MONITOR_TIME_DELAY_SEC <= stgTime)) + { + //printfd(__FILE__, "Monitor=%d file TRAFFCOUNTER %s\n", tc->monitoring, monFile.c_str()); + touchTime = stgTime; + TouchFile(monFile.c_str()); + } + + stgUsleep(100000); + } //while (us->nonstop) + +user_iter ui = us->users.begin(); +while (ui != us->users.end()) + { + us->UnSetUserNotifiers(ui); + us->DelUserFromIndexes(ui); + ui++; + } + +list::iterator iter; +iter = us->usersToDelete.begin(); +while (iter != us->usersToDelete.end()) + { + iter->delTime -= 2 * userDeleteDelayTime; + ++iter; + } +us->RealDelUser(); + +us->isRunning = false; + +return NULL; +} +//----------------------------------------------------------------------------- +void USERS::NewMinute(const struct tm & t) +{ +//Write traff, reset session traff. Fake disconnect-connect +if (t.tm_hour == 23 && t.tm_min == 59) + { + printfd(__FILE__,"MidnightResetSessionStat\n"); + for_each(users.begin(), users.end(), mem_fun_ref(&USER::MidnightResetSessionStat)); + } + +if (TimeToWriteDetailStat(t)) + { + //printfd(__FILE__, "USER::WriteInetStat\n"); + int usersCnt = 0; + + // ðÉÛÅÍ ÀÚÅÒÏ× ÞÁÓÔÑÍÉ. ÷ ÐÅÒÅÒÙ×ÁÈ ×ÙÚÙ×ÁÅÍ USER::Run + list::iterator usr = users.begin(); + while (usr != users.end()) + { + usersCnt++; + usr->WriteDetailStat(); + usr++; + if (usersCnt % 10 == 0) + for_each(users.begin(), users.end(), mem_fun_ref(&USER::Run)); + } + } + +RealDelUser(); +} +//----------------------------------------------------------------------------- +void USERS::NewDay(const struct tm & t) +{ +struct tm t1; +time_t tt = stgTime; +localtime_r(&tt, &t1); +int dayFee = settings->GetDayFee(); + +if (dayFee == 0) + dayFee = DaysInCurrentMonth(); + +printfd(__FILE__, "DayFee = %d\n", dayFee); +printfd(__FILE__, "Today = %d DayResetTraff = %d\n", t1.tm_mday, settings->GetDayResetTraff()); +printfd(__FILE__, "DayFeeIsLastDay = %d\n", settings->GetDayFeeIsLastDay()); + +if (!settings->GetDayFeeIsLastDay()) + { + printfd(__FILE__, "DayResetTraff - 1 -\n"); + DayResetTraff(t1); + //printfd(__FILE__, "DayResetTraff - 1 - 1 -\n"); + } + +if (settings->GetSpreadFee()) + { + printfd(__FILE__, "Spread DayFee\n"); + for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessDayFeeSpread)); + } +else + { + if (t.tm_mday == dayFee) + { + printfd(__FILE__, "DayFee\n"); + for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessDayFee)); + } + } + +if (settings->GetDayFeeIsLastDay()) + { + printfd(__FILE__, "DayResetTraff - 2 -\n"); + DayResetTraff(t1); + } +} +//----------------------------------------------------------------------------- +void USERS::DayResetTraff(const struct tm & t1) +{ +int dayResetTraff = settings->GetDayResetTraff(); +if (dayResetTraff == 0) + dayResetTraff = DaysInCurrentMonth(); +if (t1.tm_mday == dayResetTraff) + { + printfd(__FILE__, "ResetTraff\n"); + for_each(users.begin(), users.end(), mem_fun_ref(&USER::ProcessNewMonth)); + for_each(users.begin(), users.end(), mem_fun_ref(&USER::SetPrepaidTraff)); + } +} +//----------------------------------------------------------------------------- +int USERS::Start() +{ +if (ReadUsers()) + { + WriteServLog("USERS: Error: Cannot read users!"); + return -1; + } + +nonstop = true; +if (pthread_create(&thread, NULL, Run, this)) + { + WriteServLog("USERS: Error: Cannot start thread!"); + return -1; + } +return 0; +} +//----------------------------------------------------------------------------- +int USERS::Stop() +{ +printfd(__FILE__, "USERS::Stop()\n"); + +if (!isRunning) + { + //printfd(__FILE__, "Alredy stopped\n"); + return 0; + } + +nonstop = false; + +//5 seconds to thread stops itself +unsigned i; +for (i = 0; i < 25 * (users.size() / 50 + 1); i++) + { + if (!isRunning) + break; + + usleep(200000); + } + +//after 5 seconds waiting thread still running. now kill it +if (isRunning) + { + printfd(__FILE__, "kill USERS thread.\n"); + //TODO pthread_cancel() + if (pthread_kill(thread, SIGINT)) + { + //errorStr = "Cannot kill USERS thread."; + //printfd(__FILE__, "Cannot kill USERS thread.\n"); + //return 0; + } + printfd(__FILE__, "USERS killed\n"); + } + +printfd(__FILE__, "Before USERS::Run()\n"); +for_each(users.begin(), users.end(), mem_fun_ref(&USER::Run)); + +// 'cause bind2st accepts only constant first param +for (list::iterator it = users.begin(); + it != users.end(); + ++it) + it->WriteDetailStat(true); + +for_each(users.begin(), users.end(), mem_fun_ref(&USER::WriteStat)); +for_each(users.begin(), users.end(), mem_fun_ref(&USER::WriteConf)); + +printfd(__FILE__, "USERS::Stop()\n"); +return 0; +} +//----------------------------------------------------------------------------- +void USERS::RealDelUser() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +printfd(__FILE__, "RealDelUser() users to del: %d\n", usersToDelete.size()); + +list::iterator iter; +iter = usersToDelete.begin(); +while (iter != usersToDelete.end()) + { + printfd(__FILE__, "RealDelUser() user=%s\n", iter->iter->GetLogin().c_str()); + if (iter->delTime + userDeleteDelayTime < stgTime) + { + printfd(__FILE__, "RealDelUser() user=%s removed from DB\n", iter->iter->GetLogin().c_str()); + if (store->DelUser(iter->iter->GetLogin())) + { + WriteServLog("Error removing user \'%s\' from database.", iter->iter->GetLogin().c_str()); + } + users.erase(iter->iter); + usersToDelete.erase(iter++); + } + else + { + ++iter; + } + } +return; +} +//----------------------------------------------------------------------------- +int USERS::GetUserNum() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +return users.size(); +} +//----------------------------------------------------------------------------- +void USERS::AddToIPIdx(user_iter user) +{ +printfd(__FILE__, "USERS: Add IP Idx\n"); +uint32_t ip = user->GetCurrIP(); +//assert(ip && "User has non-null ip"); +if (!ip) + return; // User has disconnected + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +const map::iterator it( + ipIndex.lower_bound(ip) +); + +assert((it == ipIndex.end() || it->first != ip) && "User is not in index"); + +ipIndex.insert(it, std::make_pair(ip, user)); +} +//----------------------------------------------------------------------------- +void USERS::DelFromIPIdx(uint32_t ip) +{ +printfd(__FILE__, "USERS: Del IP Idx\n"); +assert(ip && "User has non-null ip"); + +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +const map::iterator it( + ipIndex.find(ip) +); + +//assert(it != ipIndex.end() && "User is in index"); +if (it == ipIndex.end()) + return; // User has not been added + +ipIndex.erase(it); +} +//----------------------------------------------------------------------------- +int USERS::FindByIPIdx(uint32_t ip, user_iter * usr) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +map::iterator it; +it = ipIndex.find(ip); + +if (it == ipIndex.end()) + { + //printfd(__FILE__, "User NOT found in IP_Index!!!\n"); + return -1; + } +*usr = it->second; +//printfd(__FILE__, "User found in IP_Index\n"); +return 0; +} +//----------------------------------------------------------------------------- +void USERS::AddNotifierUserAdd(NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +onAddNotifiers.insert(n); +} +//----------------------------------------------------------------------------- +void USERS::DelNotifierUserAdd(NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +//printfd(__FILE__, "DelNotifierUserAdd\n"); +onAddNotifiers.erase(n); +} +//----------------------------------------------------------------------------- +void USERS::AddNotifierUserDel(NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +onDelNotifiers.insert(n); +} +//----------------------------------------------------------------------------- +void USERS::DelNotifierUserDel(NOTIFIER_BASE * n) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +onDelNotifiers.erase(n); +} +//----------------------------------------------------------------------------- +int USERS::OpenSearch() +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +handle++; +searchDescriptors[handle] = users.begin(); +return handle; +} +//----------------------------------------------------------------------------- +int USERS::SearchNext(int h, user_iter * u) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +if (searchDescriptors.find(h) == searchDescriptors.end()) + { + WriteServLog("USERS. Incorrect search handle."); + return -1; + } + +if (searchDescriptors[h] == users.end()) + return -1; + +while (searchDescriptors[h]->GetDeleted()) + { + ++searchDescriptors[h]; + if (searchDescriptors[h] == users.end()) + { + return -1; + } + } + +*u = searchDescriptors[h]; + +++searchDescriptors[h]; + +return 0; +} +//----------------------------------------------------------------------------- +int USERS::CloseSearch(int h) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +if (searchDescriptors.find(h) != searchDescriptors.end()) + { + searchDescriptors.erase(searchDescriptors.find(h)); + return 0; + } + +WriteServLog("USERS. Incorrect search handle."); +return -1; +} +//----------------------------------------------------------------------------- +void USERS::SetUserNotifiers(user_iter user) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +PROPERTY_NOTIFER_IP_BEFORE nb(*this, user); +PROPERTY_NOTIFER_IP_AFTER na(*this, user); + +userIPNotifiersBefore.push_front(nb); +userIPNotifiersAfter.push_front(na); + +user->AddCurrIPBeforeNotifier(&(*userIPNotifiersBefore.begin())); +user->AddCurrIPAfterNotifier(&(*userIPNotifiersAfter.begin())); +} +//----------------------------------------------------------------------------- +void USERS::UnSetUserNotifiers(user_iter user) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); + +list::iterator bi; +list::iterator ai; + +bi = userIPNotifiersBefore.begin(); +while (bi != userIPNotifiersBefore.end()) + { + if (bi->GetUser() == user) + { + bi->GetUser()->DelCurrIPBeforeNotifier(&(*bi)); + userIPNotifiersBefore.erase(bi); + //printfd(__FILE__, "Notifier Before removed. User %s\n", bi->GetUser()->GetLogin().c_str()); + break; + } + bi++; + } + +ai = userIPNotifiersAfter.begin(); +while (ai != userIPNotifiersAfter.end()) + { + if (ai->GetUser() == user) + { + ai->GetUser()->DelCurrIPAfterNotifier(&(*ai)); + userIPNotifiersAfter.erase(ai); + //printfd(__FILE__, "Notifier After removed. User %s\n", ai->GetUser()->GetLogin().c_str()); + break; + } + ai++; + } +} +//----------------------------------------------------------------------------- +void USERS::AddUserIntoIndexes(user_iter user) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +loginIndex.insert(pair(user->GetLogin(), user)); +} +//----------------------------------------------------------------------------- +void USERS::DelUserFromIndexes(user_iter user) +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +loginIndex.erase(user->GetLogin()); +} +//----------------------------------------------------------------------------- +bool USERS::TimeToWriteDetailStat(const struct tm & t) +{ +int statTime = settings->GetDetailStatWritePeriod(); + +switch (statTime) + { + case dsPeriod_1: + if (t.tm_min == 0) + return true; + break; + case dsPeriod_1_2: + if (t.tm_min % 30 == 0) + return true; + break; + case dsPeriod_1_4: + if (t.tm_min % 15 == 0) + return true; + break; + case dsPeriod_1_6: + if (t.tm_min % 10 == 0) + return true; + break; + } +return false; +} diff --git a/projects/stargazer/users_impl.h b/projects/stargazer/users_impl.h new file mode 100644 index 00000000..424958da --- /dev/null +++ b/projects/stargazer/users_impl.h @@ -0,0 +1,198 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * Author : Boris Mikhailenko + */ + +/* +$Revision: 1.31 $ +$Date: 2010/10/07 20:04:48 $ +$Author: faust $ +*/ + + +#ifndef USERS_H +#define USERS_H + +#include + +#include +#include +#include +#include +#include + +#include "os_int.h" + +#include "settings.h" +#include "user.h" +#include "tariffs.h" +#include "stg_logger.h" +#include "notifer.h" +#include "actions.h" +#include "noncopyable.h" +#include "eventloop.h" + +const int userDeleteDelayTime = 120; + +using namespace std; +class USERS; +//----------------------------------------------------------------------------- +class PROPERTY_NOTIFER_IP_BEFORE: public PROPERTY_NOTIFIER_BASE +{ +public: + PROPERTY_NOTIFER_IP_BEFORE(USERS & us, user_iter u) : users(us), user(u) {}; + void Notify(const uint32_t & oldValue, const uint32_t & newValue); + user_iter GetUser() const { return user; }; +private: + USERS & users; + user_iter user; +}; +//----------------------------------------------------------------------------- +class PROPERTY_NOTIFER_IP_AFTER: public PROPERTY_NOTIFIER_BASE +{ +public: + PROPERTY_NOTIFER_IP_AFTER(USERS & us, user_iter u) : users(us), user(u) {}; + void Notify(const uint32_t & oldValue, const uint32_t & newValue); + user_iter GetUser() const { return user; }; +private: + USERS & users; + user_iter user; +}; +//----------------------------------------------------------------------------- +struct USER_TO_DEL +{ +USER_TO_DEL() + : iter(), + delTime(0) +{}; + +list::iterator iter; +time_t delTime; +}; +//----------------------------------------------------------------------------- +class USERS : private NONCOPYABLE + { + friend class PROPERTY_NOTIFER_IP_BEFORE; + friend class PROPERTY_NOTIFER_IP_AFTER; + +public: + USERS(SETTINGS * s, BASE_STORE * store, TARIFFS * tariffs, const ADMIN & sysAdmin); + ~USERS(); + + int FindByName(const string & login, user_iter * user) const; + int FindByID(int id, user_iter * user); + + bool TariffInUse(const string & tariffName); + + void AddNotifierUserAdd(NOTIFIER_BASE *); + void DelNotifierUserAdd(NOTIFIER_BASE *); + + void AddNotifierUserDel(NOTIFIER_BASE *); + void DelNotifierUserDel(NOTIFIER_BASE *); + + int Add(const string & login, const ADMIN & admin); + void Del(const string & login, const ADMIN & admin); + + int ReadUsers(); + int GetUserNum(); + + int FindByIPIdx(uint32_t ip, user_iter * user); + + int OpenSearch(); + int SearchNext(int handler, user_iter * u); + int CloseSearch(int handler); + + int Start(); + int Stop(); + +private: + void AddToIPIdx(user_iter); + void DelFromIPIdx(uint32_t ip); + + int FindByNameNonLock(const string & login, user_iter * user) const; + int FindByIDNonLock(int id, user_iter * user); + + void RealDelUser(); + void ProcessActions(); + + void SetUserNotifiers(user_iter user); + void UnSetUserNotifiers(user_iter user); + + void AddUserIntoIndexes(user_iter user); + void DelUserFromIndexes(user_iter user); + + static void * Run(void *); + void NewMinute(const struct tm & t); + void NewDay(const struct tm & t); + void DayResetTraff(const struct tm & t); + + bool TimeToWriteDetailStat(const struct tm & t); + + list users; + list usersToDelete; + list userIPNotifiersBefore; + list userIPNotifiersAfter; + + map ipIndex; + map loginIndex; + + SETTINGS * settings; + TARIFFS * tariffs; + BASE_STORE * store; + const ADMIN sysAdmin; + STG_LOGGER & WriteServLog; + + bool nonstop; + bool isRunning; + + mutable pthread_mutex_t mutex; + pthread_t thread; + mutable unsigned int handle; + + mutable map searchDescriptors; + + set *> onAddNotifiers; + set *> onDelNotifiers; + }; +//----------------------------------------------------------------------------- +inline +void PROPERTY_NOTIFER_IP_BEFORE::Notify(const uint32_t & oldValue, + const uint32_t &) +{ +if (!oldValue) + return; + +//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(users, &USERS::DelFromIPIdx, oldValue); +// Using explicit call to assure that index is valid, because fast reconnect with delayed call can result in authorization error +users.DelFromIPIdx(oldValue); +} +//----------------------------------------------------------------------------- +inline +void PROPERTY_NOTIFER_IP_AFTER::Notify(const uint32_t &, + const uint32_t & newValue) +{ +if (!newValue) + return; + +//EVENT_LOOP_SINGLETON::GetInstance().Enqueue(users, &USERS::AddToIPIdx, user); +// Using explicit call to assure that index is valid, because fast reconnect with delayed call can result in authorization error +users.AddToIPIdx(user); +} +//----------------------------------------------------------------------------- +#endif +