serviceChg(0),
corpChg(0)
{}
- PRIV(uint32_t p)
+ explicit PRIV(uint32_t p)
: userStat((p & 0x00000003) >> 0x00),
userConf((p & 0x0000000C) >> 0x02),
userCash((p & 0x00000030) >> 0x04),
login(),
password("* NO PASSWORD *")
{}
- ADMIN_CONF(const ADMIN_CONF & rvalue)
- : priv(rvalue.priv),
- login(rvalue.login),
- password(rvalue.password)
- {}
ADMIN_CONF(const PRIV & pr, const std::string & l, const std::string & p)
: priv(pr),
login(l),
//-----------------------------------------------------------------------------
struct ADMIN_CONF_RES
{
- ADMIN_CONF_RES()
+ ADMIN_CONF_RES() {}
+ ADMIN_CONF_RES(const ADMIN_CONF_RES & rhs)
+ : priv(rhs.priv),
+ login(rhs.login),
+ password(rhs.password)
{}
+ ADMIN_CONF_RES & operator=(const ADMIN_CONF_RES & rhs)
+ {
+ priv = rhs.priv;
+ login = rhs.login;
+ password = rhs.password;
+ return *this;
+ }
RESETABLE<PRIV> priv;
RESETABLE<std::string> login;
RESETABLE<std::string> password;
+/*
+ * 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 CORP_CONF_H
#define CORP_CONF_H
+#include "resetable.h"
+
#include <string>
struct CORP_CONF
{
CORP_CONF() : name(), cash(0) {}
- CORP_CONF(const std::string & n) : name(n), cash(0) {}
+ explicit CORP_CONF(const std::string & n) : name(n), cash(0) {}
CORP_CONF(const std::string & n, double c) : name(n), cash(c) {}
std::string name;
double cash;
};
+struct CORP_CONF_RES
+{
+CORP_CONF_RES()
+ : name(), cash()
+{}
+
+CORP_CONF_RES & operator=(const CORP_CONF & conf)
+{
+name = conf.name;
+cash = conf.cash;
+return *this;
+}
+
+CORP_CONF GetData() const
+{
+CORP_CONF cc;
+cc.name = name.data();
+cc.cash = cash.data();
+return cc;
+}
+
+RESETABLE<std::string> name;
+RESETABLE<double> cash;
+};
+
inline
bool operator==(const CORP_CONF & a, const CORP_CONF & b)
{
typedef ContainerType::size_type IndexType;
DIR_TRAFF() : traff(DIR_NUM) {}
- DIR_TRAFF(const DIR_TRAFF & ts) : traff(ts.traff) {}
- DIR_TRAFF & operator=(const DIR_TRAFF & ts) { traff = ts.traff; return *this; }
const uint64_t & operator[](IndexType idx) const { return traff[idx]; }
uint64_t & operator[](IndexType idx) { return traff[idx]; }
IndexType size() const { return traff.size(); }
class DIR_TRAFF_RES
{
public:
+ typedef RESETABLE<uint64_t> value_type;
typedef RESETABLE<uint64_t> ValueType;
typedef std::vector<ValueType> ContainerType;
typedef ContainerType::size_type IndexType;
DIR_TRAFF_RES() : traff(DIR_NUM) {}
- DIR_TRAFF_RES(const DIR_TRAFF & ts)
+ explicit DIR_TRAFF_RES(const DIR_TRAFF & ts)
: traff(ts.size())
{
for (IndexType i = 0; i < ts.size(); ++i)
traff[i] = ts[i];
}
+ DIR_TRAFF_RES & operator=(const DIR_TRAFF & ts)
+ {
+ for (IndexType i = 0; i < ts.size(); ++i)
+ traff[i] = ts[i];
+ return *this;
+ }
const ValueType & operator[](IndexType idx) const { return traff[idx]; }
ValueType & operator[](IndexType idx) { return traff[idx]; }
+ IndexType size() const { return traff.size(); }
DIR_TRAFF GetData() const
{
DIR_TRAFF res;
#include "parser_admins.h"
#include "parser_tariffs.h"
#include "parser_users.h"
+#include "parser_services.h"
#include "parser_message.h"
+#include "parser_user_info.h"
#include "parser_auth_by.h"
#include "stg/common.h"
m_admins(NULL),
m_tariffs(NULL),
m_users(NULL),
+ m_services(NULL),
+ m_corporations(NULL),
m_store(NULL),
m_port(0),
m_bindAddress("0.0.0.0"),
CONFIGPROTO::~CONFIGPROTO()
{
+ {
std::deque<STG::Conn *>::iterator it;
for (it = m_conns.begin(); it != m_conns.end(); ++it)
delete *it;
+ }
+ {
+ BASE_PARSER::REGISTRY::iterator it;
+ for (it = m_registry.begin(); it != m_registry.end(); ++it)
+ delete it->second;
+ }
}
int CONFIGPROTO::Prepare()
sigaddset(&sigmask, SIGUSR1);
sigaddset(&sigmask, SIGHUP);
pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
-
m_listenSocket = socket(PF_INET, SOCK_STREAM, 0);
if (m_listenSocket < 0)
assert(m_admins != NULL);
assert(m_users != NULL);
assert(m_tariffs != NULL);
+ assert(m_services != NULL);
+ assert(m_corporations != NULL);
SP::GET_SERVER_INFO::FACTORY::Register(m_registry, *m_settings, *m_users, *m_tariffs);
SP::CHG_USER::FACTORY::Register(m_registry, *m_users, *m_store, *m_tariffs);
SP::CHECK_USER::FACTORY::Register(m_registry, *m_users);
+ SP::GET_SERVICES::FACTORY::Register(m_registry, *m_services);
+ SP::GET_SERVICE::FACTORY::Register(m_registry, *m_services);
+ SP::ADD_SERVICE::FACTORY::Register(m_registry, *m_services);
+ SP::DEL_SERVICE::FACTORY::Register(m_registry, *m_services);
+ SP::CHG_SERVICE::FACTORY::Register(m_registry, *m_services);
+
SP::SEND_MESSAGE::FACTORY::Register(m_registry, *m_users);
SP::AUTH_BY::FACTORY::Register(m_registry, *m_users);
+
+ SP::USER_INFO::FACTORY::Register(m_registry, *m_users);
}
int CONFIGPROTO::MaxFD() const
class ADMINS;
class TARIFFS;
class USERS;
+class SERVICES;
+class CORPORATIONS;
class STORE;
class PLUGIN_LOGGER;
class CONFIGPROTO {
public:
- CONFIGPROTO(PLUGIN_LOGGER & l);
+ explicit CONFIGPROTO(PLUGIN_LOGGER & l);
~CONFIGPROTO();
- void SetPort(uint16_t port) { m_port = port; }
- void SetBindAddress(const std::string & address) { m_bindAddress = address; }
- void SetSettings(const SETTINGS * settings) { m_settings = settings; }
- void SetAdmins(ADMINS * admins) { m_admins = admins; }
- void SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
- void SetUsers(USERS * users) { m_users = users; }
- void SetStore(STORE * store) { m_store = store; }
-
- int Prepare();
- int Stop();
+ void SetPort(uint16_t port) { m_port = port; }
+ void SetBindAddress(const std::string & address) { m_bindAddress = address; }
+ void SetSettings(const SETTINGS * settings) { m_settings = settings; }
+ void SetAdmins(ADMINS * admins) { m_admins = admins; }
+ void SetTariffs(TARIFFS * tariffs) { m_tariffs = tariffs; }
+ void SetUsers(USERS * users) { m_users = users; }
+ void SetStore(STORE * store) { m_store = store; }
+ void SetServices(SERVICES * services) { m_services = services; }
+ void SetCorporations(CORPORATIONS * corporations) { m_corporations = corporations; }
+
+ int Prepare();
+ int Stop();
const std::string & GetStrError() const { return m_errorStr; }
- void Run();
+ void Run();
private:
CONFIGPROTO(const CONFIGPROTO & rvalue);
ADMINS * m_admins;
TARIFFS * m_tariffs;
USERS * m_users;
+ SERVICES * m_services;
+ CORPORATIONS * m_corporations;
STORE * m_store;
uint16_t m_port;
void CleanupConns();
void HandleEvents(const fd_set & fds);
void AcceptConnection();
-
- //void WriteLogAccessFailed(uint32_t ip);
};
#endif //CONFIGPROTO_H
namespace
{
PLUGIN_CREATOR<FILES_STORE> fsc;
+
+bool CheckAndCreate(const std::string & dir, mode_t mode)
+{
+if (access(dir.c_str(), F_OK) == 0)
+ return true;
+if (mkdir(dir.c_str(), mode) == 0)
+ return true;
+return false;
+}
+
}
extern "C" STORE * GetStore();
workDir.resize(workDir.size() - 1);
}
usersDir = workDir + "/users/";
+if (!CheckAndCreate(usersDir, GetConfModeDir()))
+ {
+ errorStr = usersDir + " doesn't exist. Failed to create.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return -1;
+ }
tariffsDir = workDir + "/tariffs/";
+if (!CheckAndCreate(tariffsDir, GetConfModeDir()))
+ {
+ errorStr = tariffsDir + " doesn't exist. Failed to create.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return -1;
+ }
adminsDir = workDir + "/admins/";
+if (!CheckAndCreate(adminsDir, GetConfModeDir()))
+ {
+ errorStr = adminsDir + " doesn't exist. Failed to create.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return -1;
+ }
+servicesDir = workDir + "/services/";
+if (!CheckAndCreate(servicesDir, GetConfModeDir()))
+ {
+ errorStr = servicesDir + " doesn't exist. Failed to create.";
+ printfd(__FILE__, "%s\n", errorStr.c_str());
+ return -1;
+ }
return 0;
}
tariffList->swap(files);
+return 0;
+}
+//-----------------------------------------------------------------------------
+int FILES_STORE::GetServicesList(std::vector<std::string> * list) const
+{
+std::vector<std::string> files;
+
+if (GetFileList(&files, storeSettings.GetServicesDir(), S_IFREG, ".serv"))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Failed to open '" + storeSettings.GetServicesDir() + "': " + std::string(strerror(errno));
+ return -1;
+ }
+
+STG_LOCKER lock(&mutex);
+
+list->swap(files);
+
return 0;
}
//-----------------------------------------------------------------------------
else
td->tariffConf.changePolicy = TARIFF::StringToChangePolicy(str);
- if (conf.ReadString("ChangePolicyTimeout", &str, "1970-01-01 00:00:00") < 0)
- td->tariffConf.changePolicyTimeout = 0;
- else
- td->tariffConf.changePolicyTimeout = readTime(str);
+ conf.ReadTime("ChangePolicyTimeout", &td->tariffConf.changePolicyTimeout, 0);
return 0;
}
//-----------------------------------------------------------------------------
cf.WriteTime("ChangePolicyTimeout", td.tariffConf.changePolicyTimeout);
}
+return 0;
+}
+//-----------------------------------------------------------------------------*/
+int FILES_STORE::AddService(const std::string & name) const
+{
+std::string fileName;
+strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
+
+if (Touch(fileName))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Cannot create file " + fileName;
+ printfd(__FILE__, "FILES_STORE::AddService - failed to add service '%s'\n", name.c_str());
+ return -1;
+ }
+
+return 0;
+}
+//-----------------------------------------------------------------------------*/
+int FILES_STORE::DelService(const std::string & name) const
+{
+std::string fileName;
+strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
+if (unlink(fileName.c_str()))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "unlink failed. Message: '";
+ errorStr += strerror(errno);
+ errorStr += "'";
+ printfd(__FILE__, "FILES_STORE::DelAdmin - unlink failed. Message: '%s'\n", strerror(errno));
+ }
+return 0;
+}
+//-----------------------------------------------------------------------------*/
+int FILES_STORE::SaveService(const SERVICE_CONF & conf) const
+{
+std::string fileName;
+
+strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), conf.name.c_str());
+
+ {
+ CONFIGFILE cf(fileName, true);
+
+ int e = cf.Error();
+
+ if (e)
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Cannot write service " + conf.name + ". " + fileName;
+ printfd(__FILE__, "FILES_STORE::SaveService - failed to save service '%s'\n", conf.name.c_str());
+ return -1;
+ }
+
+ cf.WriteString("name", conf.name);
+ cf.WriteString("comment", conf.comment);
+ cf.WriteDouble("cost", conf.cost);
+ cf.WriteInt("pay_day", conf.payDay);
+ }
+
+return 0;
+}
+//-----------------------------------------------------------------------------
+int FILES_STORE::RestoreService(SERVICE_CONF * conf, const std::string & name) const
+{
+std::string fileName;
+strprintf(&fileName, "%s/%s.serv", storeSettings.GetServicesDir().c_str(), name.c_str());
+CONFIGFILE cf(fileName);
+
+if (cf.Error())
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Cannot open " + fileName;
+ printfd(__FILE__, "FILES_STORE::RestoreService - failed to restore service '%s'\n", name.c_str());
+ return -1;
+ }
+
+if (cf.ReadString("name", &conf->name, name))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Error in parameter 'name'";
+ printfd(__FILE__, "FILES_STORE::RestoreService - name read failed for service '%s'\n", name.c_str());
+ return -1;
+ }
+
+if (cf.ReadString("comment", &conf->comment, ""))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Error in parameter 'comment'";
+ printfd(__FILE__, "FILES_STORE::RestoreService - comment read failed for service '%s'\n", name.c_str());
+ return -1;
+ }
+
+if (cf.ReadDouble("cost", &conf->cost, 0.0))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Error in parameter 'cost'";
+ printfd(__FILE__, "FILES_STORE::RestoreService - cost read failed for service '%s'\n", name.c_str());
+ return -1;
+ }
+
+unsigned short value = 0;
+if (cf.ReadUShortInt("pay_day", &value, 0))
+ {
+ STG_LOCKER lock(&mutex);
+ errorStr = "Error in parameter 'pay_day'";
+ printfd(__FILE__, "FILES_STORE::RestoreService - pay day read failed for service '%s'\n", name.c_str());
+ return -1;
+ }
+conf->payDay = value;
+
return 0;
}
//-----------------------------------------------------------------------------
#ifndef SETTINGS_IMPL_H
#define SETTINGS_IMPL_H
- #include <string>
- #include <vector>
-
#include "stg/settings.h"
#include "stg/common.h"
#include "stg/module_settings.h"
+ #include <string>
+ #include <vector>
+
//-----------------------------------------------------------------------------
enum DETAIL_STAT_PERIOD {
dsPeriod_1,
//-----------------------------------------------------------------------------
class SETTINGS_IMPL : public SETTINGS {
public:
- SETTINGS_IMPL(const std::string &);
+ explicit SETTINGS_IMPL(const std::string &);
SETTINGS_IMPL(const SETTINGS_IMPL &);
virtual ~SETTINGS_IMPL() {}
SETTINGS_IMPL & operator=(const SETTINGS_IMPL &);
bool GetSpreadFee() const { return spreadFee; }
bool GetFreeMbAllowInet() const { return freeMbAllowInet; }
bool GetDayFeeIsLastDay() const { return dayFeeIsLastDay; }
+ bool GetStopOnError() const { return stopOnError; }
bool GetWriteFreeMbTraffCost() const
{ return writeFreeMbTraffCost; }
bool GetShowFeeInCash() const { return showFeeInCash; }
bool spreadFee;
bool freeMbAllowInet;
bool dayFeeIsLastDay;
+ bool stopOnError;
bool writeFreeMbTraffCost;
bool showFeeInCash;
unsigned messageTimeout;
userdata7(property.userdata7),
userdata8(property.userdata8),
userdata9(property.userdata9),
+ sessionUploadModTime(stgTime),
+ sessionDownloadModTime(stgTime),
passiveNotifier(this),
disabledNotifier(this),
tariffNotifier(this),
userdata7(property.userdata7),
userdata8(property.userdata8),
userdata9(property.userdata9),
+ sessionUploadModTime(stgTime),
+ sessionDownloadModTime(stgTime),
passiveNotifier(this),
disabledNotifier(this),
tariffNotifier(this),
userdata9(property.userdata9),
sessionUpload(),
sessionDownload(),
+ sessionUploadModTime(stgTime),
+ sessionDownloadModTime(stgTime),
passiveNotifier(this),
disabledNotifier(this),
tariffNotifier(this),
ResetPassiveTime();
}
//-----------------------------------------------------------------------------
+void USER_IMPL::ProcessServices()
+{
+struct tm tms;
+time_t t = stgTime;
+localtime_r(&t, &tms);
+
+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;
+ }
+ }
+
+for (size_t i = 0; i < property.Conf().services.size(); ++i)
+ {
+ SERVICE_CONF conf;
+ if (m_services.Find(property.Conf().services[i], &conf))
+ continue;
+ if (conf.payDay == tms.tm_mday ||
+ (conf.payDay == 0 && tms.tm_mday == DaysInCurrentMonth()))
+ {
+ double c = cash;
+ double fee = conf.cost * passiveTimePart;
+ printfd(__FILE__, "Service fee. login: %8s Cash=%f Credit=%f Fee=%f PassiveTimePart=%f fee=%f\n",
+ login.c_str(),
+ cash.ConstData(),
+ credit.ConstData(),
+ tariff->GetFee(),
+ passiveTimePart,
+ fee);
+ switch (settings->GetFeeChargeType())
+ {
+ case 0:
+ property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+ SetPrepaidTraff();
+ break;
+ case 1:
+ if (c + credit >= 0)
+ {
+ property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+ SetPrepaidTraff();
+ }
+ break;
+ case 2:
+ if (c + credit >= fee)
+ {
+ property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+ SetPrepaidTraff();
+ }
+ break;
+ case 3:
+ if (c >= 0)
+ {
+ property.cash.Set(c - fee, sysAdmin, login, store, "Subscriber fee charge");
+ SetPrepaidTraff();
+ }
+ break;
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
void USER_IMPL::SetPrepaidTraff()
{
if (tariff != NULL)
class CHG_PASSIVE_NOTIFIER : public PROPERTY_NOTIFIER_BASE<int>,
private NONCOPYABLE {
public:
- CHG_PASSIVE_NOTIFIER(USER_IMPL * u) : user(u) {}
+ explicit CHG_PASSIVE_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const int & oldPassive, const int & newPassive);
private:
class CHG_DISABLED_NOTIFIER : public PROPERTY_NOTIFIER_BASE<int>,
private NONCOPYABLE {
public:
- CHG_DISABLED_NOTIFIER(USER_IMPL * u) : user(u) {}
+ explicit CHG_DISABLED_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const int & oldValue, const int & newValue);
private:
class CHG_TARIFF_NOTIFIER : public PROPERTY_NOTIFIER_BASE<std::string>,
private NONCOPYABLE {
public:
- CHG_TARIFF_NOTIFIER(USER_IMPL * u) : user(u) {}
+ explicit CHG_TARIFF_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const std::string & oldTariff, const std::string & newTariff);
private:
class CHG_CASH_NOTIFIER : public PROPERTY_NOTIFIER_BASE<double>,
private NONCOPYABLE {
public:
- CHG_CASH_NOTIFIER(USER_IMPL * u) : user(u) {}
+ explicit CHG_CASH_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const double & oldCash, const double & newCash);
private:
class CHG_IPS_NOTIFIER : public PROPERTY_NOTIFIER_BASE<USER_IPS>,
private NONCOPYABLE {
public:
- CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
+ explicit CHG_IPS_NOTIFIER(USER_IMPL * u) : user(u) {}
void Notify(const USER_IPS & oldIPs, const USER_IPS & newIPs);
private:
void ProcessDayFeeSpread();
void ProcessNewMonth();
void ProcessDailyFee();
+ void ProcessServices();
bool IsInetable();
std::string GetEnabledDirs() const;
user_iter ui;
+unsigned errors = 0;
for (unsigned int i = 0; i < usersList.size(); i++)
{
USER_IMPL u(settings, store, tariffs, sysAdmin, this, m_services);
AddUserIntoIndexes(ui);
- if (ui->ReadConf() < 0)
- return -1;
+ if (settings->GetStopOnError())
+ {
+ if (ui->ReadConf() < 0)
+ return -1;
+
+ if (ui->ReadStat() < 0)
+ return -1;
+ }
+ else
+ {
+ if (ui->ReadConf() < 0)
+ errors++;
- if (ui->ReadStat() < 0)
- return -1;
+ if (ui->ReadStat() < 0)
+ errors++;
+ }
}
+if (errors > 0)
+ return -1;
return 0;
}
//-----------------------------------------------------------------------------
{
//printfd(__FILE__, "Monitor=%d file TRAFFCOUNTER %s\n", tc->monitoring, monFile.c_str());
touchTime = stgTime;
- TouchFile(monFile.c_str());
+ TouchFile(monFile);
}
stgUsleep(100000);
}
std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessDailyFee));
+std::for_each(users.begin(), users.end(), std::mem_fun_ref(&USER_IMPL::ProcessServices));
if (settings->GetDayFeeIsLastDay())
{