Add documentation and fixes
authorJose Bollo <jose.bollo@iot.bzh>
Mon, 7 Oct 2019 15:16:22 +0000 (17:16 +0200)
committerJose Bollo <jose.bollo@iot.bzh>
Mon, 7 Oct 2019 15:17:14 +0000 (17:17 +0200)
Documents the client API

Fixes few bugs

Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
compat/src/lib-compat.c
src/cyn-server.c
src/cyn-server.h
src/cynagora.c
src/cynagora.h
src/main-cynagoradm.c

index 8035292..a7c1532 100644 (file)
@@ -151,12 +151,12 @@ struct cynara_admin;
 
 int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin)
 {
-       return from_status(cynagora_open((cynagora_t**)pp_cynara_admin, cynagora_Admin, 1, 0));
+       return from_status(cynagora_create((cynagora_t**)pp_cynara_admin, cynagora_Admin, 1, 0));
 }
 
 int cynara_admin_finish(struct cynara_admin *p_cynara_admin)
 {
-       cynagora_close((cynagora_t*)p_cynara_admin);
+       cynagora_destroy((cynagora_t*)p_cynara_admin);
        return CYNARA_API_SUCCESS;
 }
 
@@ -413,7 +413,7 @@ int cynara_async_initialize(cynara_async **pp_cynara, const cynara_async_configu
        if (p_cynara == NULL)
                ret = CYNARA_API_OUT_OF_MEMORY;
        else {
-               ret = from_status(cynagora_open(&p_cynara->rcyn, cynagora_Check, p_conf ? p_conf->szcache : 1, 0));
+               ret = from_status(cynagora_create(&p_cynara->rcyn, cynagora_Check, p_conf ? p_conf->szcache : 1, 0));
                if (ret != CYNARA_API_SUCCESS)
                        free(p_cynara);
                else {
@@ -439,7 +439,7 @@ void cynara_async_finish(cynara_async *p_cynara)
                }
        }
 
-       cynagora_close(p_cynara->rcyn);
+       cynagora_destroy(p_cynara->rcyn);
 
        while((req = p_cynara->reqs)) {
                p_cynara->reqs = req->next;
@@ -569,12 +569,12 @@ int cynara_configuration_set_cache_size(cynara_configuration *p_conf,
 
 int cynara_initialize(cynara **pp_cynara, const cynara_configuration *p_conf)
 {
-       return from_status(cynagora_open((cynagora_t**)pp_cynara, cynagora_Check, p_conf ? p_conf->szcache : 1, 0));
+       return from_status(cynagora_create((cynagora_t**)pp_cynara, cynagora_Check, p_conf ? p_conf->szcache : 1, 0));
 }
 
 int cynara_finish(cynara *p_cynara)
 {
-       cynagora_close((cynagora_t*)p_cynara);
+       cynagora_destroy((cynagora_t*)p_cynara);
        return CYNARA_API_SUCCESS;
 }
 
index 1921142..d751fda 100644 (file)
@@ -108,6 +108,13 @@ struct cyn_server
        pollitem_t check;
 };
 
+/**
+ * Log the protocol
+ * @param cli the client handle
+ * @param c2s direction: if not 0: client to server, if 0: server to client
+ * @param count count of fields
+ * @param fields the fields
+ */
 static
 void
 dolog(
@@ -365,12 +372,16 @@ onrequest(
 
        /* version hand-shake */
        if (!cli->version) {
-               if (!ckarg(args[0], _cynagora_, 0) || count != 2 || !ckarg(args[1], "1", 0))
-                       goto invalid;
-               putx(cli, _yes_, "1", cyn_changeid_string(), NULL);
-               flushw(cli);
+               if (ckarg(args[0], _cynagora_, 0)) {
+                       if (count < 2 || !ckarg(args[1], "1", 0))
+                               goto invalid;
+                       putx(cli, _yes_, "1", cyn_changeid_string(), NULL);
+                       flushw(cli);
+                       cli->version = 1;
+                       return;
+               }
+               /* switch automatically to version 1 */
                cli->version = 1;
-               return;
        }
 
        switch(args[0][0]) {
@@ -703,7 +714,7 @@ on_agent_server_event(
        on_server_event(pollitem, events, pollfd, server_Agent);
 }
 
-/** destroy a server */
+/* see cyn-server.h */
 void
 cyn_server_destroy(
        cyn_server_t *server
@@ -719,7 +730,7 @@ cyn_server_destroy(
        }
 }
 
-/** create a server */
+/* see cyn-server.h */
 int
 cyn_server_create(
        cyn_server_t **server,
@@ -821,7 +832,7 @@ error:
        return rc;
 }
 
-/** stop the server */
+/* see cyn-server.h */
 void
 cyn_server_stop(
        cyn_server_t *server,
@@ -830,7 +841,7 @@ cyn_server_stop(
        server->stopped = status ?: INT_MIN;
 }
 
-/** create a server */
+/* see cyn-server.h */
 int
 cyn_server_serve(
        cyn_server_t *server
@@ -842,4 +853,3 @@ cyn_server_serve(
        }
        return server->stopped == INT_MIN ? 0 : server->stopped;
 }
-
index 8117724..d2c7984 100644 (file)
 
 typedef struct cyn_server cyn_server_t;
 
+/**
+ * Boolean flag telling whether the server logs or not its received commands
+ */
 extern
 bool
 cyn_server_log;
 
-extern
-void
-cyn_server_destroy(
-       cyn_server_t *server
-);
-
+/**
+ * Create a cynagora server
+ * 
+ * @param server where to store the handler of the created server
+ * @param admin_socket_spec specification of the admin socket
+ * @param check_socket_spec specification of the check socket
+ * @param agent_socket_spec specification of the agent socket
+ * 
+ * @return 0 on success or a negative -errno value
+ * 
+ * @see cyn_server_destroy
+ */
 extern
 int
 cyn_server_create(
@@ -42,12 +51,42 @@ cyn_server_create(
        const char *agent_socket_spec
 );
 
+/**
+ * Destroy a created server and release its resources
+ * 
+ * @param server the handler of the server
+ * 
+ * @see cyn_server_create
+ */
+extern
+void
+cyn_server_destroy(
+       cyn_server_t *server
+);
+
+/**
+ * Start the cynagora server and returns only when stopped
+ * 
+ * @param server the handler of the server
+ * 
+ * @return 0 on success or a negative -errno value
+ * 
+ * @see cyn_server_stop
+ */
 extern
 int
 cyn_server_serve(
        cyn_server_t *server
 );
 
+/**
+ * Stop the cynagora server
+ * 
+ * @param server the handler of the server
+ * @param status the status that the function cyn_server_serve should return
+ * 
+ * @see cyn_server_serve
+ */
 extern
 void
 cyn_server_stop(
index 1165e64..ee55dc6 100644 (file)
@@ -52,9 +52,7 @@ struct asreq
        struct asreq *next;
 
        /** callback function */
-       void (*callback)(
-               void *closure,
-               int status);
+       cynagora_async_check_cb_t *callback;
 
        /** closure of the callback */
        void *closure;
@@ -75,9 +73,6 @@ struct cynagora
        /** type of link */
        cynagora_type_t type;
 
-       /** spec of the socket */
-       const char *socketspec;
-
        /** protocol manager object */
        prot_t *prot;
 
@@ -96,7 +91,7 @@ struct cynagora
        /** async */
        struct {
                /** control callback */
-               cynagora_async_ctl_controlcb;
+               cynagora_async_ctl_cb_t *controlcb;
 
                /** closure */
                void *closure;
@@ -104,12 +99,17 @@ struct cynagora
                /** requests */
                asreq_t *requests;
        } async;
-};
 
-static void disconnection(cynagora_t *cynagora);
+       /** spec of the socket */
+       char socketspec[];
+};
 
 /**
- * Flush the write buffer
+ * Flush the write buffer of the client
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
  */
 static
 int
@@ -141,7 +141,14 @@ flushw(
 /**
  * Put the command made of arguments ...
  * Increment the count of pending requests.
- * Return 0 in case of success or a negative number on error.
+ *
+ * @param cynagora  the handler of the client
+ * @param command   the command to send
+ * @param optarg    an optional argument or NULL
+ * @param optkey    an optional key or NULL
+ * @param optval    an optional value or NULL
+ *
+ * @return  0 in case of success or a negative -errno value
  */
 static
 int
@@ -156,8 +163,10 @@ putxkv(
        prot_t *prot;
        char text[30];
 
+       /* retrieves the protocol handler */
        prot = cynagora->prot;
        for(trial = 0 ; ; trial++) {
+               /* fill the protocol handler with command and its arguments */
                rc = prot_put_field(prot, command);
                if (!rc && optarg)
                        rc = prot_put_field(prot, optarg);
@@ -183,19 +192,33 @@ putxkv(
                if (!rc)
                        rc = prot_put_end(prot);
                if (!rc) {
+                       /* success ! */
                        /* client always flushes */
                        cynagora->pending++;
                        return flushw(cynagora);
                }
+
+               /* failed to fill protocol, cancel current composition  */
                prot_put_cancel(prot);
+
+               /* fail if was last trial */
                if (trial >= 1)
                        return rc;
+
+               /* try to flush the output buffer */
                rc = flushw(cynagora);
                if (rc)
                        return rc;
        }
 }
 
+/**
+ * Wait some input event
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 wait_input(
@@ -210,19 +233,28 @@ wait_input(
        return rc < 0 ? -errno : 0;
 }
 
+/**
+ * Get the next reply if any
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  the count of field of the reply (can be 0)
+ *          or -EAGAIN if there is no reply
+ */
 static
 int
 get_reply(
        cynagora_t *cynagora
 ) {
        int rc;
+       uint32_t cacheid;
 
        prot_next(cynagora->prot);
        rc = prot_get(cynagora->prot, &cynagora->reply.fields);
        if (rc > 0) {
                if (0 == strcmp(cynagora->reply.fields[0], _clear_)) {
-                       cache_clear(cynagora->cache,
-                               rc > 1 ? (uint32_t)atol(cynagora->reply.fields[1]) : 0);
+                       cacheid = rc > 1 ? (uint32_t)atol(cynagora->reply.fields[1]) : 0;
+                       cache_clear(cynagora->cache, cacheid);
                        rc = 0;
                } else {
                        if (0 != strcmp(cynagora->reply.fields[0], _item_))
@@ -233,6 +265,16 @@ get_reply(
        return rc;
 }
 
+/**
+ * Wait for a reply
+ *
+ * @param cynagora  the handler of the client
+ * @param block
+ *
+ * @return  the count of fields greater than 0 or a negative -errno value
+ *          or -EAGAIN if nothing and block == 0
+ *          or -EPIPE if broken link
+ */
 static
 int
 wait_reply(
@@ -242,11 +284,13 @@ wait_reply(
        int rc;
 
        for(;;) {
-               prot_next(cynagora->prot);
+               /* get the next reply if any */
                rc = get_reply(cynagora);
                if (rc > 0)
                        return rc;
+
                if (rc < 0) {
+                       /* wait for an answer */
                        rc = prot_read(cynagora->prot, cynagora->fd);
                        while (rc <= 0) {
                                if (rc == 0)
@@ -261,6 +305,13 @@ wait_reply(
        }
 }
 
+/**
+ * Read and process any input data
+ *
+ * @param cynagora the client handler
+ *
+ * @return 0 on success or a negative -errno error code
+ */
 static
 int
 flushr(
@@ -272,6 +323,13 @@ flushr(
        return rc;
 }
 
+/**
+ * Test if the first field is "done"
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 if done or -ECANCELED otherwise
+ */
 static
 int
 status_done(
@@ -280,6 +338,14 @@ status_done(
        return strcmp(cynagora->reply.fields[0], _done_) ? -ECANCELED : 0;
 }
 
+/**
+ * Translates the check/test reply to a forbiden/granted status
+ *
+ * @param cynagora  the handler of the client
+ * @param expire    where to store the expiration read
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 status_check(
@@ -305,6 +371,13 @@ status_check(
        return rc;
 }
 
+/**
+ * Wait for a reply
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 wait_pending_reply(
@@ -320,6 +393,14 @@ wait_pending_reply(
        }
 }
 
+/**
+ * Wait the reply "done"
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
+ *          -ECANCELED when received an error status
+ */
 static
 int
 wait_done(
@@ -331,6 +412,15 @@ wait_done(
        return rc;
 }
 
+/**
+ * Calls the asynchronous control callback with operation and the given events
+ *
+ * @param cynagora  the handler of the client
+ * @param op operation (see epoll_ctl)
+ * @param events the events (see epoll_ctl)
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 async(
@@ -343,6 +433,11 @@ async(
                : 0;
 }
 
+/**
+ * Disconnect the client
+ *
+ * @param cynagora  the handler of the client
+ */
 static
 void
 disconnection(
@@ -355,6 +450,13 @@ disconnection(
        }
 }
 
+/**
+ * connect the client
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 connection(
@@ -391,6 +493,13 @@ connection(
        return rc;
 }
 
+/**
+ * ensure the connection is opened
+ *
+ * @param cynagora  the handler of the client
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
 static
 int
 ensure_opened(
@@ -401,10 +510,63 @@ ensure_opened(
        return cynagora->fd < 0 ? connection(cynagora) : 0;
 }
 
-/************************************************************************************/
+/**
+ * Check or test synchronously
+ *
+ * @param cynagora
+ * @param key
+ * @param action
+ *
+ * @return  0 in case of success or a negative -errno value
+ */
+static
+int
+check_or_test(
+       cynagora_t *cynagora,
+       const cynagora_key_t *key,
+       const char *action
+) {
+       int rc;
+       time_t expire;
+
+       /* forbids 2 queries interleaved */
+       if (cynagora->async.requests != NULL)
+               return -EINPROGRESS;
+
+       /* ensure opened */
+       rc = ensure_opened(cynagora);
+       if (rc < 0)
+               return rc;
+
+       /* ensure there is no clear cache pending */
+       flushr(cynagora);
+
+       /* check cache item */
+       rc = cache_search(cynagora->cache, key);
+       if (rc >= 0)
+               return rc;
+
+       /* send the request */
+       rc = putxkv(cynagora, action, 0, key, 0);
+       if (rc >= 0) {
+               /* get the response */
+               rc = wait_pending_reply(cynagora);
+               if (rc >= 0) {
+                       rc = status_check(cynagora, &expire);
+                       if (rc >= 0 && action == _check_ && cynagora->cache)
+                               cache_put(cynagora->cache, key, rc, expire);
+               }
+       }
+       return rc;
+}
+
+/******************************************************************************/
+/*** PUBLIC METHODS                                                         ***/
+/******************************************************************************/
 
+/* see cynagora.h */
 int
-cynagora_open(
+cynagora_create(
        cynagora_t **prcyn,
        cynagora_type_t type,
        uint32_t cache_size,
@@ -415,10 +577,18 @@ cynagora_open(
 
        /* socket spec */
        switch(type) {
+       case cynagora_Admin:
+               socketspec = cyn_get_socket_admin(socketspec);
+               break;
+
+       case cynagora_Agent:
+               socketspec = cyn_get_socket_agent(socketspec);
+               break;
+
+       case cynagora_Check:
        default:
-       case cynagora_Check: socketspec = cyn_get_socket_check(socketspec); break;
-       case cynagora_Admin: socketspec = cyn_get_socket_admin(socketspec); break;
-       case cynagora_Agent: socketspec = cyn_get_socket_agent(socketspec); break;
+               socketspec = cyn_get_socket_check(socketspec);
+               break;
        }
 
        /* allocate the structure */
@@ -434,12 +604,11 @@ cynagora_open(
                goto error2;
 
        /* socket spec */
-       strcpy((char*)(cynagora+1), socketspec);
+       strcpy(cynagora->socketspec, socketspec);
 
        /* record type and weakly create cache */
-       cache_create(&cynagora->cache, CACHESIZE(cache_size));
+       cache_create(&cynagora->cache, CACHESIZE(cache_size)); /* ignore errors */
        cynagora->type = type;
-       cynagora->socketspec = socketspec;
        cynagora->async.controlcb = NULL;
        cynagora->async.closure = 0;
        cynagora->async.requests = NULL;
@@ -457,6 +626,7 @@ error:
        return rc;
 }
 
+/* see cynagora.h */
 void
 cynagora_disconnect(
        cynagora_t *cynagora
@@ -464,8 +634,9 @@ cynagora_disconnect(
        disconnection(cynagora);
 }
 
+/* see cynagora.h */
 void
-cynagora_close(
+cynagora_destroy(
        cynagora_t *cynagora
 ) {
        cynagora_async_setup(cynagora, NULL, NULL);
@@ -475,85 +646,33 @@ cynagora_close(
        free(cynagora);
 }
 
+/* see cynagora.h */
 int
-cynagora_enter(
-       cynagora_t *cynagora
+cynagora_cache_resize(
+       cynagora_t *cynagora,
+       uint32_t size
 ) {
-       int rc;
-
-       if (cynagora->type != cynagora_Admin)
-               return -EPERM;
-       if (cynagora->async.requests != NULL)
-               return -EINPROGRESS;
-       rc = ensure_opened(cynagora);
-       if (rc < 0)
-               return rc;
-
-       rc = putxkv(cynagora, _enter_, 0, 0, 0);
-       if (rc >= 0)
-               rc = wait_done(cynagora);
-       return rc;
+       return cache_resize(&cynagora->cache, CACHESIZE(size));
 }
 
-int
-cynagora_leave(
-       cynagora_t *cynagora,
-       bool commit
+/* see cynagora.h */
+void
+cynagora_cache_clear(
+       cynagora_t *cynagora
 ) {
-       int rc;
-
-       if (cynagora->type != cynagora_Admin)
-               return -EPERM;
-       if (cynagora->async.requests != NULL)
-               return -EINPROGRESS;
-       rc = ensure_opened(cynagora);
-       if (rc < 0)
-               return rc;
-
-       rc = putxkv(cynagora, _leave_, commit ? _commit_ : 0/*default: rollback*/, 0, 0);
-       if (rc >= 0)
-               rc = wait_done(cynagora);
-       return rc;
+       cache_clear(cynagora->cache, 0);
 }
 
-static
+/* see cynagora.h */
 int
-check_or_test(
+cynagora_cache_check(
        cynagora_t *cynagora,
-       const cynagora_key_t *key,
-       const char *action
+       const cynagora_key_t *key
 ) {
-       int rc;
-       time_t expire;
-
-       if (cynagora->async.requests != NULL)
-               return -EINPROGRESS;
-       rc = ensure_opened(cynagora);
-       if (rc < 0)
-               return rc;
-
-       /* ensure there is no clear cache pending */
-       flushr(cynagora);
-
-       /* check cache item */
-       rc = cache_search(cynagora->cache, key);
-       if (rc >= 0)
-               return rc;
-
-       /* send the request */
-       rc = putxkv(cynagora, action, 0, key, 0);
-       if (rc >= 0) {
-               /* get the response */
-               rc = wait_pending_reply(cynagora);
-               if (rc >= 0) {
-                       rc = status_check(cynagora, &expire);
-                       if (cynagora->cache && rc >= 0)
-                               cache_put(cynagora->cache, key, rc, expire);
-               }
-       }
-       return rc;
+       return cache_search(cynagora->cache, key);
 }
 
+/* see cynagora.h */
 int
 cynagora_check(
        cynagora_t *cynagora,
@@ -562,6 +681,7 @@ cynagora_check(
        return check_or_test(cynagora, key, _check_);
 }
 
+/* see cynagora.h */
 int
 cynagora_test(
        cynagora_t *cynagora,
@@ -570,37 +690,12 @@ cynagora_test(
        return check_or_test(cynagora, key, _test_);
 }
 
-int
-cynagora_set(
-       cynagora_t *cynagora,
-       const cynagora_key_t *key,
-       const cynagora_value_t *value
-) {
-       int rc;
-
-       if (cynagora->type != cynagora_Admin)
-               return -EPERM;
-       if (cynagora->async.requests != NULL)
-               return -EINPROGRESS;
-       rc = ensure_opened(cynagora);
-       if (rc < 0)
-               return rc;
-
-       rc = putxkv(cynagora, _set_, 0, key, value);
-       if (rc >= 0)
-               rc = wait_done(cynagora);
-       return rc;
-}
-
+/* see cynagora.h */
 int
 cynagora_get(
        cynagora_t *cynagora,
        const cynagora_key_t *key,
-       void (*callback)(
-               void *closure,
-               const cynagora_key_t *key,
-               const cynagora_value_t *value
-       ),
+       cynagora_get_cb_t *callback,
        void *closure
 ) {
        int rc;
@@ -633,6 +728,7 @@ cynagora_get(
        return rc;
 }
 
+/* see cynagora.h */
 int
 cynagora_log(
        cynagora_t *cynagora,
@@ -657,11 +753,10 @@ cynagora_log(
        return rc < 0 ? rc : cynagora->reply.count < 2 ? 0 : !strcmp(cynagora->reply.fields[1], _on_);
 }
 
-
+/* see cynagora.h */
 int
-cynagora_drop(
-       cynagora_t *cynagora,
-       const cynagora_key_t *key
+cynagora_enter(
+       cynagora_t *cynagora
 ) {
        int rc;
 
@@ -673,44 +768,84 @@ cynagora_drop(
        if (rc < 0)
                return rc;
 
-       rc = putxkv(cynagora, _drop_, 0, key, 0);
+       rc = putxkv(cynagora, _enter_, 0, 0, 0);
        if (rc >= 0)
                rc = wait_done(cynagora);
        return rc;
 }
 
-/************************************************************************************/
-
+/* see cynagora.h */
 int
-cynagora_cache_resize(
+cynagora_leave(
        cynagora_t *cynagora,
-       uint32_t size
+       int commit
 ) {
-       return cache_resize(&cynagora->cache, CACHESIZE(size));
+       int rc;
+
+       if (cynagora->type != cynagora_Admin)
+               return -EPERM;
+       if (cynagora->async.requests != NULL)
+               return -ECANCELED;
+       rc = ensure_opened(cynagora);
+       if (rc < 0)
+               return rc;
+
+       rc = putxkv(cynagora, _leave_, commit ? _commit_ : 0/*default: rollback*/, 0, 0);
+       if (rc >= 0)
+               rc = wait_done(cynagora);
+       return rc;
 }
 
-void
-cynagora_cache_clear(
-       cynagora_t *cynagora
+/* see cynagora.h */
+int
+cynagora_set(
+       cynagora_t *cynagora,
+       const cynagora_key_t *key,
+       const cynagora_value_t *value
 ) {
-       cache_clear(cynagora->cache, 0);
+       int rc;
+
+       if (cynagora->type != cynagora_Admin)
+               return -EPERM;
+       if (cynagora->async.requests != NULL)
+               return -ECANCELED;
+       rc = ensure_opened(cynagora);
+       if (rc < 0)
+               return rc;
+
+       rc = putxkv(cynagora, _set_, 0, key, value);
+       if (rc >= 0)
+               rc = wait_done(cynagora);
+       return rc;
 }
 
+/* see cynagora.h */
 int
-cynagora_cache_check(
+cynagora_drop(
        cynagora_t *cynagora,
        const cynagora_key_t *key
 ) {
-       return cache_search(cynagora->cache, key);
-}
+       int rc;
 
+       if (cynagora->type != cynagora_Admin)
+               return -EPERM;
+       if (cynagora->async.requests != NULL)
+               return -ECANCELED;
+       rc = ensure_opened(cynagora);
+       if (rc < 0)
+               return rc;
 
-/************************************************************************************/
+       rc = putxkv(cynagora, _drop_, 0, key, 0);
+       if (rc >= 0)
+               rc = wait_done(cynagora);
+       return rc;
+}
 
+/* see cynagora.h */
 int
 cynagora_async_setup(
        cynagora_t *cynagora,
-       cynagora_async_ctl_controlcb,
+       cynagora_async_ctl_cb_t *controlcb,
        void *closure
 ) {
        asreq_t *ar;
@@ -721,15 +856,19 @@ cynagora_async_setup(
                ar->callback(ar->closure, -ECANCELED);
                free(ar);
        }
+
        /* remove existing polling */
        async(cynagora, EPOLL_CTL_DEL, 0);
+
        /* records new data */
        cynagora->async.controlcb = controlcb;
        cynagora->async.closure = closure;
+
        /* record to polling */
        return async(cynagora, EPOLL_CTL_ADD, EPOLLIN);
 }
 
+/* see cynagora.h */
 int
 cynagora_async_process(
        cynagora_t *cynagora
@@ -776,14 +915,13 @@ cynagora_async_process(
        }
 }
 
+/* see cynagora.h */
 int
 cynagora_async_check(
        cynagora_t *cynagora,
        const cynagora_key_t *key,
        int simple,
-       void (*callback)(
-               void *closure,
-               int status),
+       cynagora_async_check_cb_t *callback,
        void *closure
 ) {
        int rc;
index 3b856da..d17476c 100644 (file)
@@ -26,93 +26,240 @@ typedef enum cynagora_type cynagora_type_t;
 typedef struct cynagora_key cynagora_key_t;
 typedef struct cynagora_value cynagora_value_t;
 
+/**
+ * type of the client interface
+ */
 enum cynagora_type {
+       /** type for checking permissions */
        cynagora_Check,
+       /** type for adminstration */
        cynagora_Admin,
+       /** type for handling agents */
        cynagora_Agent
 };
 
+/**
+ * Describes a query key
+ */
 struct cynagora_key {
+       /** client item of the key */
        const char *client;
+       /** session item of the key */
        const char *session;
+       /** user item of the key */
        const char *user;
+       /** permission item of the key */
        const char *permission;
 };
 
+/**
+ * Describes the value associated to a key
+ */
 struct cynagora_value {
+       /** the associated value */
        const char *value;
+       /** the expiration */
        time_t expire;
 };
 
+/**
+ * Callback for enumeration of items (admin)
+ * The function is called for each entry matching the selection key 
+ * with the key and the associated value for that entry
+ * 
+ * @see cynagora_get
+ */
+typedef void cynagora_get_cb_t(
+                       void *closure,
+                       const cynagora_key_t *key,
+                       const cynagora_value_t *value);
+
+/**
+ * Callback for receiving asynchronousely the replies to the queries
+ * Receives:
+ *  closure: the closure given to cynagora_async_check
+ *  status: 0 if forbidden
+ *          1 if granted
+ *          -ECANCELED if cancelled
+ */
+typedef void cynagora_async_check_cb_t(
+               void *closure,
+               int status);
+
+/**
+ * Callback for managing the connection in an external loop
+ * 
+ * That callback receives epoll_ctl operations, a file descriptor number and
+ * a mask of expected events.
+ * 
+ * @see epoll_ctl
+ */
+typedef int cynagora_async_ctl_cb_t(
+                       void *closure,
+                       int op,
+                       int fd,
+                       uint32_t events);
+
+/**
+ * Create a client to the permission server cynagora
+ * The client is created but not connected. The connection is made on need.
+ * 
+ * @param cynagora   pointer to the handle of the opened client
+ * @param type       type of the client to open
+ * @param cache_size requested cache size
+ * @param socketspec specification of the socket to connect to or NULL for
+ *                   using the default
+ * 
+ * @return 0 in case of success and in that case *cynagora is filled
+ *         a negative -errno value and *cynara is set to NULL
+ * 
+ * @see cynagora_destroy, cynagora_cache_resize
+ */
 extern
 int
-cynagora_open(
+cynagora_create(
        cynagora_t **cynagora,
        cynagora_type_t type,
        uint32_t cache_size,
        const char *socketspec
 );
 
+/**
+ * Destroy the client handler and release its memory
+ * 
+ * @param cynagora the client handler to close
+ * 
+ * @see cynagora_create
+ */
 extern
 void
-cynagora_disconnect(
+cynagora_destroy(
        cynagora_t *cynagora
 );
 
+/**
+ * Ask the client to disconnect from the server.
+ * The client will reconnect if needed.
+ * 
+ * @param cynagora the client handler
+ */
 extern
 void
-cynagora_close(
+cynagora_disconnect(
        cynagora_t *cynagora
 );
 
+/**
+ * Clear the cache
+ * 
+ * @param cynagora the client handler
+ * 
+ * @see cynagora_cache_resize
+ */
 extern
-int
-cynagora_enter(
+void
+cynagora_cache_clear(
        cynagora_t *cynagora
 );
 
+/**
+ * Resize the cache
+ * 
+ * @param cynagora the client handler
+ * @param size     new expected cache
+ * 
+ * @return 0 on success or -ENOMEM if out of memory
+ * 
+ * @see cynagora_cache_clear, cynagora_create
+ */
 extern
 int
-cynagora_leave(
+cynagora_cache_resize(
        cynagora_t *cynagora,
-       bool commit
+       uint32_t size
 );
 
+/**
+ * Check a key against the cache
+ * 
+ * @param cynagora the client handler
+ * @param key the key to check
+ * 
+ * @return 0 if forbidden, 1 if authorize, -ENOENT if cache miss
+ * 
+ * @see cynagora_check
+ */
 extern
 int
-cynagora_check(
+cynagora_cache_check(
        cynagora_t *cynagora,
        const cynagora_key_t *key
 );
 
+/**
+ * Query the permission database for the key (synchronous)
+ * Allows agent resolution.
+ * 
+ * @param cynagora the client handler
+ * @param key      the key to check
+ * 
+ * @return 0 if permission forbidden, 1 if permission granted
+ *         or if error a negative -errno value
+ * 
+ * @see cynagora_test, cynagora_cache_check
+ */
 extern
 int
-cynagora_test(
+cynagora_check(
        cynagora_t *cynagora,
        const cynagora_key_t *key
 );
 
+/**
+ * Query the permission database for the key (synchronous)
+ * Avoids agent resolution.
+ * 
+ * @param cynagora the client handler
+ * @param key
+ * @return 
+ * 
+ * @see cynagora_check
+ */
 extern
 int
-cynagora_set(
+cynagora_test(
        cynagora_t *cynagora,
-       const cynagora_key_t *key,
-       const cynagora_value_t *value
+       const cynagora_key_t *key
 );
 
+/**
+ * List any value of the permission database that matches the key (admin, synchronous)
+ * 
+ * @param cynagora the client handler
+ * @param key      the selection key
+ * @param callback the callback for receiving items
+ * @param closure  closure of the callback
+ * 
+ * @return 0 in case of success or a negative -errno value
+ */
 extern
 int
 cynagora_get(
        cynagora_t *cynagora,
        const cynagora_key_t *key,
-       void (*callback)(
-               void *closure,
-               const cynagora_key_t *key,
-               const cynagora_value_t *value
-       ),
+       cynagora_get_cb_t *callback,
        void *closure
 );
 
+/**
+ * Query or set the logging of requests (admin, synchronous)
+ * 
+ * @param cynagora the client handler
+ * @param on       should set on
+ * @param off      should set off
+ * 
+ * @return 0 if not logging, 1 if logging or a negative -errno value
+ */
 extern
 int
 cynagora_log(
@@ -121,61 +268,132 @@ cynagora_log(
        int off
 );
 
+/**
+ * Enter cancelable section for modifying database (admin, synchronous)
+ * 
+ * @param cynagora the handler of the client
+ * 
+ * @return 0 in case of success or a negative -errno value
+ *         -EPERM if not a admin client
+ *         -EINPROGRESS if already entered
+ * 
+ * @see cynagora_leave, cynagora_set, cynagora_drop
+ */
 extern
 int
-cynagora_drop(
-       cynagora_t *cynagora,
-       const cynagora_key_t *key
+cynagora_enter(
+       cynagora_t *cynagora
 );
 
+/**
+ * Leave cancelable section for modifying database (admin, synchronous)
+ * 
+ * @param cynagora  the handler of the client
+ * @param commit    if zero, cancel the modifications in progress otherwise if
+ *                  not zero, commit the changes
+ * 
+ * @return 0 in case of success or a negative -errno value
+ *         -EPERM if not a admin client
+ *         -ECANCELED if not entered
+ * 
+ * @see cynagora_enter, cynagora_set, cynagora_drop
+ */
 extern
-void
-cynagora_cache_clear(
-       cynagora_t *cynagora
+int
+cynagora_leave(
+       cynagora_t *cynagora,
+       int commit
 );
 
+/**
+ * Set a rule (either create or change it) (admin, synchronous)
+ * This call requires to have entered the cancelable section.
+ * 
+ * @param cynagora  the handler of the client
+ * @param key       the key to set
+ * @param value     the value to set to the key
+ * 
+ * @return 0 in case of success or a negative -errno value
+ *         -EPERM if not a admin client
+ *         -ECANCELED if not entered
+ * 
+ * @see cynagora_enter, cynagora_leave, cynagora_drop
+ */
 extern
 int
-cynagora_cache_check(
+cynagora_set(
        cynagora_t *cynagora,
-       const cynagora_key_t *key
+       const cynagora_key_t *key,
+       const cynagora_value_t *value
 );
 
+/**
+ * Drop items matching the key selector (admin, synchronous)
+ * This call requires to have entered the cancelable section.
+ * 
+ * @param cynagora  the handler of the client
+ * @param key       Filter of the keys to drop
+ * 
+ * @return  0 in case of success or a negative -errno value
+ *         -EPERM if not a admin client
+ *         -ECANCELED if not entered
+ * 
+ * @see cynagora_enter, cynagora_leave, cynagora_set
+ */
 extern
 int
-cynagora_cache_resize(
+cynagora_drop(
        cynagora_t *cynagora,
-       uint32_t size
+       const cynagora_key_t *key
 );
 
-typedef int (*cynagora_async_ctl_t)(
-                       void *closure,
-                       int op,
-                       int fd,
-                       uint32_t events);
-
+/**
+ * Set the asynchronous control function
+ * 
+ * @param cynagora  the handler of the client
+ * @param controlcb
+ * @param closure
+ * 
+ * @return  0 in case of success or a negative -errno value
+ */
 extern
 int
 cynagora_async_setup(
        cynagora_t *cynagora,
-       cynagora_async_ctl_controlcb,
+       cynagora_async_ctl_cb_t *controlcb,
        void *closure
 );
 
+/**
+ * Process the inputs of the client
+ * 
+ * @param cynagora  the handler of the client
+ * 
+ * @return  0 in case of success or a negative -errno value
+ */
 extern
 int
 cynagora_async_process(
        cynagora_t *cynagora
 );
 
+/**
+ * Check the key asynchronousely (async)
+ * 
+ * @param cynagora  the handler of the client
+ * @param key       the key to query
+ * @param simple    if zero allows agent process else if not 0 forbids it
+ * @param callback  the callback to call on reply
+ * @param closure   a closure for the callback
+ * 
+ * @return  0 in case of success or a negative -errno value
+ */
 extern
 int
 cynagora_async_check(
        cynagora_t *cynagora,
        const cynagora_key_t *key,
        int simple,
-       void (*callback)(
-               void *closure,
-               int status),
+       cynagora_async_check_cb_t *callback,
        void *closure
 );
index 216dd7e..7b657c0 100644 (file)
@@ -764,7 +764,7 @@ int main(int ac, char **av)
 
        /* initialize server */
        signal(SIGPIPE, SIG_IGN); /* avoid SIGPIPE! */
-       rc = cynagora_open(&cynagora, cynagora_Admin, cachesize, socket);
+       rc = cynagora_create(&cynagora, cynagora_Admin, cachesize, socket);
        if (rc < 0) {
                fprintf(stderr, "initialization failed: %s\n", strerror(-rc));
                return 1;