From 4ab6759cf046b076e454cbf01bc4b299e4e63794 Mon Sep 17 00:00:00 2001 From: Maxim Mamontov Date: Mon, 8 Nov 2010 12:27:32 +0200 Subject: [PATCH] =?utf8?q?=D0=A1=D0=B8=D0=BD=D1=85=D1=80=D0=BE=D0=BD=D0=B8?= =?utf8?q?=D0=B7=D0=B8=D1=80=D1=83=D1=8E=20=D0=B8=D1=81=D1=85=D0=BE=D0=B4?= =?utf8?q?=D0=BD=D0=B8=D0=BA=D0=B8=20=D0=BC=D0=B5=D1=80=D1=82=D0=B2=D1=8B?= =?utf8?q?=D1=85=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2=20?= =?utf8?q?=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0=20=D1=8E=D0=B7=D0=B5?= =?utf8?q?=D1=80=D1=81=D0=BA=D0=BE=D0=B9=20=D1=81=D1=82=D0=B0=D1=82=D0=B8?= =?utf8?q?=D1=81=D1=82=D0=B8=D0=BA=D0=B8=20=D0=B8=20=D1=83=D0=BD=D0=B8?= =?utf8?q?=D0=B2=D0=B5=D1=80=D1=81=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3?= =?utf8?q?=D0=BE=20=D0=B4=D1=80=D0=B0=D0=B9=D0=B2=D0=B5=D1=80=D0=B0=20?= =?utf8?q?=D0=91=D0=94.=20=D0=92=D0=B4=D1=80=D1=83=D0=B3=20=D0=BA=D0=BE?= =?utf8?q?=D0=B3=D0=B4=D0=B0-=D1=82=D0=BE=20=D0=BA=D0=BE=D0=BC=D1=83-?= =?utf8?q?=D1=82=D0=BE=20=D0=BF=D0=BE=D0=BD=D0=B0=D0=B4=D0=BE=D0=B1=D1=8F?= =?utf8?q?=D1=82=D1=81=D1=8F...?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../stargazer/plugins/other/userstat/Makefile | 5 +- .../plugins/other/userstat/datathread.cpp | 384 ++++++++++++------ .../plugins/other/userstat/datathread.h | 99 +++-- .../plugins/other/userstat/userstat.cpp | 254 +++++++++++- .../plugins/other/userstat/userstat.h | 50 +-- .../stargazer/plugins/store/db/pg_driver.cpp | 18 +- .../stargazer/plugins/store/db/pg_driver.h | 4 + 7 files changed, 590 insertions(+), 224 deletions(-) diff --git a/projects/stargazer/plugins/other/userstat/Makefile b/projects/stargazer/plugins/other/userstat/Makefile index 23470f88..0046e2cf 100644 --- a/projects/stargazer/plugins/other/userstat/Makefile +++ b/projects/stargazer/plugins/other/userstat/Makefile @@ -1,5 +1,5 @@ ############################################################################### -# $Id: Makefile,v 1.1 2008/07/05 12:35:53 faust Exp $ +# $Id: Makefile,v 1.4 2007/09/26 14:07:28 faust Exp $ ############################################################################### include ../../../../../Makefile.conf @@ -20,7 +20,8 @@ endif PROG = mod_userstat.so -SRCS = ./userstat.cpp +SRCS = ./userstat.cpp \ + ./datathread.cpp LIBS += -lstg_common \ -lstg_crypto diff --git a/projects/stargazer/plugins/other/userstat/datathread.cpp b/projects/stargazer/plugins/other/userstat/datathread.cpp index 40d44305..2409d481 100644 --- a/projects/stargazer/plugins/other/userstat/datathread.cpp +++ b/projects/stargazer/plugins/other/userstat/datathread.cpp @@ -1,193 +1,327 @@ #include "datathread.h" -bool DataThread::Init() +DataThread::DataThread() + : tid(-1), + users(NULL), + store(NULL), + sock(-1), + done(true), + pvList(NULL), + data(NULL), + dataSize(0) { - parser = XML_ParserCreate(NULL); - if (!parser) { - printfd(__FILE__, "Error creating XML parser\n"); +xmlParser = XML_ParserCreate(NULL); +if (!xmlParser) + { + printfd(__FILE__, "DataThread::DataThread() Failed to create parser\n"); + return; } - XML_SetStartElementHandler(parser, StartHandler); - XML_SetEndElementHandler(parser, EndHandler); - XML_SetCharacterDataHandler(parser, DataHandler); +XML_SetElementHandler(xmlParser, DTXMLStart, DTXMLEnd); } DataThread::~DataThread() { - XML_ParserFree(parser); +XML_ParserFree(xmlParser); } -void * DataThread::Run(void * val) +bool DataThread::Handle(int s) { - DataThread * dt = reinterpret_cast(val); - - running = true; - stoppped = false; - while (running) { - if (sock >= 0) { - done = false; - dt->Handle(); - done = true; - close(sock); - sock = -1; - } else { - usleep(1000); - } +if (users == NULL) + { + printfd(__FILE__, "DataThread::Handle() Users not set\n"); + return false; } - stopped = true; - running = false; +if (store == NULL) + { + printfd(__FILE__, "DataThread::Handle() Storage not set\n"); + return false; + } + +sock = s; - return NULL; +if (pthread_create(&tid, NULL, Run, this)) + { + printfd(__FILE__, "DataThread::Handle() Failed to create thread\n"); + return false; + } +if (pthread_detach(tid)) + { + printfd(__FILE__, "DataThread::Handle() Cannot detach the thread\n"); + } +return true; } -void DataThread::Handle() +void * DataThread::Run(void * self) { - int32_t size; - unsigned char * buf; +DataThread * dt = reinterpret_cast(self); - if (!PrepareContext()) - return; +dt->done = false; - res = read(sock, &size, sizeof(size)); - if (res != sizeof(size)) +if (dt->ReadRequest()) { - printfd(__FILE__, "Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res); - return; + if (dt->DecodeRequest()) + { + if (dt->ParseRequest()) + { + if (dt->MakeAnswer()) + { + printfd(__FILE__, "DataThread::Run() All done\n"); + } + else + { + printfd(__FILE__, "DataThread::Run() Failed to answer the request\n"); + } + } + else + { + printfd(__FILE__, "DataThread::Run() Cannot parse the request\n"); + } + } + else + { + printfd(__FILE__, "DataThread::Run() Cannot decode the request\n"); + } + } +else + { + printfd(__FILE__, "DataThread::Run() Cannot read the request\n"); } - printfd(__FILE__, "DataThread::Handle() size = %d\n", size); +dt->Cleanup(); - if (size < 0) { - printfd(__FILE__, "DataThread::Handle() Invalid data size.\n"); - return; +return NULL; +} + +bool DataThread::ReadRequest() +{ +int32_t size; +char * buf; + +int res = read(sock, &size, sizeof(size)); +if (res != sizeof(size)) + { + printfd(__FILE__, "DataThread::ReadRequest() Reading login size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res); + done = true; + return false; } - buf = new unsigned char[size]; - res = read(sock, buf, size); - if (res != size) +if (size < 0) { - printfd(__FILE__, "Reading stream failed! Wanted %d bytes, got %d bytes.\n", size, res); - return; + printfd(__FILE__, "DataThread::ReadRequest() Invalid login size.\n"); + done = true; + return false; } - std::string data; - Decode(buf, data, size); +buf = new char[size]; + +res = read(sock, buf, size); +if (res != size) + { + printfd(__FILE__, "DataThread::ReadRequest() Reading login failed! Wanted %d bytes, got %d bytes.\n", size, res); + delete[] buf; + done = true; + return false; + } - printfd(__FILE__, "Received XML: %s\n", data.c_str()); +login.assign(buf, size); +delete[] buf; - XML_ParserReset(parser, NULL); +res = read(sock, &size, sizeof(size)); +if (res != sizeof(size)) + { + printfd(__FILE__, "DataThread::ReadRequest() Reading request size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res); + done = true; + return false; + } - if (XML_Parse(parser, data.c_str(), data.length(), true) == XML_STATUS_OK) { - SendReply(); - } else { - SendError(); +if (size < 0) + { + printfd(__FILE__, "DataThread::ReadRequest() Invalid request size.\n"); + done = true; + return false; } - delete[] buf; +data = new char[size + 1]; +dataSize = size; - return; +res = read(sock, data, size); +if (res != size) + { + printfd(__FILE__, "DataThread::ReadRequest() Reading request failed! Wanted %d bytes, got %d bytes.\n", size, res); + done = true; + return false; + } +data[res] = 0; + +return true; } -bool DataThread::PrepareContext() +bool DataThread::DecodeRequest() { - int32_t size; - char * login; - - int res = read(sock, &size, sizeof(size)); - if (res != sizeof(size)) +if (users->FindByName(login, &(uit))) { - printfd(__FILE__, "Reading stream size failed! Wanted %d bytes, got %d bytes.\n", sizeof(size), res); - return; + printfd(__FILE__, "DataThread::DecodeRequest() User '%s' not found.\n", login.c_str()); + done = true; + return false; } - printfd(__FILE__, "DataThread::Handle() size = %d\n", size); +std::string password = uit->property.password; - if (size < 0) { - printfd(__FILE__, "DataThread::Handle() Invalid data size.\n"); - return; - } +BLOWFISH_CTX ctx; +char * key = new char[password.length()]; +strncpy(key, password.c_str(), password.length()); - login = new char[size]; +Blowfish_Init(&ctx, + reinterpret_cast(key), + password.length()); - res = read(sock, login, size); - if (res != size) +for (int i = 0; i < dataSize / 8; ++i) { - printfd(__FILE__, "Reading login failed! Wanted %d bytes, got %d bytes.\n", 32, res); - return; + uint32_t a; + uint32_t b; + a = n2l(reinterpret_cast(data + i * 8)); + b = n2l(reinterpret_cast(data + i * 8 + 4)); + Blowfish_Decrypt(&ctx, + &a, + &b); + l2n(a, reinterpret_cast(data + i * 8)); + l2n(b, reinterpret_cast(data + i * 8 + 4)); } - std::string l; - l.assign(login, size); - delete[] login; +delete[] key; - user_iter it; - if (users->FindByName(l, &it)) +return true; +} + +bool DataThread::ParseRequest() +{ +if (XML_Parse(xmlParser, data, dataSize, 1) != XML_STATUS_OK) { - printfd(__FILE__, "User '%s' not found.\n", login); - return; + printfd(__FILE__, "DataThread::ParseRequest() Failed to parse the request\n"); + request.isBad = true; + return false; } +return true; +} - password = it->property.password; - - printfd(__FILE__, "DataThread::Handle() Requested user: '%s'\n", login); - printfd(__FILE__, "DataThread::Handle() Encryption initiated using password: '%s'\n", password.c_str()); - - char * key = new char[password.length()]; - strncpy(key, password.c_str(), password.length()); +bool DataThread::MakeAnswer() +{ +if (MakeConf()) + { + if (MakeStat()) + { + if (SendAnswer()) + { + // All is ok + } + else + { + printfd(__FILE__, "DataThread::MakeAnswer() Failed to send answer"); + return false; + } + } + else + { + printfd(__FILE__, "DataThread::MakeAnswer() Failed to make stat answer\n"); + return false; + } + } +else + { + printfd(__FILE__, "DataThread::MakeAnswer() Failed to make conf answer\n"); + return false; + } - Blowfish_Init(&ctx, - reinterpret_cast(key), - password.length()); - delete[] key; +return true; +} - return true; +void DataThread::Cleanup() +{ +delete[] data; +dataSize = 0; +login = ""; +done = false; +data = NULL; +request.conf.erase(request.conf.begin(), request.conf.end()); +request.stat.erase(request.stat.begin(), request.stat.end()); +request.login = ""; +request.isOk = true; +request.isBad = false; } -void DataThread::Encode(const std::string & src, char * dst, int size) +void DataThread::ParseTag(const std::string & name, const char ** attr) { - const char * ptr = src.c_str(); - for (int i = 0; i < size / 8; ++i) { - uint32_t a; - uint32_t b; - a = n2l(ptr + i * 8); - b = n2l(ptr + i * 8 + 4); - Blowfish_Encrypt(&ctx, - &a, - &b); - l2n(a, dst + i * 8); - l2n(b, dst + i * 8 + 4); +if (request.isBad) + return; +if (name == "request") + { + if (attr == NULL) + { + printfd(__FILE__, "DataThread::ParseTag() 'request' tag require an attribute\n"); + request.isBad = true; + return; + } + else + { + std::string attrName(*attr++); + std::string attrValue(*attr++); + if (attr != NULL) + { + printfd(__FILE__, "DataThread::ParseTag() Extra attributes on tag 'request'\n"); + } + if (attrName == "login") + { + if (attrValue != login) + { + printfd(__FILE__, "DataThread::ParseTag() Logins doesn't match\n"); + request.isBad = true; + return; + } + } + else + { + printfd(__FILE__, "DataThread::ParseTag() Unexpected attribute '%s'\n", attrName.c_str()); + request.isBad = true; + return; + } + } + } +else if (name == "conf") + { + pvList = &(request.conf); + } +else if (name == "stat") + { + pvList = &(request.stat); + } +else + { + (*pvList)[name]; } } -void DataThread::Decode(char * src, std::string & dst, int size) +bool DataThread::MakeConf() { - char tmp[9]; - tmp[8] = 0; - dst = ""; - - for (int i = 0; i < size / 8; ++i) { - uint32_t a; - uint32_t b; - a = n2l(src + i * 8); - b = n2l(src + i * 8 + 4); - Blowfish_Decrypt(&ctx, - &a, - &b); - l2n(a, tmp); - l2n(b, tmp + 4); - - dst += tmp; - } +return false; +} + +bool DataThread::MakeStat() +{ +return false; } -void StartHandler(void *data, const char *el, const char **attr) +bool DataThread::SendAnswer() { - printfd(__FILE__, "Node: %s\n", el); +return false; } -void EndHandler(void *data, const char *el) +void DTXMLStart(void * data, const char * name, const char ** attr) { +DataThread * dt = reinterpret_cast(data); +dt->ParseTag(name, attr); } -void DataHandler(void *data, const char *el) +void DTXMLEnd(void * data, const char * name) { +//DataThread * dt = reinterpret_cast(data); } diff --git a/projects/stargazer/plugins/other/userstat/datathread.h b/projects/stargazer/plugins/other/userstat/datathread.h index cd9a87b6..4371516e 100644 --- a/projects/stargazer/plugins/other/userstat/datathread.h +++ b/projects/stargazer/plugins/other/userstat/datathread.h @@ -1,58 +1,87 @@ #ifndef __DATATHREAD_H__ #define __DATATHREAD_H__ -#include "../../../users.h" -#include "base_store.h" -#include +#include +#include + #include +#include + +#include "common.h" +#include "../../../users.h" + +uint32_t n2l(unsigned char * c) +{ + uint32_t t = *c++ << 24; + t += *c++ << 16; + t += *c++ << 8; + t += *c; + return t; +} + +void l2n(uint32_t t, unsigned char * c) +{ + *c++ = t >> 24 & 0x000000FF; + *c++ = t >> 16 & 0x000000FF; + *c++ = t >> 8 & 0x000000FF; + *c++ = t & 0x000000FF; +} + +typedef std::map PV_LIST; class DataThread { public: - DataThread() : done(false), sock(-1) { Init(); }; - DataThread(USERS * u, BASE_STORE * s, int sd) - : users(u), - store(s), - sock(sd), - done(false) - { - Init(); - }; + DataThread(); ~DataThread(); void SetUsers(USERS * u) { users = u; }; void SetStore(BASE_STORE * s) { store = s; }; - void SetSocket(int s) { sock = s; }; bool isDone() const { return done; }; - bool Init(); - - bool Start(); - bool Stop(); - - static void * Run(void *); + bool Handle(int s); + friend void DTXMLStart(void * data, const char * name, const char ** attr); + friend void DTXMLEnd(void * data, const char * name); private: - pthread_t thread; + pthread_t tid; USERS * users; BASE_STORE * store; - XML_Parser parser; int sock; bool done; - bool running; - bool stopped; - BLOWFISH_CTX ctx; - std::string password; - std::string reply; - - void Handle(); - bool PrepareContect(); - void Encode(const std::string &, char *); - void Decode(char *, const std::string &); - - friend void StartHandler(void *data, const char *el, const char **attr); - friend void EndHandler(void *data, const char *el); - friend void DataHandler(void *data, const char *el); + struct Request { + PV_LIST conf; + PV_LIST stat; + std::string login; + bool isOk; + bool isBad; + } request; + PV_LIST * pvList; + char * data; + int32_t dataSize; + + std::string login; + user_iter uit; + + XML_Parser xmlParser; + + static void * Run(void * self); + + bool ReadRequest(); + bool DecodeRequest(); + bool ParseRequest(); + bool MakeAnswer(); + + bool MakeConf(); + bool MakeStat(); + bool SendAnswer(); + + void Cleanup(); + + void ParseTag(const std::string & name, const char ** attr); }; +void DTXMLStart(void * data, const char * name, const char ** attr); +void DTXMLEnd(void * data, const char * name); + #endif diff --git a/projects/stargazer/plugins/other/userstat/userstat.cpp b/projects/stargazer/plugins/other/userstat/userstat.cpp index eca424e8..6b97111d 100644 --- a/projects/stargazer/plugins/other/userstat/userstat.cpp +++ b/projects/stargazer/plugins/other/userstat/userstat.cpp @@ -15,16 +15,22 @@ return new USERSTAT(); } 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() @@ -41,6 +47,7 @@ for(i = settings.moduleParams.begin(); i != settings.moduleParams.end(); ++i) if (str2x(*(i->value.begin()), port)) { errorStr = "'Port' parameter must be a numeric value"; + printfd(__FILE__, "USERSTAT::ParseSettings() %s\n", errorStr.c_str()); return -1; } } @@ -49,6 +56,7 @@ for(i = settings.moduleParams.begin(); i != settings.moduleParams.end(); ++i) if (str2x(*(i->value.begin()), maxThreads)) { errorStr = "'MaxThreads' parameter must be a numeric value"; + printfd(__FILE__, "USERSTAT::ParseSettings() %s\n", errorStr.c_str()); return -1; } } @@ -64,6 +72,7 @@ listenSocket = socket(PF_INET, SOCK_STREAM, 0); if (listenSocket < 0) { errorStr = "Create USERSTAT socket failed."; + printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str()); return -1; } @@ -78,6 +87,7 @@ int lng = 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; } @@ -88,6 +98,7 @@ int res = bind(listenSocket, (struct sockaddr*)&listenAddr, sizeof(listenAddr)); if (res == -1) { errorStr = "Bind USERSTAT socket failed"; + printfd(__FILE__, "USERSTAT::Prepare() %s\n", errorStr.c_str()); return -1; } @@ -97,6 +108,7 @@ res = listen(listenSocket, 0); 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"); @@ -112,6 +124,16 @@ return close(listenSocket); 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; @@ -120,6 +142,7 @@ nonstop = true; if (pthread_create(&thread, NULL, Run, this)) { errorStr = "Cannot create thread"; + printfd(__FILE__, "USERSTAT::Start() %s\n", errorStr.c_str()); return -1; } @@ -132,6 +155,7 @@ nonstop = false; 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++) @@ -144,6 +168,7 @@ 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; @@ -174,6 +199,9 @@ while (us->nonstop) info.store = us->store; info.outerSocket = outerSocket; info.done = false; + + info.request.Reset(); + us->pool.push_back(info); it = us->pool.end(); --it; @@ -181,7 +209,7 @@ while (us->nonstop) 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; } @@ -200,7 +228,7 @@ void * USERSTAT::Operate(void * i) 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; } @@ -218,7 +246,7 @@ void * USERSTAT::Operate(void * i) 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; } @@ -229,7 +257,7 @@ void * USERSTAT::Operate(void * i) 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; } @@ -246,22 +274,22 @@ void * USERSTAT::Operate(void * i) 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()); @@ -288,9 +316,205 @@ void * USERSTAT::Operate(void * i) 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(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(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(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; +} diff --git a/projects/stargazer/plugins/other/userstat/userstat.h b/projects/stargazer/plugins/other/userstat/userstat.h index 83f66202..9dd01f25 100644 --- a/projects/stargazer/plugins/other/userstat/userstat.h +++ b/projects/stargazer/plugins/other/userstat/userstat.h @@ -19,47 +19,26 @@ */ /* - $Revision: 1.1 $ - $Date: 2008/07/05 12:35:53 $ - $Author: faust $ + $Revision: $ + $Date: $ + $Author: $ */ #ifndef __USERSTAT_H__ #define __USERSTAT_H__ -#include +#include +#include +#include + #include #include #include "base_plugin.h" -extern "C" BASE_PLUGIN * GetPlugin(); - -struct THREAD_INFO -{ - pthread_t thread; - USERS * users; - BASE_STORE * store; - int outerSocket; - bool done; -}; - -uint32_t n2l(unsigned char * c) -{ - uint32_t t = *c++ << 24; - t += *c++ << 16; - t += *c++ << 8; - t += *c; - return t; -} +#define USTAT_VERSION "UserStats 1.0_alt" -void l2n(uint32_t t, unsigned char * c) -{ - *c++ = t >> 24 & 0x000000FF; - *c++ = t >> 16 & 0x000000FF; - *c++ = t >> 8 & 0x000000FF; - *c++ = t & 0x000000FF; -} +extern "C" BASE_PLUGIN * GetPlugin(); class USERSTAT : public BASE_PLUGIN { @@ -85,9 +64,9 @@ public: virtual uint16_t GetStopPosition() const { return 0; }; private: - struct IsDone : public unary_function + struct IsDone : public unary_function { - bool operator()(const THREAD_INFO & info) { return info.done; }; + bool operator()(const DataThread & info) { return info.IsDone(); }; }; struct ToLower : public unary_function { @@ -97,7 +76,7 @@ private: bool nonstop; std::string errorStr; std::string version; - std::vector pool; + std::vector pool; int listenSocket; int threads; unsigned maxThreads; @@ -110,15 +89,10 @@ private: MODULE_SETTINGS settings; - XML_Parser xmlParser; - int Prepare(); int Finalize(); static void * Run(void *); static void * Operate(void *); - - friend void ParseXMLStart(void * data, char * name, char ** attr); - friend void ParseXMLEnd(void * data, char * name); }; #endif diff --git a/projects/stargazer/plugins/store/db/pg_driver.cpp b/projects/stargazer/plugins/store/db/pg_driver.cpp index 4dda25d3..61adda26 100644 --- a/projects/stargazer/plugins/store/db/pg_driver.cpp +++ b/projects/stargazer/plugins/store/db/pg_driver.cpp @@ -21,9 +21,9 @@ PG_DRIVER::~PG_DRIVER() bool PG_DRIVER::Connect() { std::stringstream params; - params << "host=" << host << " " - << "dbname=" << database << " " - << "user=" << user << " " + params << "host=" << host + << "dbname=" << database + << "user=" << user << "password=" << password; std::string str = params.str(); conn = PQconnectdb(str.c_str()); @@ -35,7 +35,8 @@ bool PG_DRIVER::Disconnect() { if (PQstatus(conn) == CONNECTION_OK) { PQfinish(conn); - conn = NULL; + errorMsg = PQerrorMessage(conn); + return PQstatus(conn) != CONNECTION_BAD; } return false; @@ -43,6 +44,9 @@ bool PG_DRIVER::Disconnect() bool PG_DRIVER::Query(const std::string & query) { + cols.erase(cols.begin(), cols.end()); + cols.reserve(columns); + PQclear(result); result = PQexec(conn, query.c_str()); errorMsg = PQerrorMessage(conn); @@ -50,13 +54,9 @@ bool PG_DRIVER::Query(const std::string & query) columns = PQnfields(result); affected = atoi(PQcmdTuples(result)); - cols.erase(cols.begin(), cols.end()); - cols.reserve(columns); - if (tuples) { - for (int i = 0; i < columns; ++i) { + for (int i = 0; i < columns; ++i) cols.push_back(PQfname(result, i)); - } } if (!result) diff --git a/projects/stargazer/plugins/store/db/pg_driver.h b/projects/stargazer/plugins/store/db/pg_driver.h index a6cee6e2..95b938fa 100644 --- a/projects/stargazer/plugins/store/db/pg_driver.h +++ b/projects/stargazer/plugins/store/db/pg_driver.h @@ -5,6 +5,9 @@ #include "base_db.h" +extern "C" BASE_DB * CreateDriver(); +extern "C" void DestroyDriver(BASE_DB *); + class PG_DRIVER : public BASE_DB { public: virtual ~PG_DRIVER(); @@ -22,6 +25,7 @@ public: private: PGconn * conn; PGresult * result; + COLUMNS cols; }; #endif -- 2.44.2