--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef ADMIN_H
+#define ADMIN_H
+
+#include <string>
+
+#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
--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef ADMINS_H
+#define ADMINS_H
+
+#include <string>
+
+#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
--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef TARIFF_H
+#define TARIFF_H
+
+#include <ctime>
+
+#include <string>
+
+#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
--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef TARIFFS_H
+#define TARIFFS_H
+
+#include <string>
+#include <list>
+
+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<TARIFF_DATA> * tdl) = 0;
+
+ virtual const std::string & GetStrError() const = 0;
+};
+
+#endif
--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef USER_H
+#define USER_H
+
+#include <ctime>
+#include <string>
+
+#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<uint32_t> * notifier) = 0;
+ virtual void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * notifier) = 0;
+
+ virtual void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * notifier) = 0;
+ virtual void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * 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
--- /dev/null
+/*
+ * 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 <faust@stargazer.dp.ua>
+ */
+
+#ifndef USERS_H
+#define USERS_H
+
+#include <string>
+
+#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<USER_PTR> * notifier) = 0;
+ virtual void DelNotifierUserAdd(NOTIFIER_BASE<USER_PTR> * notifier) = 0;
+
+ virtual void AddNotifierUserDel(NOTIFIER_BASE<USER_PTR> * notifier) = 0;
+ virtual void DelNotifierUserDel(NOTIFIER_BASE<USER_PTR> * 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
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
- /*
- $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() + ":";
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.14 $
- $Date: 2010/10/04 20:15:43 $
- $Author: faust $
- */
-
-#ifndef ADMIN_H
-#define ADMIN_H
-
-#include <string>
-
-#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
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $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() + ":";
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.14 $
+ $Date: 2010/10/04 20:15:43 $
+ $Author: faust $
+ */
+
+#ifndef ADMIN_H
+#define ADMIN_H
+
+#include <string>
+
+#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
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.15 $
- $Date: 2010/10/04 20:17:12 $
- $Author: faust $
- */
-
-#include <cerrno>
-#include <cassert>
-#include <algorithm>
-
-#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<int, const_admin_iter>::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<string> 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;
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
- /*
- $Revision: 1.10 $
- $Date: 2010/10/04 20:17:12 $
- $Author: faust $
- */
-
-#ifndef ADMINS_H
-#define ADMINS_H
-
-#include <pthread.h>
-#include <list>
-#include <map>
-
-#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<ADMIN>::iterator admin_iter;
- typedef list<ADMIN>::const_iterator const_admin_iter;
-
- int ReadAdmins();
-
- ADMIN stg;
- ADMIN noAdmin;
- list<ADMIN> data;
- BASE_STORE * store;
- STG_LOGGER & WriteServLog;
- mutable map<int, const_admin_iter> searchDescriptors;
- mutable unsigned int handle;
- mutable pthread_mutex_t mutex;
- string strError;
-};
-//-----------------------------------------------------------------------------
-#endif
-
-
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.15 $
+ $Date: 2010/10/04 20:17:12 $
+ $Author: faust $
+ */
+
+#include <cerrno>
+#include <cassert>
+#include <algorithm>
+
+#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<int, const_admin_iter>::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<string> 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;
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+ /*
+ $Revision: 1.10 $
+ $Date: 2010/10/04 20:17:12 $
+ $Author: faust $
+ */
+
+#ifndef ADMINS_H
+#define ADMINS_H
+
+#include <pthread.h>
+#include <list>
+#include <map>
+
+#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<ADMIN>::iterator admin_iter;
+ typedef list<ADMIN>::const_iterator const_admin_iter;
+
+ int ReadAdmins();
+
+ ADMIN stg;
+ ADMIN noAdmin;
+ list<ADMIN> data;
+ BASE_STORE * store;
+ STG_LOGGER & WriteServLog;
+ mutable map<int, const_admin_iter> searchDescriptors;
+ mutable unsigned int handle;
+ mutable pthread_mutex_t mutex;
+ string strError;
+};
+//-----------------------------------------------------------------------------
+#endif
+
+
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.11 $
- $Date: 2010/10/07 16:57:21 $
- $Author: faust $
- */
-
-#include <ctime>
-#include <algorithm> // 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;
- }
- }*/
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.9 $
- $Date: 2010/10/07 17:53:39 $
- $Author: faust $
- */
-
-#ifndef TARIFF_H
-#define TARIFF_H
-
-#include <ctime>
-
-#include <string>
-#include <list>
-
-#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
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.11 $
+ $Date: 2010/10/07 16:57:21 $
+ $Author: faust $
+ */
+
+#include <ctime>
+#include <algorithm> // 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;
+ }
+ }*/
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.9 $
+ $Date: 2010/10/07 17:53:39 $
+ $Author: faust $
+ */
+
+#ifndef TARIFF_H
+#define TARIFF_H
+
+#include <ctime>
+
+#include <string>
+#include <list>
+
+#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
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.9 $
- $Date: 2010/10/07 18:43:21 $
- $Author: faust $
- */
-
-#include <cassert>
-#include <algorithm>
-#include <vector>
-
-#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<string> 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<TARIFF>::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<TARIFF>::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<TARIFF>::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<TARIFF>::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<TARIFF_DATA> * tdl)
-{
-assert(tdl != NULL && "Tariffs data list is not null");
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
-std::list<TARIFF>::const_iterator it = tariffs.begin();
-TARIFF_DATA td;
-for (; it != tariffs.end(); ++it)
- {
- it->GetTariffData(&td);
- tdl->push_back(td);
- }
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
- /*
- $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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.7 $
- $Date: 2010/10/07 18:43:21 $
- $Author: faust $
- */
-
-#ifndef TARIFFS_H
-#define TARIFFS_H
-
-#include <pthread.h>
-
-#include <string>
-#include <list>
-
-#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<TARIFF_DATA> * tdl);
-
- const std::string & GetStrError() const { return strError; };
-private:
- std::list<TARIFF> tariffs;
- BASE_STORE * store;
- STG_LOGGER & WriteServLog;
- mutable pthread_mutex_t mutex;
- std::string strError;
- TARIFF noTariff;
-};
-//-----------------------------------------------------------------------------
-
-#endif
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.9 $
+ $Date: 2010/10/07 18:43:21 $
+ $Author: faust $
+ */
+
+#include <cassert>
+#include <algorithm>
+#include <vector>
+
+#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<string> 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<TARIFF>::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<TARIFF>::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<TARIFF>::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<TARIFF>::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<TARIFF_DATA> * tdl)
+{
+assert(tdl != NULL && "Tariffs data list is not null");
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+
+std::list<TARIFF>::const_iterator it = tariffs.begin();
+TARIFF_DATA td;
+for (; it != tariffs.end(); ++it)
+ {
+ it->GetTariffData(&td);
+ tdl->push_back(td);
+ }
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+ /*
+ $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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.7 $
+ $Date: 2010/10/07 18:43:21 $
+ $Author: faust $
+ */
+
+#ifndef TARIFFS_H
+#define TARIFFS_H
+
+#include <pthread.h>
+
+#include <string>
+#include <list>
+
+#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<TARIFF_DATA> * tdl);
+
+ const std::string & GetStrError() const { return strError; };
+private:
+ std::list<TARIFF> tariffs;
+ BASE_STORE * store;
+ STG_LOGGER & WriteServLog;
+ mutable pthread_mutex_t mutex;
+ std::string strError;
+ TARIFF noTariff;
+};
+//-----------------------------------------------------------------------------
+
+#endif
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.101 $
- $Date: 2010/11/03 10:50:03 $
- $Author: faust $
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <pthread.h>
-#include <unistd.h> // access
-
-#include <cassert>
-
-#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<uint32_t, user_iter> * 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<STG_MSG_HDR> hdrsList;
-
-if (store->GetMessageHdrs(&hdrsList, login))
- {
- printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
- return -1;
- }
-
-std::vector<STG_MSG_HDR>::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<uint32_t, user_iter>::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=" <<realName << endl;
-cout << "group=" << group << endl;
-cout << "credit=" << credit << endl;
-cout << "nextTariff=" << nextTariff << endl;
-cout << "userdata0" << userdata0 << endl;
-cout << "userdata1" << userdata1 << endl;
-cout << "creditExpire=" << creditExpire << endl;
-cout << "ips=" << ips << endl;
-cout << "------------------------" << endl;
-cout << "up=" << up << endl;
-cout << "down=" << down << endl;
-cout << "cash=" << cash << endl;
-cout << "freeMb=" << freeMb << endl;
-cout << "lastCashAdd=" << lastCashAdd << endl;
-cout << "lastCashAddTime=" << lastCashAddTime << endl;
-cout << "passiveTime=" << passiveTime << endl;
-cout << "lastActivityTime=" << lastActivityTime << endl;
-cout << "============================================================" << endl;
-}
-//-----------------------------------------------------------------------------
-void USER::Run()
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-
-if (stgTime > static_cast<time_t>(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<time_t *>(&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<IP_DIR_PAIR, STAT_NODE>::iterator lb;
-lb = traffStat.lower_bound(idp);
-if (lb == traffStat.end() || lb->first != idp)
- {
- traffStat.insert(lb,
- pair<IP_DIR_PAIR, STAT_NODE>(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<IP_DIR_PAIR, STAT_NODE>::iterator lb;
-lb = traffStat.lower_bound(idp);
-if (lb == traffStat.end() || lb->first != idp)
- {
- traffStat.insert(lb,
- pair<IP_DIR_PAIR, STAT_NODE>(idp,
- STAT_NODE(0, len, cost)));
- }
-else
- {
- lb->second.cash += cost;
- lb->second.down += len;
- }
-}
-//-----------------------------------------------------------------------------
-void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-currIP.AddBeforeNotifier(n);
-}
-//-----------------------------------------------------------------------------
-void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-currIP.DelBeforeNotifier(n);
-}
-//-----------------------------------------------------------------------------
-void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-currIP.AddAfterNotifier(n);
-}
-//-----------------------------------------------------------------------------
-void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * 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<const BASE_AUTH*>::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<STG_MSG>::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<time_t *>(&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);
-}
-//-----------------------------------------------------------------------------
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.48 $
- $Date: 2010/11/03 10:50:03 $
- $Author: faust $
- */
-
-#ifndef USER_H
-#define USER_H
-
-#include <ctime>
-#include <list>
-#include <string>
-#include <map>
-#include <set>
-
-#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<USER>::iterator user_iter;
-typedef list<USER>::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<int>,
- 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<string>,
- 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<double>,
- 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<uint32_t>,
- 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<uint32_t, user_iter> * 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<uint32_t> *);
- void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
-
- void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
- void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
-
- 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<bool> connected;
-
- bool enabledDirs[DIR_NUM];
-
- USER_ID_GENERATOR userIDGenerator;
-
- uint32_t __currIP; // ôÅËÕÝÉÊ ÁÄÒÅÓ ÐÏÌØÚÏ×ÁÔÅÌÑ
- USER_PROPERTY<uint32_t> 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<time_t, TRAFF_STAT> traffStatSaved;
-
- const SETTINGS * settings;
-
- set<const BASE_AUTH *> authorizedBy;
-
- const map<uint32_t, user_iter> * ipIndex;
-
- list<STG_MSG> messages;
-
- bool deleted;
-
- time_t lastWriteStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÓÔÁÔÉÓÔÉËÉ
- time_t lastWriteDeatiledStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÄÅÔÁÌØÎÏÊ ÓÔÁÔÉÓÔÉËÉ
-
- // Properties
- USER_PROPERTY<double> & cash;
- USER_PROPERTY<DIR_TRAFF> & up;
- USER_PROPERTY<DIR_TRAFF> & down;
- USER_PROPERTY<double> & lastCashAdd;
- USER_PROPERTY<time_t> & passiveTime;
- USER_PROPERTY<time_t> & lastCashAddTime;
- USER_PROPERTY<double> & freeMb;
- USER_PROPERTY<time_t> & lastActivityTime;
- USER_PROPERTY<string> & password;
- USER_PROPERTY<int> & passive;
- USER_PROPERTY<int> & disabled;
- USER_PROPERTY<int> & disabledDetailStat;
- USER_PROPERTY<int> & alwaysOnline;
- USER_PROPERTY<string> & tariffName;
- USER_PROPERTY<string> & nextTariff;
- USER_PROPERTY<string> & address;
- USER_PROPERTY<string> & note;
- USER_PROPERTY<string> & group;
- USER_PROPERTY<string> & email;
- USER_PROPERTY<string> & phone;
- USER_PROPERTY<string> & realName;
- USER_PROPERTY<double> & credit;
- USER_PROPERTY<time_t> & creditExpire;
- USER_PROPERTY<USER_IPS> & ips;
- USER_PROPERTY<string> & userdata0;
- USER_PROPERTY<string> & userdata1;
- USER_PROPERTY<string> & userdata2;
- USER_PROPERTY<string> & userdata3;
- USER_PROPERTY<string> & userdata4;
- USER_PROPERTY<string> & userdata5;
- USER_PROPERTY<string> & userdata6;
- USER_PROPERTY<string> & userdata7;
- USER_PROPERTY<string> & userdata8;
- USER_PROPERTY<string> & 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
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.101 $
+ $Date: 2010/11/03 10:50:03 $
+ $Author: faust $
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <pthread.h>
+#include <unistd.h> // access
+
+#include <cassert>
+
+#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<uint32_t, user_iter> * 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<STG_MSG_HDR> hdrsList;
+
+if (store->GetMessageHdrs(&hdrsList, login))
+ {
+ printfd(__FILE__, "Error GetMessageHdrs %s\n", store->GetStrError().c_str());
+ return -1;
+ }
+
+std::vector<STG_MSG_HDR>::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<uint32_t, user_iter>::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=" <<realName << endl;
+cout << "group=" << group << endl;
+cout << "credit=" << credit << endl;
+cout << "nextTariff=" << nextTariff << endl;
+cout << "userdata0" << userdata0 << endl;
+cout << "userdata1" << userdata1 << endl;
+cout << "creditExpire=" << creditExpire << endl;
+cout << "ips=" << ips << endl;
+cout << "------------------------" << endl;
+cout << "up=" << up << endl;
+cout << "down=" << down << endl;
+cout << "cash=" << cash << endl;
+cout << "freeMb=" << freeMb << endl;
+cout << "lastCashAdd=" << lastCashAdd << endl;
+cout << "lastCashAddTime=" << lastCashAddTime << endl;
+cout << "passiveTime=" << passiveTime << endl;
+cout << "lastActivityTime=" << lastActivityTime << endl;
+cout << "============================================================" << endl;
+}
+//-----------------------------------------------------------------------------
+void USER::Run()
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+
+if (stgTime > static_cast<time_t>(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<time_t *>(&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<IP_DIR_PAIR, STAT_NODE>::iterator lb;
+lb = traffStat.lower_bound(idp);
+if (lb == traffStat.end() || lb->first != idp)
+ {
+ traffStat.insert(lb,
+ pair<IP_DIR_PAIR, STAT_NODE>(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<IP_DIR_PAIR, STAT_NODE>::iterator lb;
+lb = traffStat.lower_bound(idp);
+if (lb == traffStat.end() || lb->first != idp)
+ {
+ traffStat.insert(lb,
+ pair<IP_DIR_PAIR, STAT_NODE>(idp,
+ STAT_NODE(0, len, cost)));
+ }
+else
+ {
+ lb->second.cash += cost;
+ lb->second.down += len;
+ }
+}
+//-----------------------------------------------------------------------------
+void USER::AddCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+currIP.AddBeforeNotifier(n);
+}
+//-----------------------------------------------------------------------------
+void USER::DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+currIP.DelBeforeNotifier(n);
+}
+//-----------------------------------------------------------------------------
+void USER::AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+currIP.AddAfterNotifier(n);
+}
+//-----------------------------------------------------------------------------
+void USER::DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> * 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<const BASE_AUTH*>::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<STG_MSG>::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<time_t *>(&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);
+}
+//-----------------------------------------------------------------------------
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.48 $
+ $Date: 2010/11/03 10:50:03 $
+ $Author: faust $
+ */
+
+#ifndef USER_H
+#define USER_H
+
+#include <ctime>
+#include <list>
+#include <string>
+#include <map>
+#include <set>
+
+#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<USER>::iterator user_iter;
+typedef list<USER>::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<int>,
+ 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<string>,
+ 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<double>,
+ 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<uint32_t>,
+ 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<uint32_t, user_iter> * 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<uint32_t> *);
+ void DelCurrIPBeforeNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
+
+ void AddCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
+ void DelCurrIPAfterNotifier(PROPERTY_NOTIFIER_BASE<uint32_t> *);
+
+ 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<bool> connected;
+
+ bool enabledDirs[DIR_NUM];
+
+ USER_ID_GENERATOR userIDGenerator;
+
+ uint32_t __currIP; // ôÅËÕÝÉÊ ÁÄÒÅÓ ÐÏÌØÚÏ×ÁÔÅÌÑ
+ USER_PROPERTY<uint32_t> 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<time_t, TRAFF_STAT> traffStatSaved;
+
+ const SETTINGS * settings;
+
+ set<const BASE_AUTH *> authorizedBy;
+
+ const map<uint32_t, user_iter> * ipIndex;
+
+ list<STG_MSG> messages;
+
+ bool deleted;
+
+ time_t lastWriteStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÓÔÁÔÉÓÔÉËÉ
+ time_t lastWriteDeatiledStat; // ÷ÒÅÍÑ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ ÄÅÔÁÌØÎÏÊ ÓÔÁÔÉÓÔÉËÉ
+
+ // Properties
+ USER_PROPERTY<double> & cash;
+ USER_PROPERTY<DIR_TRAFF> & up;
+ USER_PROPERTY<DIR_TRAFF> & down;
+ USER_PROPERTY<double> & lastCashAdd;
+ USER_PROPERTY<time_t> & passiveTime;
+ USER_PROPERTY<time_t> & lastCashAddTime;
+ USER_PROPERTY<double> & freeMb;
+ USER_PROPERTY<time_t> & lastActivityTime;
+ USER_PROPERTY<string> & password;
+ USER_PROPERTY<int> & passive;
+ USER_PROPERTY<int> & disabled;
+ USER_PROPERTY<int> & disabledDetailStat;
+ USER_PROPERTY<int> & alwaysOnline;
+ USER_PROPERTY<string> & tariffName;
+ USER_PROPERTY<string> & nextTariff;
+ USER_PROPERTY<string> & address;
+ USER_PROPERTY<string> & note;
+ USER_PROPERTY<string> & group;
+ USER_PROPERTY<string> & email;
+ USER_PROPERTY<string> & phone;
+ USER_PROPERTY<string> & realName;
+ USER_PROPERTY<double> & credit;
+ USER_PROPERTY<time_t> & creditExpire;
+ USER_PROPERTY<USER_IPS> & ips;
+ USER_PROPERTY<string> & userdata0;
+ USER_PROPERTY<string> & userdata1;
+ USER_PROPERTY<string> & userdata2;
+ USER_PROPERTY<string> & userdata3;
+ USER_PROPERTY<string> & userdata4;
+ USER_PROPERTY<string> & userdata5;
+ USER_PROPERTY<string> & userdata6;
+ USER_PROPERTY<string> & userdata7;
+ USER_PROPERTY<string> & userdata8;
+ USER_PROPERTY<string> & 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
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
- $Revision: 1.61 $
- $Date: 2010/09/13 05:56:42 $
- $Author: faust $
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <pthread.h>
-#include <csignal>
-#include <cassert>
-#include <algorithm>
-#include <utility>
-#include <string>
-#include <vector>
-
-#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<string, user_iter>::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<USER>::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<NOTIFIER_BASE<user_iter> *>::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<NOTIFIER_BASE<user_iter> *>::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<string> 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<USER_TO_DEL>::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<USER>::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<USER>::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<USER_TO_DEL>::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<uint32_t, user_iter>::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<uint32_t, user_iter>::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<uint32_t, user_iter>::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<user_iter> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-onAddNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-void USERS::DelNotifierUserAdd(NOTIFIER_BASE<user_iter> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-//printfd(__FILE__, "DelNotifierUserAdd\n");
-onAddNotifiers.erase(n);
-}
-//-----------------------------------------------------------------------------
-void USERS::AddNotifierUserDel(NOTIFIER_BASE<user_iter> * n)
-{
-STG_LOCKER lock(&mutex, __FILE__, __LINE__);
-onDelNotifiers.insert(n);
-}
-//-----------------------------------------------------------------------------
-void USERS::DelNotifierUserDel(NOTIFIER_BASE<user_iter> * 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<PROPERTY_NOTIFER_IP_BEFORE>::iterator bi;
-list<PROPERTY_NOTIFER_IP_AFTER>::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<string, user_iter>(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;
-}
+++ /dev/null
-/*
- * 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 <stg34@stargazer.dp.ua>
- */
-
-/*
-$Revision: 1.31 $
-$Date: 2010/10/07 20:04:48 $
-$Author: faust $
-*/
-
-
-#ifndef USERS_H
-#define USERS_H
-
-#include <pthread.h>
-
-#include <ctime>
-#include <string>
-#include <map>
-#include <list>
-#include <set>
-
-#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<uint32_t>
-{
-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<uint32_t>
-{
-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<USER>::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<user_iter> *);
- void DelNotifierUserAdd(NOTIFIER_BASE<user_iter> *);
-
- void AddNotifierUserDel(NOTIFIER_BASE<user_iter> *);
- void DelNotifierUserDel(NOTIFIER_BASE<user_iter> *);
-
- 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<USER> users;
- list<USER_TO_DEL> usersToDelete;
- list<PROPERTY_NOTIFER_IP_BEFORE> userIPNotifiersBefore;
- list<PROPERTY_NOTIFER_IP_AFTER> userIPNotifiersAfter;
-
- map<uint32_t, user_iter> ipIndex;
- map<string, user_iter> 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<int, user_iter> searchDescriptors;
-
- set <NOTIFIER_BASE<user_iter>*> onAddNotifiers;
- set <NOTIFIER_BASE<user_iter>*> 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
-
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+ $Revision: 1.61 $
+ $Date: 2010/09/13 05:56:42 $
+ $Author: faust $
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <pthread.h>
+#include <csignal>
+#include <cassert>
+#include <algorithm>
+#include <utility>
+#include <string>
+#include <vector>
+
+#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<string, user_iter>::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<USER>::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<NOTIFIER_BASE<user_iter> *>::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<NOTIFIER_BASE<user_iter> *>::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<string> 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<USER_TO_DEL>::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<USER>::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<USER>::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<USER_TO_DEL>::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<uint32_t, user_iter>::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<uint32_t, user_iter>::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<uint32_t, user_iter>::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<user_iter> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onAddNotifiers.insert(n);
+}
+//-----------------------------------------------------------------------------
+void USERS::DelNotifierUserAdd(NOTIFIER_BASE<user_iter> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+//printfd(__FILE__, "DelNotifierUserAdd\n");
+onAddNotifiers.erase(n);
+}
+//-----------------------------------------------------------------------------
+void USERS::AddNotifierUserDel(NOTIFIER_BASE<user_iter> * n)
+{
+STG_LOCKER lock(&mutex, __FILE__, __LINE__);
+onDelNotifiers.insert(n);
+}
+//-----------------------------------------------------------------------------
+void USERS::DelNotifierUserDel(NOTIFIER_BASE<user_iter> * 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<PROPERTY_NOTIFER_IP_BEFORE>::iterator bi;
+list<PROPERTY_NOTIFER_IP_AFTER>::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<string, user_iter>(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;
+}
--- /dev/null
+/*
+ * 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 <stg34@stargazer.dp.ua>
+ */
+
+/*
+$Revision: 1.31 $
+$Date: 2010/10/07 20:04:48 $
+$Author: faust $
+*/
+
+
+#ifndef USERS_H
+#define USERS_H
+
+#include <pthread.h>
+
+#include <ctime>
+#include <string>
+#include <map>
+#include <list>
+#include <set>
+
+#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<uint32_t>
+{
+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<uint32_t>
+{
+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<USER>::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<user_iter> *);
+ void DelNotifierUserAdd(NOTIFIER_BASE<user_iter> *);
+
+ void AddNotifierUserDel(NOTIFIER_BASE<user_iter> *);
+ void DelNotifierUserDel(NOTIFIER_BASE<user_iter> *);
+
+ 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<USER> users;
+ list<USER_TO_DEL> usersToDelete;
+ list<PROPERTY_NOTIFER_IP_BEFORE> userIPNotifiersBefore;
+ list<PROPERTY_NOTIFER_IP_AFTER> userIPNotifiersAfter;
+
+ map<uint32_t, user_iter> ipIndex;
+ map<string, user_iter> 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<int, user_iter> searchDescriptors;
+
+ set <NOTIFIER_BASE<user_iter>*> onAddNotifiers;
+ set <NOTIFIER_BASE<user_iter>*> 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
+