X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/1347f3d1e04bedd1508589173f577673ee2c5554..35b724400e504ae6f69a478339e4549475957bb9:/projects/rlm_stg/iface.cpp?ds=sidebyside diff --git a/projects/rlm_stg/iface.cpp b/projects/rlm_stg/iface.cpp index 741017b5..d99dd393 100644 --- a/projects/rlm_stg/iface.cpp +++ b/projects/rlm_stg/iface.cpp @@ -1,41 +1,154 @@ #include "iface.h" -#include "thriftclient.h" +#include "stg_client.h" +#include "radlog.h" -int stgInstantiateImpl(const char * server, uint16_t port, const char * password) +#include + +#include + +namespace { - if (STG_CLIENT_ST::Get().Configure(server, port, password)) - return 1; - return 0; +struct Response +{ + bool done; + pthread_mutex_t mutex; + pthread_cond_t cond; + RESULT result; + bool status; + + static bool callback(void* data, const RESULT& result, bool status) + { + Response& resp = *static_cast(data); + pthread_mutex_lock(&resp.mutex); + resp.result = result; + resp.status = status; + resp.done = true; + pthread_cond_signal(&resp.cond); + pthread_mutex_unlock(&resp.mutex); + return true; + } +} response; + +STG_PAIR* toSTGPairs(const PAIRS& source) +{ + STG_PAIR * pairs = new STG_PAIR[source.size() + 1]; + for (size_t pos = 0; pos < source.size(); ++pos) { + bzero(pairs[pos].key, sizeof(STG_PAIR::key)); + bzero(pairs[pos].value, sizeof(STG_PAIR::value)); + strncpy(pairs[pos].key, source[pos].first.c_str(), sizeof(STG_PAIR::key)); + strncpy(pairs[pos].value, source[pos].second.c_str(), sizeof(STG_PAIR::value)); + } + bzero(pairs[source.size()].key, sizeof(STG_PAIR::key)); + bzero(pairs[source.size()].value, sizeof(STG_PAIR::value)); + + return pairs; +} + +PAIRS fromSTGPairs(const STG_PAIR* pairs) +{ + const STG_PAIR* pair = pairs; + PAIRS res; + + while (!emptyPair(pair)) { + res.push_back(std::pair(pair->key, pair->value)); + ++pair; + } + + return res; +} + +STG_RESULT toResult(const RESULT& source) +{ + STG_RESULT result; + result.modify = toSTGPairs(source.modify); + result.reply = toSTGPairs(source.reply); + return result; +} + +STG_RESULT emptyResult() +{ + STG_RESULT result = {NULL, NULL}; + return result; +} + +std::string toString(const char* value) +{ + if (value == NULL) + return ""; + else + return value; +} + +STG_RESULT stgRequest(STG_CLIENT::TYPE type, const char* userName, const char* password, const STG_PAIR* pairs) +{ + STG_CLIENT* client = STG_CLIENT::get(); + if (client == NULL) { + RadLog("Client is not configured."); + return emptyResult(); + } + try { + if (!client->connected()) + { + if (!STG_CLIENT::reconnect()) + return emptyResult(); + client = STG_CLIENT::get(); + } + response.done = false; + client->request(type, toString(userName), toString(password), fromSTGPairs(pairs)); + pthread_mutex_lock(&response.mutex); + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += 5; + int res = 0; + while (!response.done && res == 0) + res = pthread_cond_timedwait(&response.cond, &response.mutex, &ts); + pthread_mutex_unlock(&response.mutex); + if (res != 0 || !response.status) + return emptyResult(); + return toResult(response.result); + } catch (const STG_CLIENT::Error& ex) { + RadLog("Error: '%s'.", ex.what()); + return emptyResult(); + } +} + } -const STG_PAIR * stgAuthorizeImpl(const char * userName, const char * serviceType) +int stgInstantiateImpl(const char* address) { - return STG_CLIENT_ST::Get().Authorize(userName, serviceType); + pthread_mutex_init(&response.mutex, NULL); + pthread_cond_init(&response.cond, NULL); + response.done = false; + + if (STG_CLIENT::configure(toString(address), &Response::callback, &response)) + return 1; + + return 0; } -const STG_PAIR * stgAuthenticateImpl(const char * userName, const char * serviceType) +STG_RESULT stgAuthorizeImpl(const char* userName, const char* password, const STG_PAIR* pairs) { - return STG_CLIENT_ST::Get().Authenticate(userName, serviceType); + return stgRequest(STG_CLIENT::AUTHORIZE, userName, password, pairs); } -const STG_PAIR * stgPostAuthImpl(const char * userName, const char * serviceType) +STG_RESULT stgAuthenticateImpl(const char* userName, const char* password, const STG_PAIR* pairs) { - return STG_CLIENT_ST::Get().PostAuth(userName, serviceType); + return stgRequest(STG_CLIENT::AUTHENTICATE, userName, password, pairs); } -const STG_PAIR * stgPreAcctImpl(const char * userName, const char * serviceType) +STG_RESULT stgPostAuthImpl(const char* userName, const char* password, const STG_PAIR* pairs) { - return STG_CLIENT_ST::Get().PreAcct(userName, serviceType); + return stgRequest(STG_CLIENT::POST_AUTH, userName, password, pairs); } -const STG_PAIR * stgAccountingImpl(const char * userName, const char * serviceType, const char * statusType, const char * sessionId) +STG_RESULT stgPreAcctImpl(const char* userName, const char* password, const STG_PAIR* pairs) { - return STG_CLIENT_ST::Get().Account(userName, serviceType, statusType, sessionId); + return stgRequest(STG_CLIENT::PRE_ACCT, userName, password, pairs); } -void deletePairs(const STG_PAIR * pairs) +STG_RESULT stgAccountingImpl(const char* userName, const char* password, const STG_PAIR* pairs) { - delete[] pairs; + return stgRequest(STG_CLIENT::ACCOUNT, userName, password, pairs); }