summaryrefslogtreecommitdiffstats
path: root/src/rcyn-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rcyn-client.c')
-rw-r--r--src/rcyn-client.c72
1 files changed, 61 insertions, 11 deletions
diff --git a/src/rcyn-client.c b/src/rcyn-client.c
index f712ca6..e1f7841 100644
--- a/src/rcyn-client.c
+++ b/src/rcyn-client.c
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author José Bollo <jose.bollo@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
#define _GNU_SOURCE
#include <stdbool.h>
@@ -106,7 +123,7 @@ flushw(
if (rc == -EAGAIN) {
pfd.fd = rcyn->fd;
pfd.events = POLLOUT;
- do { rc = poll(&pfd, 1, 0); } while (rc < 0 && errno == EINTR);
+ do { rc = poll(&pfd, 1, -1); } while (rc < 0 && errno == EINTR);
if (rc < 0)
rc = -errno;
}
@@ -170,7 +187,7 @@ wait_input(
pfd.fd = rcyn->fd;
pfd.events = POLLIN;
- do { rc = poll(&pfd, 1, 0); } while (rc < 0 && errno == EINTR);
+ do { rc = poll(&pfd, 1, -1); } while (rc < 0 && errno == EINTR);
return rc < 0 ? -errno : 0;
}
@@ -284,7 +301,7 @@ async(
int op,
uint32_t events
) {
- return rcyn->async.controlcb
+ return rcyn->async.controlcb && rcyn->fd >= 0
? rcyn->async.controlcb(rcyn->async.closure, op, rcyn->fd, events)
: 0;
}
@@ -344,6 +361,13 @@ connection(
return rc;
}
+static
+int
+ensure_opened(
+ rcyn_t *rcyn
+) {
+ return rcyn->fd < 0 ? connection(rcyn) : 0;
+}
/************************************************************************************/
@@ -375,17 +399,12 @@ rcyn_open(
rcyn->async.closure = 0;
rcyn->async.requests = NULL;
- /* connection */
- rc = connection(rcyn);
- if (rc < 0)
- goto error3;
+ /* lazy connection */
+ rcyn->fd = -1;
/* done */
return 0;
-error3:
- free(rcyn->cache);
- prot_destroy(rcyn->prot);
error2:
free(rcyn);
error:
@@ -414,6 +433,9 @@ rcyn_enter(
return -EPERM;
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
rc = putx(rcyn, _enter_, NULL);
if (rc >= 0)
@@ -432,6 +454,9 @@ rcyn_leave(
return -EPERM;
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
rc = putx(rcyn, _leave_, commit ? _commit_ : NULL/*default: rollback*/, NULL);
if (rc >= 0)
@@ -453,6 +478,9 @@ check_or_test(
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
/* ensure there is no clear cache pending */
flushr(rcyn);
@@ -514,6 +542,9 @@ rcyn_set(
return -EPERM;
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
snprintf(val, sizeof val, "%u", (unsigned)value);
rc = putx(rcyn, _set_, client, session, user, permission, val, NULL);
@@ -545,6 +576,9 @@ rcyn_get(
return -EPERM;
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
rc = putx(rcyn, _get_, client, session, user, permission, NULL);
if (rc >= 0) {
@@ -577,6 +611,9 @@ rcyn_drop(
return -EPERM;
if (rcyn->async.requests != NULL)
return -EINPROGRESS;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
rc = putx(rcyn, _drop_, client, session, user, permission, NULL);
if (rc >= 0)
@@ -645,6 +682,7 @@ rcyn_async_process(
int rc;
const char *first;
asreq_t *ar;
+ const char *client, *session, *user, *permission;
for (;;) {
/* non blocking wait for a reply */
@@ -670,6 +708,13 @@ rcyn_async_process(
/* emit the asynchronous answer */
rcyn->async.requests = ar->next;
rc = status_check(rcyn);
+ if (rc >= 0) {
+ client = (const char*)(ar + 1);
+ session = &client[1 + strlen(client)];
+ user = &session[1 + strlen(session)];
+ permission = &user[1 + strlen(user)];
+ cache_put(rcyn->cache, client, session, user, permission, rc);
+ }
ar->callback(ar->closure, rc);
free(ar);
}
@@ -691,8 +736,12 @@ rcyn_async_check(
int rc;
asreq_t **pr, *ar;
+ rc = ensure_opened(rcyn);
+ if (rc < 0)
+ return rc;
+
/* allocate */
- ar = malloc(sizeof *ar);
+ ar = malloc(sizeof *ar + strlen(client) + strlen(session) + strlen(user) + strlen(permission) + 4);
if (ar == NULL)
return -ENOMEM;
@@ -700,6 +749,7 @@ rcyn_async_check(
ar->next = NULL;
ar->callback = callback;
ar->closure = closure;
+ stpcpy(1 + stpcpy(1 + stpcpy(1 + stpcpy((char*)(ar + 1), client), session), user), permission);
/* send the request */
rc = putx(rcyn, simple ? _test_ : _check_,