X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/641204dfbdb9fc870cdd2e7f9e3169a44693e7bf..1a9bbae3582d2e2a9c10f50ddc47bf8d23101cdc:/projects/stargazer/plugins/other/userstat/userstat.cpp 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; +}