]> git.stg.codes - stg.git/blobdiff - projects/rlm_stg/iface.cpp
Clear completion flag before making request.
[stg.git] / projects / rlm_stg / iface.cpp
index 40a96f729490f75b0bdaaa9c1ddf748e78ab57c6..0cb30b932090e7a0721e17212009455d81bdd539 100644 (file)
@@ -1,11 +1,37 @@
 #include "iface.h"
 
 #include "stg_client.h"
 #include "iface.h"
 
 #include "stg_client.h"
+#include "radlog.h"
+
+#include <cstring>
+
+#include <strings.h>
 
 namespace
 {
 
 
 namespace
 {
 
-STG_PAIR* toPairs(const PAIRS& source)
+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<Response*>(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) {
 {
     STG_PAIR * pairs = new STG_PAIR[source.size() + 1];
     for (size_t pos = 0; pos < source.size(); ++pos) {
@@ -13,103 +39,106 @@ STG_PAIR* toPairs(const PAIRS& source)
         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[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));
-        ++pos;
     }
     }
-    bzero(pairs[sources.size()].key, sizeof(STG_PAIR::key));
-    bzero(pairs[sources.size()].value, sizeof(STG_PAIR::value));
+    bzero(pairs[source.size()].key, sizeof(STG_PAIR::key));
+    bzero(pairs[source.size()].value, sizeof(STG_PAIR::value));
 
     return pairs;
 }
 
 
     return pairs;
 }
 
+PAIRS fromSTGPairs(const STG_PAIR* pairs)
+{
+    const STG_PAIR* pair = pairs;
+    PAIRS res;
+
+    while (!emptyPair(pair)) {
+        res.push_back(std::pair<std::string, std::string>(pair->key, pair->value));
+        ++pair;
+    }
+
+    return res;
 }
 
 }
 
-int stgInstantiateImpl(const char* server, uint16_t port, const char* password)
+STG_RESULT toResult(const RESULT& source)
 {
 {
-    if (STG_CLIENT::configure(server, port, password))
-        return 1;
+    STG_RESULT result;
+    result.modify = toSTGPairs(source.modify);
+    result.reply = toSTGPairs(source.reply);
+    return result;
+}
 
 
-    return 0;
+STG_RESULT emptyResult()
+{
+    STG_RESULT result = {NULL, NULL};
+    return result;
 }
 
 }
 
-const STG_PAIR* stgAuthorizeImpl(const char* userName, const char* serviceType)
+std::string toString(const char* value)
 {
 {
-    STG_CLIENT* client = STG_CLIENT::get();
-    if (client == NULL) {
-        // TODO: log "Not configured"
-        return NULL;
-    }
-    return toPairs(client->authorize(userName, serviceType));
+    if (value == NULL)
+        return "";
+    else
+        return value;
 }
 
 }
 
-const STG_PAIR* stgAuthenticateImpl(const char* userName, const char* serviceType)
+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) {
 {
     STG_CLIENT* client = STG_CLIENT::get();
     if (client == NULL) {
-        // TODO: log "Not configured"
-        return NULL;
+        RadLog("Client is not configured.");
+        return emptyResult();
+    }
+    try {
+        response.done = false;
+        client->request(type, toString(userName), toString(password), fromSTGPairs(pairs));
+        pthread_mutex_lock(&response.mutex);
+        while (!response.done)
+            pthread_cond_wait(&response.cond, &response.mutex);
+        pthread_mutex_unlock(&response.mutex);
+        if (!response.status)
+            return emptyResult();
+        return toResult(response.result);
+    } catch (const STG_CLIENT::Error& ex) {
+        RadLog("Error: '%s'.", ex.what());
+        return emptyResult();
     }
     }
-    return toPairs(client->authenticate(userName, serviceType));
 }
 
 }
 
-const STG_PAIR* stgPostAuthImpl(const char* userName, const char* serviceType)
+}
+
+int stgInstantiateImpl(const char* address)
 {
 {
-    STG_CLIENT* client = STG_CLIENT::get();
-    if (client == NULL) {
-        // TODO: log "Not configured"
-        return NULL;
-    }
-    return toPairs(client->postAuth(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* stgPreAcctImpl(const char* userName, const char* serviceType)
+STG_RESULT stgAuthorizeImpl(const char* userName, const char* password, const STG_PAIR* pairs)
 {
 {
-    STG_CLIENT* client = STG_CLIENT::get();
-    if (client == NULL) {
-        // TODO: log "Not configured"
-        return NULL;
-    }
-    return toPairs(client->preAcct(userName, serviceType));
+    return stgRequest(STG_CLIENT::AUTHORIZE, userName, password, pairs);
 }
 
 }
 
-const STG_PAIR* stgAccountingImpl(const char* userName, const char* serviceType, const char* statusType, const char* sessionId)
+STG_RESULT stgAuthenticateImpl(const char* userName, const char* password, const STG_PAIR* pairs)
 {
 {
-    STG_CLIENT* client = STG_CLIENT::get();
-    if (client == NULL) {
-        // TODO: log "Not configured"
-        return NULL;
-    }
-    return toPairs(client->account(userName, serviceType, statusType, sessionId));
+    return stgRequest(STG_CLIENT::AUTHENTICATE, userName, password, pairs);
 }
 
 }
 
-int countValuePairs(const VALUE_PAIR* pairs)
+STG_RESULT stgPostAuthImpl(const char* userName, const char* password, const STG_PAIR* pairs)
 {
 {
-    unsigned count = 0;
-    while (pairs != NULL) {
-        ++count;
-        pairs = pairs->next;
-    }
-    return count;
+    return stgRequest(STG_CLIENT::POST_AUTH, userName, password, pairs);
 }
 
 }
 
-STG_PAIR* fromValuePairs(const VALUE_PAIR* pairs)
+STG_RESULT stgPreAcctImpl(const char* userName, const char* password, const STG_PAIR* pairs)
 {
 {
-    unsigned size = countValuePairs(pairs);
-    STG_PAIR* res = new STG_PAIR[size + 1];
-    size_t pos = 0;
-    while (pairs != NULL) {
-        bzero(res[pos].key, sizeof(STG_PAIR::key));
-        bzero(res[pos].value, sizeof(STG_PAIR::value));
-        strncpy(res[pos].key, pairs->name, sizeof(STG_PAIR::key));
-        strncpy(res[pos].value, pairs->data.strvalue, sizeof(STG_PAIR::value));
-        ++pos;
-        pairs = pairs->next;
-    }
-    bzero(res[pos].key, sizeof(STG_PAIR::key));
-    bzero(res[pos].value, sizeof(STG_PAIR::value));
-    return res;
+    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);
 }
 }