From bb15844347ed0d53a795d24dce7035ab27df4e53 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Thu, 4 Feb 2016 12:29:49 +0100 Subject: [PATCH] Adding utils-json MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This provides facilities for handling json. Change-Id: I325d5685ded745721a1801267b9c53beb974385c Signed-off-by: José Bollo --- src/CMakeLists.txt | 4 +- src/afm-db.c | 53 +++++++------------ src/afm-run.c | 66 ++++++++++-------------- src/afm-system-daemon.c | 134 ++++++++++-------------------------------------- src/utils-json.c | 101 ++++++++++++++++++++++++++++++++++++ src/utils-json.h | 32 ++++++++++++ 6 files changed, 207 insertions(+), 183 deletions(-) create mode 100644 src/utils-json.c create mode 100644 src/utils-json.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1c64ad2..9379142 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 ) diff --git a/src/afm-db.c b/src/afm-db.c index 8f52d1c..b9cf1e0 100644 --- a/src/afm-db.c +++ b/src/afm-db.c @@ -27,6 +27,7 @@ #include +#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; } diff --git a/src/afm-run.c b/src/afm-run.c index f28849a..89d303f 100644 --- a/src/afm-run.c +++ b/src/afm-run.c @@ -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) diff --git a/src/afm-system-daemon.c b/src/afm-system-daemon.c index 70d8656..f02ff3d 100644 --- a/src/afm-system-daemon.c +++ b/src/afm-system-daemon.c @@ -26,20 +26,21 @@ #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 index 0000000..b3bee36 --- /dev/null +++ b/src/utils-json.c @@ -0,0 +1,101 @@ +/* + Copyright 2015 IoT.bzh + + author: José Bollo + + 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 + +#include + +#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 index 0000000..9778347 --- /dev/null +++ b/src/utils-json.h @@ -0,0 +1,32 @@ +/* + Copyright 2015 IoT.bzh + + author: José Bollo + + 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); + -- 2.16.6