summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/agent-at.c58
-rw-r--r--src/data.h21
2 files changed, 65 insertions, 14 deletions
diff --git a/src/agent-at.c b/src/agent-at.c
index 02bcc6c..6a33bf6 100644
--- a/src/agent-at.c
+++ b/src/agent-at.c
@@ -24,6 +24,16 @@
#include "data.h"
#include "cyn.h"
+/**
+ * Parse the spec to extract the derived key to ask.
+ *
+ * @param spec The specification of the derived key
+ * @param rkey The originally requested key
+ * @param key The derived key or NULL for computing length
+ * @param buffer The buffer that handles texts or NULL for computing length
+ * @param szbuf The size of the buffer or 0 for computing length
+ * @return the total length of buffer used
+ */
static
size_t
parse(
@@ -37,14 +47,22 @@ parse(
const char *val;
iout = 0;
- for (ikey = 0 ; ikey < 4 ; ikey++) {
+ for (ikey = 0 ; ikey < KeyIdx_Count ; ikey++) {
inf = iout;
while(*spec) {
if (*spec == ':' && ikey < 3) {
+ /* : is the separator of key's items */
spec++;
- break;
+ break; /* next key */
}
- if (*spec == '%' && spec[1]) {
+ if (!(*spec == '%' && spec[1])) {
+ /* not a % substitution mark */
+ if (iout < szbuf)
+ buffer[iout] = *spec;
+ iout++;
+ spec++;
+ } else {
+ /* what % substitution is it? */
switch(spec[1]) {
case 'c':
val = rkey->client;
@@ -59,9 +77,11 @@ parse(
val = rkey->permission;
break;
default:
+ /* none */
val = 0;
}
if (val) {
+ /* substitution of the value */
while (*val) {
if (iout < szbuf)
buffer[iout] = *val;
@@ -69,7 +89,9 @@ parse(
val++;
}
} else {
+ /* no substitution */
if (spec[1] != ':' && spec[1] != '%') {
+ /* only escape % and : */
if (iout < szbuf)
buffer[iout] = '%';
iout++;
@@ -79,27 +101,34 @@ parse(
iout++;
}
spec += 2;
- } else {
- if (iout < szbuf)
- buffer[iout] = *spec;
- iout++;
- spec++;
}
}
if (inf == iout)
- val = 0;
+ val = 0; /* empty key item */
else {
+ /* set zero ended key */
val = &buffer[inf];
if (iout < szbuf)
buffer[iout] = 0;
iout++;
}
if (key)
- ((const char**)key)[ikey] = val;
+ key->keys[ikey] = val;
}
return iout;
}
+/**
+ * Implementation of the AT-agent callback
+ *
+ * @param name name of the agent (not used, should be "@")
+ * @param agent_closure closure of the agent (not used)
+ * @param key the original searched key
+ * @param value the value found (string after @:)
+ * @param on_result_cb callback that will asynchronously handle the result
+ * @param on_result_closure closure for 'on_result_cb'
+ * @return
+ */
static
int
agent_at_cb(
@@ -114,12 +143,21 @@ agent_at_cb(
char *block;
size_t size;
+ /* compute the length */
size = parse(value, key, 0, 0, 0);
+ /* alloc the length locally */
block = alloca(size);
+ /* initialize the derived key */
parse(value, key, &atkey, block, size);
+ /* ask for the derived key */
return cyn_test_async(on_result_cb, on_result_closure, &atkey);
}
+/**
+ * Activate the AT-agent
+ *
+ * @return 0 in case of success of a negative value in -errno style.
+ */
int
agent_at_activate(
) {
diff --git a/src/data.h b/src/data.h
index 8bd35b3..ef387f8 100644
--- a/src/data.h
+++ b/src/data.h
@@ -31,11 +31,24 @@
typedef struct data_key data_key_t;
typedef struct data_value data_value_t;
+enum data_keyidx {
+ KeyIdx_Client,
+ KeyIdx_Session,
+ KeyIdx_User,
+ KeyIdx_Permission,
+ KeyIdx_Count
+};
+
struct data_key {
- const char *client;
- const char *session;
- const char *user;
- const char *permission;
+ union {
+ struct {
+ const char *client;
+ const char *session;
+ const char *user;
+ const char *permission;
+ };
+ const char *keys[KeyIdx_Count];
+ };
};
struct data_value {