универсального драйвера БД. Вдруг когда-то кому-то понадобятся...
###############################################################################
-# $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
PROG = mod_userstat.so
-SRCS = ./userstat.cpp
+SRCS = ./userstat.cpp \
+ ./datathread.cpp
LIBS += -lstg_common \
-lstg_crypto
#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<DataThread *>(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<DataThread *>(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<unsigned char *>(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<unsigned char *>(data + i * 8));
+ b = n2l(reinterpret_cast<unsigned char *>(data + i * 8 + 4));
+ Blowfish_Decrypt(&ctx,
+ &a,
+ &b);
+ l2n(a, reinterpret_cast<unsigned char *>(data + i * 8));
+ l2n(b, reinterpret_cast<unsigned char *>(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<unsigned char *>(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<DataThread *>(data);
+dt->ParseTag(name, attr);
}
-void DataHandler(void *data, const char *el)
+void DTXMLEnd(void * data, const char * name)
{
+//DataThread * dt = reinterpret_cast<DataThread *>(data);
}
#ifndef __DATATHREAD_H__
#define __DATATHREAD_H__
-#include "../../../users.h"
-#include "base_store.h"
-#include <pthread.h>
+#include <map>
+#include <string>
+
#include <expat.h>
+#include <pthread.h>
+
+#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<std::string, std::string> 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
}
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;
+}
*/
/*
- $Revision: 1.1 $
- $Date: 2008/07/05 12:35:53 $
- $Author: faust $
+ $Revision: $
+ $Date: $
+ $Author: $
*/
#ifndef __USERSTAT_H__
#define __USERSTAT_H__
-#include <expat.h>
+#include <string>
+#include <map>
+#include <functional>
+
#include <pthread.h>
#include <netinet/in.h>
#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
{
virtual uint16_t GetStopPosition() const { return 0; };
private:
- struct IsDone : public unary_function<THREAD_INFO, bool>
+ struct IsDone : public unary_function<DataThread, bool>
{
- bool operator()(const THREAD_INFO & info) { return info.done; };
+ bool operator()(const DataThread & info) { return info.IsDone(); };
};
struct ToLower : public unary_function<char, char>
{
bool nonstop;
std::string errorStr;
std::string version;
- std::vector<THREAD_INFO> pool;
+ std::vector<DataThread> pool;
int listenSocket;
int threads;
unsigned maxThreads;
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
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());
{
if (PQstatus(conn) == CONNECTION_OK) {
PQfinish(conn);
- conn = NULL;
+ errorMsg = PQerrorMessage(conn);
+ return PQstatus(conn) != CONNECTION_BAD;
}
return false;
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);
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)
#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();
private:
PGconn * conn;
PGresult * result;
+ COLUMNS cols;
};
#endif