Adding utils-json
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 4 Feb 2016 11:29:49 +0000 (12:29 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 4 Feb 2016 14:48:22 +0000 (15:48 +0100)
This provides facilities for handling json.

Change-Id: I325d5685ded745721a1801267b9c53beb974385c
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
src/CMakeLists.txt
src/afm-db.c
src/afm-run.c
src/afm-system-daemon.c
src/utils-json.c [new file with mode: 0644]
src/utils-json.h [new file with mode: 0644]

index 1c64ad2..9379142 100644 (file)
@@ -55,7 +55,8 @@ endif(USE_SIMULATION)
 
 ###########################################################################
 
-add_compile_options(-Wall -Wno-pointer-sign -Werror=maybe-uninitialized)
+add_compile_options(-Wall -Wno-pointer-sign)
+add_compile_options(-Werror=maybe-uninitialized -Werror=implicit-function-declaration)
 add_compile_options(-ffunction-sections -fdata-sections)
 add_compile_options(-fPIC)
 add_compile_options(-Wl,--gc-sections)
@@ -82,6 +83,7 @@ add_library(wgtpkg
 add_library(utils
        utils-dir.c
        utils-jbus.c
+       utils-json.c
        verbose.c
        )
 
index 8f52d1c..b9cf1e0 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <json.h>
 
+#include "utils-json.h"
 #include "wgt-info.h"
 #include "afm-db.h"
 
@@ -145,24 +146,6 @@ int afm_db_add_application(struct afm_db *afdb, const char *path)
        return add_dir(afdb, path, type_app);
 }
 
-static int json_add(struct json_object *obj, const char *key, struct json_object *val)
-{
-       json_object_object_add(obj, key, val);
-       return 0;
-}
-
-static int json_add_str(struct json_object *obj, const char *key, const char *val)
-{
-       struct json_object *str = json_object_new_string (val ? val : "");
-       return str ? json_add(obj, key, str) : -1;
-}
-
-static int json_add_int(struct json_object *obj, const char *key, int val)
-{
-       struct json_object *v = json_object_new_int (val);
-       return v ? json_add(obj, key, v) : -1;
-}
-
 static int addapp(struct afapps *apps, const char *path)
 {
        struct wgt_info *info;
@@ -188,7 +171,7 @@ static int addapp(struct afapps *apps, const char *path)
        if (!priv)
                goto error2;
 
-       if (json_add(priv, "public", pub)) {
+       if (!j_add(priv, "public", pub)) {
                json_object_put(pub);
                goto error2;
        }
@@ -197,23 +180,23 @@ static int addapp(struct afapps *apps, const char *path)
        if (!priv)
                goto error2;
 
-       if (json_add(priv, "plugins", plugs)) {
+       if (!j_add(priv, "plugins", plugs)) {
                json_object_put(plugs);
                goto error2;
        }
 
-       if(json_add_str(priv, "id", desc->id)
-       || json_add_str(priv, "path", path)
-       || json_add_str(priv, "content", desc->content_src)
-       || json_add_str(priv, "type", desc->content_type)
-       || json_add_str(pub, "id", desc->idaver)
-       || json_add_str(pub, "version", desc->version)
-       || json_add_int(pub, "width", desc->width)
-       || json_add_int(pub, "height", desc->height)
-       || json_add_str(pub, "name", desc->name)
-       || json_add_str(pub, "description", desc->description)
-       || json_add_str(pub, "shortname", desc->name_short)
-       || json_add_str(pub, "author", desc->author))
+       if(!j_add_string(priv, "id", desc->id)
+       || !j_add_string(priv, "path", path)
+       || !j_add_string(priv, "content", desc->content_src)
+       || !j_add_string(priv, "type", desc->content_type)
+       || !j_add_string(pub, "id", desc->idaver)
+       || !j_add_string(pub, "version", desc->version)
+       || !j_add_integer(pub, "width", desc->width)
+       || !j_add_integer(pub, "height", desc->height)
+       || !j_add_string(pub, "name", desc->name)
+       || !j_add_string(pub, "description", desc->description)
+       || !j_add_string(pub, "shortname", desc->name_short)
+       || !j_add_string(pub, "author", desc->author))
                goto error2;
 
        feat = desc->features;
@@ -236,17 +219,17 @@ static int addapp(struct afapps *apps, const char *path)
                bya = json_object_new_object();
                if (!bya)
                        goto error2;
-               if (json_add(apps->byapp, desc->id, bya)) {
+               if (!j_add(apps->byapp, desc->id, bya)) {
                        json_object_put(bya);
                        goto error2;
                }
        }
 
-       if (json_add(apps->direct, desc->idaver, priv))
+       if (!j_add(apps->direct, desc->idaver, priv))
                goto error2;
        json_object_get(priv);
 
-       if (json_add(bya, desc->version, priv)) {
+       if (!j_add(bya, desc->version, priv)) {
                json_object_put(priv);
                goto error2;
        }
index f28849a..89d303f 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "verbose.h"
 #include "utils-dir.h"
+#include "utils-json.h"
 #include "afm-run.h"
 #include "afm-launch.h"
 
@@ -238,35 +239,19 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
 
 /**************** handle afm_launch_desc *********************/
 
-static int get_jstr(struct json_object *obj, const char *key, const char **value)
-{
-       json_object *data;
-       return json_object_object_get_ex(obj, key, &data)
-               && json_object_get_type(data) == json_type_string
-               && (*value = json_object_get_string(data)) != NULL;
-}
-
-static int get_jint(struct json_object *obj, const char *key, int *value)
-{
-       json_object *data;
-       return json_object_object_get_ex(obj, key, &data)
-               && json_object_get_type(data) == json_type_int
-               && ((*value = (int)json_object_get_int(data)), 1);
-}
-
 static int fill_launch_desc(struct json_object *appli, struct afm_launch_desc *desc)
 {
        json_object *pub;
 
        /* main items */
-       if(!json_object_object_get_ex(appli, "public", &pub)
-       || !get_jstr(appli, "path", &desc->path)
-       || !get_jstr(appli, "id", &desc->tag)
-       || !get_jstr(appli, "content", &desc->content)
-       || !get_jstr(appli, "type", &desc->type)
-       || !get_jstr(pub, "name", &desc->name)
-       || !get_jint(pub, "width", &desc->width)
-       || !get_jint(pub, "height", &desc->height)) {
+       if(!j_object(appli, "public", &pub)
+       || !j_string(appli, "path", &desc->path)
+       || !j_string(appli, "id", &desc->tag)
+       || !j_string(appli, "content", &desc->content)
+       || !j_string(appli, "type", &desc->type)
+       || !j_string(pub, "name", &desc->name)
+       || !j_integer(pub, "width", &desc->width)
+       || !j_integer(pub, "height", &desc->height)) {
                errno = EINVAL;
                return -1;
        }
@@ -352,10 +337,8 @@ static json_object *mkstate(struct apprun *runner)
                goto error;
 
        /* the runid */
-       obj = json_object_new_int(runner->runid);
-       if (obj == NULL)
+       if (!j_add_integer(result, "runid", runner->runid))
                goto error2;
-       json_object_object_add(result, "runid", obj); /* TODO TEST STATUS */
 
        /* the state */
        switch(runner->state) {
@@ -370,17 +353,16 @@ static json_object *mkstate(struct apprun *runner)
                state = "terminated";
                break;
        }
-       obj = json_object_new_string(state);
-       if (obj == NULL)
+       if (!j_add_string(result, "state", state))
                goto error2;
-       json_object_object_add(result, "state", obj); /* TODO TEST STATUS */
 
        /* the application id */
        rc = json_object_object_get_ex(runner->appli, "public", &obj);
        assert(rc);
        rc = json_object_object_get_ex(obj, "id", &obj);
        assert(rc);
-       json_object_object_add(result, "id", obj); /* TODO TEST STATUS */
+       if (!j_add(result, "id", obj))
+               goto error2;
        json_object_get(obj);
 
        /* done */
@@ -401,25 +383,29 @@ struct json_object *afm_run_list()
 
        /* creates the object */
        result = json_object_new_array();
-       if (result == NULL) {
-               errno = ENOMEM;
-               return NULL;            
-       }
+       if (result == NULL)
+               goto error;
 
        for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) {
                for (runner = runners_by_runid[i] ; runner ; runner = runner->next_by_runid) {
                        if (runner->state != as_terminating && runner->state != as_terminated) {
                                obj = mkstate(runner);
-                               if (obj == NULL) {
-                                       json_object_put(result);
-                                       return NULL;
+                               if (obj == NULL)
+                                       goto error2;
+                               if (json_object_array_add(result, obj) == -1) {
+                                       json_object_put(obj);
+                                       goto error2;
                                }
-                               /* TODO status ? */
-                               json_object_array_add(result, obj);
                        }
                }
        }
        return result;
+
+error2:
+       json_object_put(result);
+error:
+       errno = ENOMEM;
+       return NULL;
 }
 
 struct json_object *afm_run_state(int runid)
index 70d8656..f02ff3d 100644 (file)
 
 #include "verbose.h"
 #include "utils-jbus.h"
+#include "utils-json.h"
 #include "afm.h"
 #include "afm-db.h"
 #include "wgt-info.h"
 #include "wgtpkg-install.h"
 
 static const char appname[] = "afm-system-daemon";
+static const char *rootdir = NULL;
 
 static void usage()
 {
        printf(
-               "usage: %s [-q] [-v] [-r rootdir]... [-a appdir]...\n"
+               "usage: %s [-q] [-v] [-r rootdir]\n"
                "\n"
-               "   -a appdir    adds an application directory\n"
-               "   -r rootdir   adds a root directory of applications\n"
+               "   -r rootdir   set root directory of applications\n"
                "   -d           run as a daemon\n"
                "   -q           quiet\n"
                "   -v           verbose\n"
@@ -50,7 +51,6 @@ static void usage()
 
 static struct option options[] = {
        { "root",        required_argument, NULL, 'r' },
-       { "application", required_argument, NULL, 'a' },
        { "daemon",      no_argument,       NULL, 'd' },
        { "quiet",       no_argument,       NULL, 'q' },
        { "verbose",     no_argument,       NULL, 'v' },
@@ -59,71 +59,12 @@ static struct option options[] = {
 };
 
 static struct jbus *jbus;
-static struct afm_db *afdb;
 
 const char error_nothing[] = "[]";
 const char error_bad_request[] = "\"bad request\"";
 const char error_not_found[] = "\"not found\"";
 const char error_cant_start[] = "\"can't start\"";
 
-static const char *getappid(struct json_object *obj)
-{
-       return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
-}
-
-static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
-{
-       if (resp)
-               jbus_reply_j(jreq, resp);
-       else
-               jbus_reply_error_s(jreq, errstr);
-}
-
-static void on_runnables(struct jreq *jreq, struct json_object *obj)
-{
-       struct json_object *resp = afm_db_application_list(afdb);
-       jbus_reply_j(jreq, resp);
-       json_object_put(resp);
-}
-
-static void on_detail(struct jreq *jreq, struct json_object *obj)
-{
-       const char *appid = getappid(obj);
-       struct json_object *resp = afm_db_get_application_public(afdb, appid);
-       reply(jreq, resp, error_not_found);
-       json_object_put(resp);
-}
-
-static const char *j_get_string(struct json_object *obj, const char *key, const char *defval)
-{
-       struct json_object *o;
-       return json_object_object_get_ex(obj, key, &o) && json_object_get_type(o) == json_type_string ? json_object_get_string(o) : defval;
-}
-
-static int j_get_boolean(struct json_object *obj, const char *key, int defval)
-{
-       struct json_object *o;
-       return json_object_object_get_ex(obj, key, &o) && json_object_get_type(o) == json_type_boolean ? json_object_get_boolean(o) : defval;
-}
-
-static int json_add(struct json_object *obj, const char *key, struct json_object *val)
-{
-       json_object_object_add(obj, key, val);
-       return 0;
-}
-
-static int json_add_str(struct json_object *obj, const char *key, const char *val)
-{
-       struct json_object *str = json_object_new_string (val ? val : "");
-       return str ? json_add(obj, key, str) : (errno = ENOMEM, -1);
-}
-/*
-static int json_add_int(struct json_object *obj, const char *key, int val)
-{
-       struct json_object *v = json_object_new_int (val);
-       return v ? json_add(obj, key, v) : (errno = ENOMEM, -1);
-}
-*/
 static void on_install(struct jreq *jreq, struct json_object *req)
 {
        const char *wgtfile;
@@ -136,13 +77,13 @@ static void on_install(struct jreq *jreq, struct json_object *req)
        switch (json_object_get_type(req)) {
        case json_type_string:
                wgtfile = json_object_get_string(req);
-               root = FWK_APP_DIR;
+               root = rootdir;
                force = 0;
                break;
        case json_type_object:
                wgtfile = j_get_string(req, "wgt", NULL);
                if (wgtfile != NULL) {
-                       root = j_get_string(req, "root", FWK_APP_DIR);
+                       root = j_get_string(req, "root", rootdir);
                        force = j_get_boolean(req, "force", 0);
                        break;
                }
@@ -160,7 +101,7 @@ static void on_install(struct jreq *jreq, struct json_object *req)
 
        /* build the response */
        resp = json_object_new_object();
-       if(!resp || json_add_str(resp, "added", wgt_info_desc(ifo)->idaver)) {
+       if(!resp || !j_add_string(resp, "added", wgt_info_desc(ifo)->idaver)) {
                json_object_put(resp);
                wgt_info_unref(ifo);
                jbus_reply_error_s(jreq, "\"out of memory but installed!\"");
@@ -168,9 +109,6 @@ static void on_install(struct jreq *jreq, struct json_object *req)
        }
        wgt_info_unref(ifo);
 
-       /* update the current database */
-       afm_db_update_applications(afdb);
-
        /* reply and propagate event */
        jbus_reply_j(jreq, resp);
        jbus_send_signal_j(jbus, "changed", resp);
@@ -198,8 +136,8 @@ int main(int ac, char **av)
 
        LOGAUTH(appname);
 
-       /* first interpretation of arguments */
-       while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
+       /* interpretation of arguments */
+       while ((i = getopt_long(ac, av, "hdqvr:", options, NULL)) >= 0) {
                switch (i) {
                case 'h':
                        usage();
@@ -215,8 +153,12 @@ int main(int ac, char **av)
                        daemon = 1;
                        break;
                case 'r':
-                       break;
-               case 'a':
+                       if (rootdir == NULL)
+                               rootdir = optarg;
+                       else {
+                               ERROR("duplicate definition of rootdir");
+                               return 1;
+                       }
                        break;
                case ':':
                        ERROR("missing argument value");
@@ -227,42 +169,22 @@ int main(int ac, char **av)
                }
        }
 
-       /* init framework */
-       afdb = afm_db_create();
-       if (!afdb) {
-               ERROR("afm_create failed");
-               return 1;
-       }
-       if (afm_db_add_root(afdb, FWK_APP_DIR)) {
-               ERROR("can't add root %s", FWK_APP_DIR);
-               return 1;
-       }
-
-       /* second interpretation of arguments */
-       optind = 1;
-       while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) {
-               switch (i) {
-               case 'r':
-                       if (afm_db_add_root(afdb, optarg)) {
-                               ERROR("can't add root %s", optarg);
-                               return 1;
-                       }
-                       break;
-               case 'a':
-                       if (afm_db_add_application(afdb, optarg)) {
-                                ERROR("can't add application %s", optarg);
-                                return 1;
-                        }
-                       break;
+       /* check the rootdir */
+       if (rootdir == NULL)
+               rootdir = FWK_APP_DIR;
+       else {
+               rootdir = realpath(rootdir, NULL);
+               if (rootdir == NULL) {
+                       ERROR("out of memory");
+                       return 1;
                }
        }
-
-       /* update the database */
-       if (afm_db_update_applications(afdb)) {
-               ERROR("afm_update_applications failed");
+       if (chdir(rootdir)) {
+               ERROR("can't enter %s", rootdir);
                return 1;
        }
 
+       /* daemonize */
        if (daemon && daemonize()) {
                ERROR("daemonization failed");
                return 1;
@@ -274,9 +196,7 @@ int main(int ac, char **av)
                ERROR("create_jbus failed");
                return 1;
        }
-       if(jbus_add_service_j(jbus, "runnables", on_runnables)
-       || jbus_add_service_j(jbus, "detail", on_detail)
-       || jbus_add_service_j(jbus, "install", on_install)
+       if(jbus_add_service_j(jbus, "install", on_install)
        || jbus_add_service_j(jbus, "uninstall", on_uninstall)) {
                ERROR("adding services failed");
                return 1;
diff --git a/src/utils-json.c b/src/utils-json.c
new file mode 100644 (file)
index 0000000..b3bee36
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ Copyright 2015 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.
+*/
+
+#include <errno.h>
+
+#include <json.h>
+
+#include "utils-json.h"
+
+int j_object(struct json_object *obj, const char *key, struct json_object **value)
+{
+       return json_object_object_get_ex(obj, key, value);
+}
+
+int j_string(struct json_object *obj, const char *key, const char **value)
+{
+       json_object *data;
+       return j_object(obj, key, &data)
+               && json_object_get_type(data) == json_type_string
+               && (*value = json_object_get_string(data)) != NULL;
+}
+
+int j_boolean(struct json_object *obj, const char *key, int *value)
+{
+       json_object *data;
+       return json_object_object_get_ex(obj, key, &data)
+               && json_object_get_type(data) == json_type_boolean
+               && ((*value = (int)json_object_get_boolean(data)), 1);
+}
+
+int j_integer(struct json_object *obj, const char *key, int *value)
+{
+       json_object *data;
+       return json_object_object_get_ex(obj, key, &data)
+               && json_object_get_type(data) == json_type_int
+               && ((*value = (int)json_object_get_int(data)), 1);
+}
+
+const char *j_get_string(struct json_object *obj, const char *key, const char *defval)
+{
+       struct json_object *o;
+       return json_object_object_get_ex(obj, key, &o)
+               && json_object_get_type(o) == json_type_string
+                       ? json_object_get_string(o) : defval;
+}
+
+int j_get_boolean(struct json_object *obj, const char *key, int defval)
+{
+       struct json_object *o;
+       return json_object_object_get_ex(obj, key, &o)
+               && json_object_get_type(o) == json_type_boolean
+                       ? json_object_get_boolean(o) : defval;
+}
+
+int j_get_integer(struct json_object *obj, const char *key, int defval)
+{
+       struct json_object *o;
+       return json_object_object_get_ex(obj, key, &o)
+               && json_object_get_type(o) == json_type_int
+                       ? json_object_get_int(o) : defval;
+}
+
+int j_add(struct json_object *obj, const char *key, struct json_object *val)
+{
+       json_object_object_add(obj, key, val);
+       return 1;
+}
+
+int j_add_string(struct json_object *obj, const char *key, const char *val)
+{
+       struct json_object *str = json_object_new_string (val);
+       return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
+}
+
+int j_add_boolean(struct json_object *obj, const char *key, int val)
+{
+       struct json_object *str = json_object_new_boolean (val);
+       return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
+}
+
+int j_add_integer(struct json_object *obj, const char *key, int val)
+{
+       struct json_object *str = json_object_new_int (val);
+       return str ? j_add(obj, key, str) : (errno = ENOMEM, 0);
+}
+
diff --git a/src/utils-json.h b/src/utils-json.h
new file mode 100644 (file)
index 0000000..9778347
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ Copyright 2015 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.
+*/
+
+int j_object(struct json_object *obj, const char *key, struct json_object **value);
+int j_string(struct json_object *obj, const char *key, const char **value);
+int j_boolean(struct json_object *obj, const char *key, int *value);
+int j_integer(struct json_object *obj, const char *key, int *value);
+
+extern const char *j_get_string(struct json_object *obj, const char *key, const char *defval);
+extern int j_get_boolean(struct json_object *obj, const char *key, int defval);
+extern int j_get_integer(struct json_object *obj, const char *key, int defval);
+
+extern int j_add(struct json_object *obj, const char *key, struct json_object *val);
+extern int j_add_string(struct json_object *obj, const char *key, const char *val);
+extern int j_add_boolean(struct json_object *obj, const char *key, int val);
+extern int j_add_integer(struct json_object *obj, const char *key, int val);
+