//-----------------------------------------------------------------------------
struct ADMIN_CONF_RES
{
+ ADMIN_CONF_RES() {}
ADMIN_CONF_RES(const ADMIN_CONF & conf)
: priv(conf.priv),
login(conf.login),
virtual std::string ParamDescription() const = 0;
virtual std::string DefaultDescription() const = 0;
virtual OPTION_BLOCK & Suboptions() = 0;
- virtual PARSER_STATE Parse(int argc, char ** argv) = 0;
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * data = NULL) = 0;
virtual void ParseValue(const std::string &) {}
class ERROR : public std::runtime_error
#include <string>
+#include <cassert>
+
namespace SGCONF
{
virtual std::string ParamDescription() const { return ""; }
virtual std::string DefaultDescription() const { return ""; }
virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv)
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/)
{
m_func();
return PARSER_STATE(true, argc, argv);
virtual std::string ParamDescription() const { return m_description; }
virtual std::string DefaultDescription() const;
virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv);
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
virtual void ParseValue(const std::string & value);
private:
template <typename T>
inline
-PARSER_STATE PARAM_ACTION<T>::Parse(int argc, char ** argv)
+PARSER_STATE PARAM_ACTION<T>::Parse(int argc, char ** argv, void * /*data*/)
{
if (argc == 0 ||
argv == NULL ||
template <>
inline
-PARSER_STATE PARAM_ACTION<std::string>::Parse(int argc, char ** argv)
+PARSER_STATE PARAM_ACTION<std::string>::Parse(int argc, char ** argv, void * /*data*/)
{
if (argc == 0 ||
argv == NULL ||
{
public:
KV_ACTION(const std::string & name,
- std::map<std::string, std::string> & kvs,
const std::string & paramDescription)
: m_name(name),
- m_kvs(kvs),
m_description(paramDescription)
{}
virtual std::string ParamDescription() const { return m_description; }
virtual std::string DefaultDescription() const { return ""; }
virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv);
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * data);
private:
std::string m_name;
- std::map<std::string, std::string> & m_kvs;
std::string m_description;
OPTION_BLOCK m_suboptions;
};
inline
-PARSER_STATE KV_ACTION::Parse(int argc, char ** argv)
+PARSER_STATE KV_ACTION::Parse(int argc, char ** argv, void * data)
{
if (argc == 0 ||
argv == NULL ||
*argv == NULL)
throw ERROR("Missing argument.");
-m_kvs[m_name] = *argv;
+assert(data != NULL && "Expecting container pointer.");
+std::map<std::string, std::string> & kvs = *static_cast<std::map<std::string, std::string>*>(data);
+kvs[m_name] = *argv;
return PARSER_STATE(false, --argc, ++argv);
}
inline
KV_ACTION * MakeKVAction(const std::string & name,
- std::map<std::string, std::string> & kvs,
const std::string & paramDescription)
{
-return new KV_ACTION(name, kvs, paramDescription);
+return new KV_ACTION(name, paramDescription);
}
} // namespace SGCONF
#include "api_action.h"
#include "options.h"
#include "config.h"
+#include "utils.h"
#include "stg/servconf.h"
#include "stg/servconf_types.h"
std::vector<SGCONF::API_ACTION::PARAM> GetAdminParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"priv", "<priv>", "priviledges"});
+params.push_back(SGCONF::API_ACTION::PARAM("password", "<password>", "password"));
+params.push_back(SGCONF::API_ACTION::PARAM("priv", "<priv>", "priviledges"));
return params;
}
+void ConvPriv(const std::string & value, RESETABLE<PRIV> & res)
+{
+if (value.length() != 9)
+ throw SGCONF::ACTION::ERROR("Priviledges value should be a 9-digits length binary number.");
+PRIV priv;
+priv.corpChg = (value[0] == '0' ? 0 : 1);
+priv.serviceChg = (value[1] == '0' ? 0 : 1);
+priv.tariffChg = (value[2] == '0' ? 0 : 1);
+priv.adminChg = (value[3] == '0' ? 0 : 1);
+priv.userAddDel = (value[4] == '0' ? 0 : 1);
+priv.userPasswd = (value[5] == '0' ? 0 : 1);
+priv.userCash = (value[6] == '0' ? 0 : 1);
+priv.userConf = (value[7] == '0' ? 0 : 1);
+priv.userStat = (value[8] == '0' ? 0 : 1);
+res = priv;
+}
+
void SimpleCallback(bool result,
const std::string & reason,
void * /*data*/)
bool AddAdminFunction(const SGCONF::CONFIG & config,
const std::string & arg,
- const std::map<std::string, std::string> & /*options*/)
+ const std::map<std::string, std::string> & options)
{
// TODO
-std::cerr << "Unimplemented.\n";
-return false;
+ADMIN_CONF_RES conf;
+conf.login = arg;
+SGCONF::MaybeSet(options, "priv", conf.priv, ConvPriv);
+STG::SERVCONF proto(config.server.data(),
+ config.port.data(),
+ config.userName.data(),
+ config.userPass.data());
+return proto.AddAdmin(arg, conf, SimpleCallback, NULL) == STG::st_ok;
}
bool ChgAdminFunction(const SGCONF::CONFIG & config,
#include "actions.h"
#include "parser_state.h"
-SGCONF::PARSER_STATE SGCONF::API_ACTION::Parse(int argc, char ** argv)
+SGCONF::PARSER_STATE SGCONF::API_ACTION::Parse(int argc, char ** argv, void * /*data*/)
{
PARSER_STATE state(false, argc, argv);
if (!m_argument.empty())
--state.argc;
++state.argv;
}
-m_suboptions.Parse(state.argc, state.argv);
+state = m_suboptions.Parse(state.argc, state.argv, &m_params);
m_commands.Add(m_funPtr, m_argument, m_params);
return state;
}
std::vector<PARAM>::const_iterator it(params.begin());
while (it != params.end())
{
- m_suboptions.Add(it->name, MakeKVAction(it->name, m_params, it->shortDescr), it->longDescr);
+ m_suboptions.Add(it->name, MakeKVAction(it->name, it->shortDescr), it->longDescr);
++it;
}
}
public:
struct PARAM
{
+ PARAM(const std::string & n,
+ const std::string & s,
+ const std::string & l)
+ : name(n),
+ shortDescr(s),
+ longDescr(l)
+ {}
std::string name;
std::string shortDescr;
std::string longDescr;
virtual std::string ParamDescription() const { return m_description; }
virtual std::string DefaultDescription() const { return ""; }
virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv);
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
private:
COMMANDS & m_commands;
std::vector<SGCONF::API_ACTION::PARAM> GetCorpParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"cash", "<cash>", "\tcorporation's cash"});
+params.push_back(SGCONF::API_ACTION::PARAM("cash", "<cash>", "\tcorporation's cash"));
return params;
}
virtual std::string ParamDescription() const { return m_description; }
virtual std::string DefaultDescription() const { return ""; }
virtual OPTION_BLOCK & Suboptions() { return m_suboptions; }
- virtual PARSER_STATE Parse(int argc, char ** argv);
+ virtual PARSER_STATE Parse(int argc, char ** argv, void * /*data*/);
private:
SGCONF::CONFIG & m_config;
};
-PARSER_STATE CONFIG_ACTION::Parse(int argc, char ** argv)
+PARSER_STATE CONFIG_ACTION::Parse(int argc, char ** argv, void * /*data*/)
{
if (argc == 0 ||
argv == NULL ||
}
config = configOverride;
+
+std::cerr << "Config: " << config.Serialize() << std::endl;
+return commands.Execute(config) ? 0 : -1;
}
catch (const std::exception& ex)
{
std::cerr << ex.what() << "\n";
return -1;
}
-
-std::cerr << "Config: " << config.Serialize() << std::endl;
-return commands.Execute(config) ? 0 : -1;
}
//-----------------------------------------------------------------------------
return false;
if (*arg == '-')
+{
return m_longName == arg + 1;
+}
return m_shortName == arg;
}
-PARSER_STATE OPTION::Parse(int argc, char ** argv)
+PARSER_STATE OPTION::Parse(int argc, char ** argv, void * data)
{
if (!m_action)
throw ERROR("Option is not defined.");
try
{
- return m_action->Parse(argc, argv);
+ return m_action->Parse(argc, argv, data);
}
catch (const ACTION::ERROR & ex)
{
std::bind2nd(std::mem_fun_ref(&OPTION::Help), level + 1));
}
-PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv)
+PARSER_STATE OPTION_BLOCK::Parse(int argc, char ** argv, void * data)
{
PARSER_STATE state(false, argc, argv);
+if (state.argc == 0)
+ return state;
while (state.argc > 0 && !state.stop)
{
std::vector<OPTION>::iterator it = std::find_if(m_options.begin(), m_options.end(), std::bind2nd(std::mem_fun_ref(&OPTION::Check), *state.argv));
if (it != m_options.end())
- state = it->Parse(--state.argc, ++state.argv);
+ state = it->Parse(--state.argc, ++state.argv, data);
else
break;
++it;
{
PARSER_STATE state(false, argc, argv);
std::list<OPTION_BLOCK>::iterator it(m_blocks.begin());
-while (!state.stop && it != m_blocks.end())
+while (state.argc > 0 && !state.stop && it != m_blocks.end())
{
state = it->Parse(state.argc, state.argv);
++it;
OPTION & operator=(const OPTION & rhs);
void Help(size_t level = 0) const;
- PARSER_STATE Parse(int argc, char ** argv);
+ PARSER_STATE Parse(int argc, char ** argv, void * data);
void ParseValue(const std::string & value);
bool Check(const char * arg) const;
const std::string & Name() const { return m_longName; }
void Help(size_t level) const;
- PARSER_STATE Parse(int argc, char ** argv);
+ PARSER_STATE Parse(int argc, char ** argv, void * data = NULL);
void ParseFile(const std::string & filePath);
class ERROR : public std::runtime_error
std::vector<SGCONF::API_ACTION::PARAM> GetServiceParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"cost", "<cost>", "\tcost of the service"});
-params.push_back({"pay-day", "<month day>", "payment day"});
-params.push_back({"comment", "<text>", "comment"});
+params.push_back(SGCONF::API_ACTION::PARAM("cost", "<cost>", "\tcost of the service"));
+params.push_back(SGCONF::API_ACTION::PARAM("pay-day", "<month day>", "payment day"));
+params.push_back(SGCONF::API_ACTION::PARAM("comment", "<text>", "comment"));
return params;
}
std::vector<SGCONF::API_ACTION::PARAM> GetTariffParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"fee", "<fee>", "\t\ttariff fee"});
-params.push_back({"free", "<free mb>", "\tprepaid traff"});
-params.push_back({"passive-cost", "<cost>", "\tpassive cost"});
-params.push_back({"traff-type", "<type>", "\ttraff type (up, dow, up+down, max)"});
-params.push_back({"period", "<period>", "\ttarification period (daily, monthly)"});
-params.push_back({"times", "<hh:mm-hh:mm, ...>", "coma-separated day time-spans for each direction"});
-params.push_back({"day-prices", "<price/price, ...>", "coma-separated day prices for each direction"});
-params.push_back({"night-prices", "<price/price, ...>", "coma-separated day prices for each direction"});
-params.push_back({"thresholds", "<threshold, ...>", "coma-separated thresholds for each direction"});
+params.push_back(SGCONF::API_ACTION::PARAM("fee", "<fee>", "\t\ttariff fee"));
+params.push_back(SGCONF::API_ACTION::PARAM("free", "<free mb>", "\tprepaid traff"));
+params.push_back(SGCONF::API_ACTION::PARAM("passive-cost", "<cost>", "\tpassive cost"));
+params.push_back(SGCONF::API_ACTION::PARAM("traff-type", "<type>", "\ttraff type (up, dow, up+down, max)"));
+params.push_back(SGCONF::API_ACTION::PARAM("period", "<period>", "\ttarification period (daily, monthly)"));
+params.push_back(SGCONF::API_ACTION::PARAM("times", "<hh:mm-hh:mm, ...>", "coma-separated day time-spans for each direction"));
+params.push_back(SGCONF::API_ACTION::PARAM("day-prices", "<price/price, ...>", "coma-separated day prices for each direction"));
+params.push_back(SGCONF::API_ACTION::PARAM("night-prices", "<price/price, ...>", "coma-separated day prices for each direction"));
+params.push_back(SGCONF::API_ACTION::PARAM("thresholds", "<threshold, ...>", "coma-separated thresholds for each direction"));
return params;
}
std::vector<SGCONF::API_ACTION::PARAM> GetUserParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"password", "<password>", "\tuser's password"});
-params.push_back({"cash", "<cash>", "\t\tuser's cash"});
-params.push_back({"credit", "<amount>", "\tuser's credit"});
-params.push_back({"credit-expire", "<date>", "\tcredit expiration"});
-params.push_back({"free", "<free mb>", "\tprepaid traffic"});
-params.push_back({"disabled", "<flag>", "\tdisable user (y|n)"});
-params.push_back({"passive", "<flag>", "\tmake user passive (y|n)"});
-params.push_back({"disable-detail-stat", "<flag>", "disable detail stat (y|n)"});
-params.push_back({"always-online", "<flag>", "\tmake user always online (y|n)"});
-params.push_back({"ips", "<ips>", "\t\tcoma-separated list of ips"});
-params.push_back({"tariff", "<tariff name>", "\tcurrent tariff"});
-params.push_back({"next-tariff", "<tariff name>", "tariff starting from the next month"});
-params.push_back({"group", "<group>", "\t\tuser's group"});
-params.push_back({"note", "<note>", "\t\tuser's note"});
-params.push_back({"email", "<email>", "\t\tuser's email"});
-params.push_back({"name", "<real name>", "\tuser's real name"});
-params.push_back({"address", "<address>", "\tuser's postal address"});
-params.push_back({"phone", "<phone>", "\t\tuser's phone number"});
-params.push_back({"session-traffic", "<up/dn, ...>", "coma-separated session upload and download"});
-params.push_back({"month-traffic", "<up/dn, ...>", "coma-separated month upload and download"});
-params.push_back({"user-data", "<value, ...>", "coma-separated user data values"});
+params.push_back(SGCONF::API_ACTION::PARAM("password", "<password>", "\tuser's password"));
+params.push_back(SGCONF::API_ACTION::PARAM("cash", "<cash>", "\t\tuser's cash"));
+params.push_back(SGCONF::API_ACTION::PARAM("credit", "<amount>", "\tuser's credit"));
+params.push_back(SGCONF::API_ACTION::PARAM("credit-expire", "<date>", "\tcredit expiration"));
+params.push_back(SGCONF::API_ACTION::PARAM("free", "<free mb>", "\tprepaid traffic"));
+params.push_back(SGCONF::API_ACTION::PARAM("disabled", "<flag>", "\tdisable user (y|n)"));
+params.push_back(SGCONF::API_ACTION::PARAM("passive", "<flag>", "\tmake user passive (y|n)"));
+params.push_back(SGCONF::API_ACTION::PARAM("disable-detail-stat", "<flag>", "disable detail stat (y|n)"));
+params.push_back(SGCONF::API_ACTION::PARAM("always-online", "<flag>", "\tmake user always online (y|n)"));
+params.push_back(SGCONF::API_ACTION::PARAM("ips", "<ips>", "\t\tcoma-separated list of ips"));
+params.push_back(SGCONF::API_ACTION::PARAM("tariff", "<tariff name>", "\tcurrent tariff"));
+params.push_back(SGCONF::API_ACTION::PARAM("next-tariff", "<tariff name>", "tariff starting from the next month"));
+params.push_back(SGCONF::API_ACTION::PARAM("group", "<group>", "\t\tuser's group"));
+params.push_back(SGCONF::API_ACTION::PARAM("note", "<note>", "\t\tuser's note"));
+params.push_back(SGCONF::API_ACTION::PARAM("email", "<email>", "\t\tuser's email"));
+params.push_back(SGCONF::API_ACTION::PARAM("name", "<real name>", "\tuser's real name"));
+params.push_back(SGCONF::API_ACTION::PARAM("address", "<address>", "\tuser's postal address"));
+params.push_back(SGCONF::API_ACTION::PARAM("phone", "<phone>", "\t\tuser's phone number"));
+params.push_back(SGCONF::API_ACTION::PARAM("session-traffic", "<up/dn, ...>", "coma-separated session upload and download"));
+params.push_back(SGCONF::API_ACTION::PARAM("month-traffic", "<up/dn, ...>", "coma-separated month upload and download"));
+params.push_back(SGCONF::API_ACTION::PARAM("user-data", "<value, ...>", "coma-separated user data values"));
return params;
}
std::vector<SGCONF::API_ACTION::PARAM> GetCheckParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"password", "<password>", "\tuser's password"});
+params.push_back(SGCONF::API_ACTION::PARAM("password", "<password>", "\tuser's password"));
return params;
}
std::vector<SGCONF::API_ACTION::PARAM> GetMessageParams()
{
std::vector<SGCONF::API_ACTION::PARAM> params;
-params.push_back({"logins", "<login, ...>", "\tlist of logins to send a message"});
-params.push_back({"text", "<text>", "\t\tmessage text"});
+params.push_back(SGCONF::API_ACTION::PARAM("logins", "<login, ...>", "\tlist of logins to send a message"));
+params.push_back(SGCONF::API_ACTION::PARAM("text", "<text>", "\t\tmessage text"));
return params;
}
--- /dev/null
+#ifndef __STG_SGCONF_UTILS_H__
+#define __STG_SGCONF_UTILS_H__
+
+#include "stg/common.h"
+#include "stg/resetable.h"
+
+#include <string>
+#include <map>
+
+namespace SGCONF
+{
+
+template <typename T>
+inline
+void MaybeSet(const std::map<std::string, std::string> & options, const std::string & name, RESETABLE<T> & res)
+{
+std::map<std::string, std::string>::const_iterator it(options.find(name));
+if (it == options.end())
+ return;
+T value;
+if (str2x(it->second, value) < 0)
+ return;
+res = value;
+}
+
+template <typename T, typename F>
+inline
+void MaybeSet(const std::map<std::string, std::string> & options, const std::string & name, RESETABLE<T> & res, F conv)
+{
+std::map<std::string, std::string>::const_iterator it(options.find(name));
+if (it == options.end())
+ return;
+conv(it->second, res);
+}
+
+template <>
+inline
+void MaybeSet<std::string>(const std::map<std::string, std::string> & options, const std::string & name, RESETABLE<std::string> & res)
+{
+std::map<std::string, std::string>::const_iterator it(options.find(name));
+if (it == options.end())
+ return;
+res = it->second;
+}
+
+} // namespace SGCONF
+
+#endif