}
USERSTAT::USERSTAT()
- : maxThreads(16),
- port(5555)
+ : isRunning(false),
+ nonstop(false),
+ errorStr(""),
+ version(USTAT_VERSION),
+ listenSocket(-1),
+ maxThreads(16),
+ port(5555),
+ thread(0),
+ users(NULL),
+ store(NULL)
{
-xmlParser = XML_ParserCreate(NULL);
pthread_mutex_init(&mutex, NULL);
}
USERSTAT::~USERSTAT()
{
-XML_ParserFree(xmlParser);
}
int USERSTAT::ParseSettings()
if (str2x<uint16_t>(*(i->value.begin()), port))
{
errorStr = "'Port' parameter must be a numeric value";
+ printfd(__FILE__, "USERSTAT::ParseSettings() %s\n", errorStr.c_str());
return -1;
}
}
if (str2x<unsigned>(*(i->value.begin()), maxThreads))
{
errorStr = "'MaxThreads' parameter must be a numeric value";
+ printfd(__FILE__, "USERSTAT::ParseSettings() %s\n", errorStr.c_str());
return -1;
}
}
if (listenSocket < 0)
{
errorStr = "Create USERSTAT socket failed.";
+ printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str());
return -1;
}
if (0 != setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &lng, 4))
{
errorStr = "Setsockopt failed. " + string(strerror(errno));
+ printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str());
return -1;
}
if (res == -1)
{
errorStr = "Bind USERSTAT socket failed";
+ printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str());
return -1;
}
if (res == -1)
{
errorStr = "Listen USERSTAT socket failed";
+ printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str());
return -1;
}
printfd(__FILE__, "USERSTAT::Prepare() listen - ok\n");
int USERSTAT::Start()
{
+if (users == NULL) {
+ errorStr = "Users must be set";
+ printfd(__FILE__, "USERSTAT::Start() %s\n", errorStr.c_str());
+ return -1;
+}
+if (store == NULL) {
+ errorStr = "Store must be set";
+ printfd(__FILE__, "USERSTAT::Start() %s\n", errorStr.c_str());
+ return -1;
+}
if (Prepare())
{
return -1;
if (pthread_create(&thread, NULL, Run, this))
{
errorStr = "Cannot create thread";
+ printfd(__FILE__, "USERSTAT::Start() %s\n", errorStr.c_str());
return -1;
}
if (pthread_kill(thread, SIGTERM))
{
errorStr = "Cannot send signal to thread";
+ printfd(__FILE__, "USERSTAT::Stop() %s\n", errorStr.c_str());
return -1;
}
for (int i = 0; i < 25; i++)
if (isRunning)
{
errorStr = "Cannot stop thread";
+ printfd(__FILE__, "USERSTAT::Stop() %s\n", errorStr.c_str());
return -1;
}
return 0;
info.store = us->store;
info.outerSocket = outerSocket;
info.done = false;
+
+ info.request.Reset();
+
us->pool.push_back(info);
it = us->pool.end();
--it;
if (pthread_create(&thread, NULL, Operate, &(*it)))
{
us->errorStr = "Cannot create thread";
- printfd(__FILE__, "Cannot create thread\n");
+ printfd(__FILE__, "USERSTAT::Run() %s\n", us->errorStr.c_str());
}
it->thread = thread;
}
int res = read(info->outerSocket, &size, sizeof(size));
if (res != sizeof(size))
{
- printfd(__FILE__, "Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res);
+ printfd(__FILE__, "USERSTAT::Operate() Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res);
info->done = true;
return NULL;
}
res = read(info->outerSocket, login, size);
if (res != size)
{
- printfd(__FILE__, "Reading login failed! Wanted %d bytes, got %d bytes.\n", 32, res);
+ printfd(__FILE__, "USERSTAT::Operate() Reading login failed! Wanted %d bytes, got %d bytes.\n", 32, res);
info->done = true;
return NULL;
}
res = read(info->outerSocket, &size, sizeof(size));
if (res != sizeof(size))
{
- printfd(__FILE__, "Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res);
+ printfd(__FILE__, "USERSTAT::Operate() Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res);
info->done = true;
return NULL;
}
res = read(info->outerSocket, buf, size);
if (res != size)
{
- printfd(__FILE__, "Reading stream failed! Wanted %d bytes, got %d bytes.\n", size, res);
+ printfd(__FILE__, "USERSTAT::Operate() Reading stream failed! Wanted %d bytes, got %d bytes.\n", size, res);
info->done = true;
return NULL;
}
+ buf[res] = 0;
- printfd(__FILE__, "Received data: %s\n", buf);
+ printfd(__FILE__, "USERSTAT::Operate() Received data: %s\n", buf);
- user_iter it;
- if (info->users->FindByName(l, &it))
+ if (info->users->FindByName(l, &(info->uit)))
{
- printfd(__FILE__, "User '%s' not found.\n", login);
+ printfd(__FILE__, "USERSTAT::Operate() User '%s' not found.\n", login);
info->done = true;
return NULL;
}
- std::string password = it->property.password;
+ std::string password = info->uit->property.password;
printfd(__FILE__, "USERSTAT::Operate() Requested user: '%s'\n", login);
printfd(__FILE__, "USERSTAT::Operate() Encription init using password: '%s'\n", password.c_str());
delete[] key;
- printfd(__FILE__, "Received XML: %s\n", buf);
+ printfd(__FILE__, "USERSTAT::Operate() Received XML: %s\n", buf);
+
+ if (XML_Parse(info->xmlParser,
+ reinterpret_cast<char *>(buf),
+ size,
+ 1) != XML_STATUS_OK) {
+ printfd(__FILE__, "USERSTAT::Operate() Invalid password\n", login);
+ info->done = true;
+ delete[] buf;
+ return NULL;
+ }
+
+ if (!info->request.isOk) {
+ printfd(__FILE__, "USERSTAT::Operate() Malformed XML\n");
+ info->done = true;
+ delete[] buf;
+ return NULL;
+ }
+
+ info->Handle();
+
+ std::cout << "USERSTAT::Operate() Request:" << std::endl;
+ std::for_each(info->request.conf.begin(),
+ info->request.conf.end(),
+ THREAD_INFO::LinePrinter());
+ std::for_each(info->request.stat.begin(),
+ info->request.stat.end(),
+ THREAD_INFO::LinePrinter());
info->done = true;
delete[] buf;
return NULL;
}
+
+void TIParseXMLStart(void * data, const char * name, const char ** attr)
+{
+ THREAD_INFO * ti = reinterpret_cast<THREAD_INFO *>(data);
+ if (strncmp(name, "request", 7) == 0) {
+ if (attr == NULL) {
+ printfd(__FILE__, "ParseXMLStart() 'reqest' tag require a 'login' parameter\n");
+ ti->request.isOk |= false;
+ return;
+ } else {
+ ti->request.login = *attr;
+ }
+ } else if (strncmp(name, "stat", 4)) {
+ ti->pvList = &(ti->request.stat);
+ } else if (strncmp(name, "conf", 4)) {
+ ti->pvList = &(ti->request.conf);
+ } else {
+ if (ti->pvList == NULL) {
+ printfd(__FILE__, "ParseXMLStart() Unexpected tag: '%s'\n", name);
+ ti->request.isOk |= false;
+ return;
+ }
+ (*ti->pvList)[name];
+ }
+}
+
+void TIParseXMLEnd(void * data, const char * name)
+{
+ THREAD_INFO * ti = reinterpret_cast<THREAD_INFO *>(data);
+ if (strncmp(name, "stat", 4) == 0) {
+ ti->pvList = NULL;
+ } else if (strncmp(name, "conf", 4) == 0) {
+ ti->pvList = NULL;
+ } else if (strncmp(name, "request", 7) == 0) {
+ }
+}
+
+THREAD_INFO::THREAD_INFO() : pvList(NULL),
+ users(NULL),
+ store(NULL),
+ outerSocket(-1),
+ done(true)
+{
+ printfd(__FILE__, "THREAD_INFO::THREAD_INFO()\n");
+ xmlParser = XML_ParserCreate(NULL);
+
+ if (!xmlParser)
+ {
+ printfd(__FILE__, "USERSTAT::Run() Couldn't allocate memory for parser\n");
+ }
+
+ XML_ParserReset(xmlParser, NULL);
+ XML_SetElementHandler(xmlParser, TIParseXMLStart, TIParseXMLEnd);
+ XML_SetUserData(xmlParser, this);
+}
+
+THREAD_INFO::~THREAD_INFO()
+{
+ printfd(__FILE__, "THREAD_INFO::~THREAD_INFO()\n");
+ XML_ParserFree(xmlParser);
+}
+
+int THREAD_INFO::Handle()
+{
+ if (!request.isOk)
+ return -1;
+
+ if (HandleStat())
+ return -1;
+
+ if (HandleConf())
+ return -1;
+
+ return 0;
+}
+
+int THREAD_INFO::HandleConf()
+{
+ PV_LIST::iterator it(request.conf.begin());
+
+ for (; it != request.conf.end(); ++it)
+ {
+ if (it->first == "password")
+ {
+ it->second = uit->property.password;
+ }
+ else if (it->first == "passive")
+ {
+ it->second = uit->property.passive;
+ }
+ else if (it->first == "disabled")
+ {
+ it->second = uit->property.disabled;
+ }
+ else if (it->first == "disabledDetailStat")
+ {
+ it->second = uit->property.disabledDetailStat;
+ }
+ else if (it->first == "alwaysOnline")
+ {
+ it->second = uit->property.alwaysOnline;
+ }
+ else if (it->first == "tariffName")
+ {
+ it->second = uit->property.tariffName;
+ }
+ else if (it->first == "address")
+ {
+ it->second = uit->property.address;
+ }
+ else if (it->first == "phone")
+ {
+ it->second = uit->property.phone;
+ }
+ else if (it->first == "email")
+ {
+ it->second = uit->property.email;
+ }
+ else if (it->first == "note")
+ {
+ it->second = uit->property.note;
+ }
+ else if (it->first == "realName")
+ {
+ it->second = uit->property.realName;
+ }
+ else if (it->first == "group")
+ {
+ it->second = uit->property.group;
+ }
+ else if (it->first == "credit")
+ {
+ it->second = uit->property.credit;
+ }
+ else if (it->first == "creditExpire")
+ {
+ it->second = uit->property.creditExpire;
+ }
+ else if (it->first == "nextTariff")
+ {
+ it->second = uit->property.nextTariff;
+ }
+ else
+ {
+ printfd(__FILE__, "THREAD_INFO::HandleConf() Invalid param: '%s'\n", it->first.c_str());
+ }
+ }
+
+ return 0;
+}
+
+int THREAD_INFO::HandleStat()
+{
+ PV_LIST::iterator it(request.conf.begin());
+
+ for (; it != request.conf.end(); ++it)
+ {
+ if (it->first == "cash")
+ {
+ it->second = uit->property.password;
+ }
+ else
+ {
+ printfd(__FILE__, "THREAD_INFO::HandleConf() Invalid param: '%s'\n", it->first.c_str());
+ }
+ }
+
+ return 0;
+}