in progress
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 15 Dec 2015 10:20:08 +0000 (11:20 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Tue, 15 Dec 2015 10:20:08 +0000 (11:20 +0100)
Change-Id: Ida682c87abc3413e0e84c56f60d54e1c5409fd3a

.gitignore
configure.ac
src/Makefile.am
src/appfwk.c
src/wgtpkg-install.c
src/wgtpkg-installer.c
src/wgtpkg-workdir.c

index 96295c2..cee9cf3 100644 (file)
@@ -1,3 +1,4 @@
+appfwk
 wgtpkg-installer
 wgtpkg-pack
 wgtpkg-sign
@@ -16,14 +17,13 @@ depcomp
 install-sh
 missing
 
-UNPACK*/
-PACK*/
 TODO
 a.pem
 b.pem
 ca-certificates/
 certs/
 old/
+root/
 schemas/
 tests-w3c/
 tests/
index 04f21ce..adee3da 100644 (file)
@@ -25,6 +25,7 @@ PKG_CHECK_MODULES([XML2], [libxml-2.0])
 PKG_CHECK_MODULES([OPENSSL], [openssl])
 PKG_CHECK_MODULES([XMLSEC], [xmlsec1 xmlsec1-openssl])
 PKG_CHECK_MODULES([JSON], [json-c])
+PKG_CHECK_MODULES([DBUS], [dbus-1])
 
 # Checks for header files.
 AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h syslog.h unistd.h])
index 0826e12..3465049 100644 (file)
@@ -1,6 +1,12 @@
-bin_PROGRAMS = wgtpkg-installer wgtpkg-pack wgtpkg-sign wgtpkg-info appfwk
+bin_PROGRAMS = \
+       wgtpkg-installer \
+       wgtpkg-pack \
+       wgtpkg-sign \
+       wgtpkg-info \
+       appfwk
 
 OTHERSRCS = \
+       utils-dir.c \
        verbose.c
 
 WGTPKGSRCS = \
@@ -26,28 +32,45 @@ APPFWK = \
        appfwk.c
 
 
-#pkgsysconfdir = $(sysconfdir)
-pkgsysconfdir = .
-#deffwdir = $(datadir)/af
-deffwdir = ./af
-defappdir = $(deffwdir)/applications
-deficondir = $(deffwdir)/icons
-
 AM_CFLAGS  = -Wall -Wno-pointer-sign
 AM_CFLAGS += -ffunction-sections -fdata-sections
-AM_CFLAGS += ${ZIP_CFLAGS} ${XML2_CFLAGS} ${OPENSSL_CFLAGS} ${XMLSEC_CFLAGS} ${JSON_CFLAGS}
-
-AM_CFLAGS += -Isimulation
-
-AM_CFLAGS += -DPKGSYSCONFDIR=\"$(pkgsysconfdir)\"
-AM_CFLAGS += -DPREFIXPERMISSION=\"urn:agl-perm:\"
-AM_CFLAGS += -DICONDESTDIR=\"$(deficondir)\"
-AM_CFLAGS += -DAPPDEFDIR=\"$(defappdir)\"
 
+fwk_name = aglfwk
+fwk_confdir = $(sysconfdir)/$(fwk_name)
+fwk_datadir = $(datadir)/$(fwk_name)
+fwk_appdir = $(fwk_datadir)/applications
+fwk_icondir = $(fwk_datadir)/icons
+fwk_prefix = urn:agl:
+fwk_prefix_permission = $(fwk_prefix)perm:
+fwk_prefix_plugin = $(fwk_prefix)plugin:
+
+AM_CFLAGS += -DFWK_CONFIG_DIR=\"$(fwk_confdir)\"
+AM_CFLAGS += -DFWK_PREFIX_PERMISSION=\"$(fwk_prefix_permission)\"
+AM_CFLAGS += -DFWK_PREFIX_PLUGIN=\"$(fwk_prefix_plugin)\"
+AM_CFLAGS += -DFWK_ICON_DIR=\"$(fwk_icondir)\"
+AM_CFLAGS += -DFWK_APP_DIR=\"$(fwk_appdir)\"
 
 AM_LDFLAGS = -Wl,--gc-sections
 
-LDADD = ${ZIP_LIBS} ${XML2_LIBS} ${OPENSSL_LIBS} ${XMLSEC_LIBS} ${JSON_LIBS}
+AM_CFLAGS += \
+       ${DBUS_CFLAGS} \
+       ${JSON_CFLAGS} \
+       ${OPENSSL_CFLAGS} \
+       ${XML2_CFLAGS} \
+       ${XMLSEC_CFLAGS} \
+       ${ZIP_CFLAGS}
+
+LDADD = \
+       ${DBUS_LIBS} \
+       ${JSON_LIBS} \
+       ${OPENSSL_LIBS} \
+       ${XML2_LIBS} \
+       ${XMLSEC_LIBS} \
+       ${ZIP_LIBS}
+
+# remove (or comment) following line to really use simulated components
+AM_CFLAGS += -Isimulation
+
 
 wgtpkg_sign_SOURCES = wgtpkg-sign.c ${WGTPKGSRCS} ${OTHERSRCS}
 
@@ -59,3 +82,4 @@ wgtpkg_info_SOURCES = wgtpkg-info.c ${WGTPKGSRCS} ${WGTSRCS} ${OTHERSRCS}
 
 appfwk_SOURCES = ${APPFWK} ${WGTSRCS} ${OTHERSRCS}
 
+
index c6a874e..0ede96a 100644 (file)
 
 #include <wgt-info.h>
 
+struct afapps {
+       struct json_object *pubarr;
+       struct json_object *direct;
+       struct json_object *byapp;
+};
+
 struct appfwk {
        int refcount;
        int nrroots;
        char **roots;
-       struct json_object *applications;
+       struct afapps applications;
 };
 
 struct appfwk *appfwk_create()
@@ -43,7 +49,9 @@ struct appfwk *appfwk_create()
                appfwk->refcount = 1;
                appfwk->nrroots = 0;
                appfwk->roots = NULL;
-               appfwk->applications = NULL;
+               appfwk->applications.pubarr = NULL;
+               appfwk->applications.direct = NULL;
+               appfwk->applications.byapp = NULL;
        }
        return appfwk;
 }
@@ -100,7 +108,6 @@ int appfwk_add_root(struct appfwk *appfwk, const char *path)
        return 0;
 }
 
-
 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
 {
        json_object_object_add(obj, key, val);
@@ -119,66 +126,113 @@ static int json_add_int(struct json_object *obj, const char *key, int val)
        return v ? json_add(obj, key, v) : -1;
 }
 
-static struct json_object *read_app_desc(const char *path)
+static int addapp(struct afapps *apps, const char *path)
 {
        struct wgt_info *info;
        const struct wgt_desc *desc;
-       struct json_object *result;
+       const struct wgt_desc_feature *feat;
+       struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
        char *appid, *end;
 
-       result = json_object_new_object();
-       if (!result)
-               goto error;
-
-       info = wgt_info_createat(AT_FDCWD, path, 0, 0, 0);
+       /* connect to the widget */
+       info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
        if (info == NULL)
-               goto error2;
+               goto error;
        desc = wgt_info_desc(info);
 
+       /* create the application id */
        appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
        end = stpcpy(appid, desc->id);
        *end++ = '@';
        strcpy(end, desc->version);
 
-       if(json_add_str(result, "appid", appid)
-       || json_add_str(result, "id", desc->id)
-       || json_add_str(result, "version", desc->version)
-       || json_add_str(result, "path", path)
-       || json_add_int(result, "width", desc->width)
-       || json_add_int(result, "height", desc->height)
-       || json_add_str(result, "name", desc->name)
-       || json_add_str(result, "description", desc->description)
-       || json_add_str(result, "shortname", desc->name_short)
-       || json_add_str(result, "author", desc->author))
-               goto error3;
+       /* create the application structure */
+       priv = json_object_new_object();
+       if (!priv)
+               goto error2;
 
-       wgt_info_unref(info);
-       return result;
+       pub = json_object_new_object();
+       if (!priv)
+               goto error2;
 
-error3:
-       wgt_info_unref(info);
-error2:
-       json_object_put(result);
-error:
-       return NULL;
-}
+       if (json_add(priv, "public", pub)) {
+               json_object_put(pub);
+               goto error2;
+       }
 
-static int add_appdesc(struct json_object *appset, struct json_object *app)
-{
-       struct json_object *appid;
+       plugs = json_object_new_array();
+       if (!priv)
+               goto error2;
 
-       if (!json_object_object_get_ex(app, "appid", &appid)) {
-               errno = EINVAL;
-               return -1;
+       if (json_add(priv, "plugins", plugs)) {
+               json_object_put(plugs);
+               goto error2;
        }
 
-       return json_add(appset, json_object_get_string(appid), app);
+       if(json_add_str(pub, "id", appid)
+       || json_add_str(priv, "id", desc->id)
+       || json_add_str(pub, "version", desc->version)
+       || json_add_str(priv, "path", path)
+       || 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))
+               goto error2;
+
+       feat = desc->features;
+       while (feat) {
+               static const char prefix[] = FWK_PREFIX_PLUGIN;
+               if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
+                       str = json_object_new_string (feat->name + sizeof prefix - 1);
+                       if (str == NULL)
+                               goto error2;
+                       if (json_object_array_add(plugs, str)) {
+                               json_object_put(str);
+                               goto error2;
+                       }
+               }
+               feat = feat->next;
+       }
+
+       /* record the application structure */
+       if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
+               bya = json_object_new_object();
+               if (!bya)
+                       goto error2;
+               if (json_add(apps->byapp, desc->id, bya)) {
+                       json_object_put(bya);
+                       goto error2;
+               }
+       }
+
+       if (json_add(apps->direct, appid, priv))
+               goto error2;
+       json_object_get(priv);
+
+       if (json_add(bya, desc->version, priv)) {
+               json_object_put(priv);
+               goto error2;
+       }
+
+       if (json_object_array_add(apps->pubarr, pub))
+               goto error2;
+
+       wgt_info_unref(info);
+       return 0;
+
+error2:
+       json_object_put(priv);
+       wgt_info_unref(info);
+error:
+       return -1;
 }
 
 struct enumdata {
        char path[PATH_MAX];
        int length;
-       struct json_object *apps;
+       struct afapps apps;
 };
 
 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
@@ -217,15 +271,7 @@ static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
 
 static int recordapp(struct enumdata *data)
 {
-       struct json_object *app;
-
-       app = read_app_desc(data->path);
-       if (app != NULL) {
-               if (!add_appdesc(data->apps, app))
-                       return 0;
-               json_object_put(app);
-       }
-       return -1;
+       return addapp(&data->apps, data->path);
 }
 
 /* enumerate the versions */
@@ -240,13 +286,15 @@ int appfwk_update_applications(struct appfwk *af)
 {
        int rc, iroot;
        struct enumdata edata;
-       struct json_object *oldapps;
+       struct afapps oldapps;
 
        /* create the result */
-       edata.apps = json_object_new_object();
-       if (edata.apps == NULL) {
+       edata.apps.pubarr = json_object_new_array();
+       edata.apps.direct = json_object_new_object();
+       edata.apps.byapp = json_object_new_object();
+       if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
                errno = ENOMEM;
-               return -1;
+               goto error;
        }
        /* for each root */
        for (iroot = 0 ; iroot < af->nrroots ; iroot++) {
@@ -254,25 +302,44 @@ int appfwk_update_applications(struct appfwk *af)
                assert(edata.length < sizeof edata.path);
                /* enumerate the applications */
                rc = enumentries(&edata, enumvers);
-               if (rc) {
-                       json_object_put(edata.apps);
-                       return rc;
-               }
+               if (rc)
+                       goto error;
        }
        /* commit the result */
        oldapps = af->applications;
        af->applications = edata.apps;
-       if (oldapps)
-               json_object_put(oldapps);
+       json_object_put(oldapps.pubarr);
+       json_object_put(oldapps.direct);
+       json_object_put(oldapps.byapp);
        return 0;
+
+error:
+       json_object_put(edata.apps.pubarr);
+       json_object_put(edata.apps.direct);
+       json_object_put(edata.apps.byapp);
+       return -1;
+}
+
+int appfwk_ensure_applications(struct appfwk *af)
+{
+       return af->applications.pubarr ? 0 : appfwk_update_applications(af);
+}
+
+/* regenerate the list of applications */
+struct json_object *appfwk_application_list(struct appfwk *af)
+{
+       return appfwk_ensure_applications(af) ? NULL : af->applications.pubarr;
 }
 
+#include <stdio.h>
 int main()
 {
 struct appfwk *af = appfwk_create();
-appfwk_add_root(af,"af/apps/");
+appfwk_add_root(af,FWK_APP_DIR);
 appfwk_update_applications(af);
-json_object_to_file("/dev/stdout", af->applications);
+printf("array = %s\n", json_object_to_json_string_ext(af->applications.pubarr, 3));
+printf("direct = %s\n", json_object_to_json_string_ext(af->applications.direct, 3));
+printf("byapp = %s\n", json_object_to_json_string_ext(af->applications.byapp, 3));
 return 0;
 }
 
index 6a4a865..096903b 100644 (file)
@@ -28,6 +28,7 @@
 #include "wgt.h"
 #include "wgt-info.h"
 #include "secmgr-wrap.h"
+#include "utils-dir.h"
 
 static int check_defined(const void *data, const char *name)
 {
@@ -126,7 +127,8 @@ static int install_icon(const struct wgt_desc *desc)
        char target[PATH_MAX];
        int rc;
 
-       rc = snprintf(link, sizeof link, "%s/%s@%s", ICONDESTDIR, desc->id, desc->version);
+       create_directory(FWK_ICON_DIR, 0755, 1);
+       rc = snprintf(link, sizeof link, "%s/%s@%s", FWK_ICON_DIR, desc->id, desc->version);
        if (rc >= sizeof link) {
                ERROR("link to long in install_icon");
                errno = EINVAL;
@@ -221,6 +223,7 @@ void install_widget(const char *wgtfile, const char *root, int force)
        NOTICE("-- INSTALLING widget %s --", wgtfile);
 
        /* workdir */
+       create_directory(root, 0755, 1);
        if (make_workdir_base(root, "TMP", 0)) {
                ERROR("failed to create a working directory");
                goto error1;
index 62807aa..3d9c237 100644 (file)
@@ -29,7 +29,7 @@
 #include "verbose.h"
 #include "wgtpkg.h"
 
-static const char appname[] = "wgtpkg-install";
+static const char appname[] = "wgtpkg-installer";
 static const char *root;
 static int force;
 
@@ -61,7 +61,6 @@ static struct option options[] = {
 int main(int ac, char **av)
 {
        int i;
-       char *wpath;
 
        openlog(appname, LOG_PERROR, LOG_AUTH);
 
@@ -104,19 +103,9 @@ int main(int ac, char **av)
                return 1;
        }
 
-       /* canonic names for files */
+       /* install widgets */
        av += optind;
-       for (i = 0 ; av[i] != NULL ; i++) {
-               wpath = realpath(av[i], NULL);
-               if (wpath == NULL) {
-                       ERROR("error while getting realpath of %dth widget: %s", i+1, av[i]);
-                       return 1;
-               }
-               av[i] = wpath;
-       }
        root = *av++;
-
-       /* install widgets */
        for ( ; *av ; av++)
                install_widget(*av, root, force);
 
index 7f2c7e6..1b8684c 100644 (file)
 
 #include "verbose.h"
 #include "wgtpkg.h"
+#include "utils-dir.h"
 
-static int mode = 0755;
+static const int dirmode = 0755;
 char workdir[PATH_MAX] = { 0, };
 int workdirfd = -1;
 
-/* removes recursively the content of a directory */
-static int clean_dirfd(int dirfd)
-{
-       int cr, fd;
-       DIR *dir;
-       struct dirent *ent;
-       struct {
-               struct dirent entry;
-               char spare[PATH_MAX];
-       } entry;
-
-       dirfd = dup(dirfd);
-       if (dirfd < 0) {
-               ERROR("failed to dup the dirfd");
-               return -1;
-       }
-       dir = fdopendir(dirfd);
-       if (dir == NULL) {
-               ERROR("fdopendir failed in clean_dirfd");
-               return -1;
-       }
-
-       cr = -1;
-       for (;;) {
-               if (readdir_r(dir, &entry.entry, &ent) != 0) {
-                       ERROR("readdir_r failed in clean_dirfd");
-                       goto error;
-               }
-               if (ent == NULL)
-                       break;
-               if (ent->d_name[0] == '.' && (ent->d_name[1] == 0
-                               || (ent->d_name[1] == '.' && ent->d_name[2] == 0)))
-                       continue;
-               cr = unlinkat(dirfd, ent->d_name, 0);
-               if (!cr)
-                       continue;
-               if (errno != EISDIR) {
-                       ERROR("unlink of %s failed in clean_dirfd", ent->d_name);
-                       goto error;
-               }
-               fd = openat(dirfd, ent->d_name, O_DIRECTORY|O_RDONLY);
-               if (fd < 0) {
-                       ERROR("opening directory %s failed in clean_dirfd", ent->d_name);
-                       goto error;
-               }
-               cr = clean_dirfd(fd);
-               close(fd);
-               if (cr)
-                       goto error;
-               cr = unlinkat(dirfd, ent->d_name, AT_REMOVEDIR);
-               if (cr) {
-                       ERROR("rmdir of %s failed in clean_dirfd", ent->d_name);
-                       goto error;
-               }
-       }
-       cr = 0;
-error:
-       closedir(dir);
-       return cr;
-}
-
-/* removes recursively the content of a directory */
-static int clean_dir(const char *directory)
-{
-       int fd, rc;
-
-       fd = openat(AT_FDCWD, directory, O_DIRECTORY|O_RDONLY);
-       if (fd < 0) {
-               ERROR("opening directory %s failed in clean_dir", directory);
-               return fd;
-       }
-       rc = clean_dirfd(fd);
-       close(fd);
-       return rc;
-}
-
 /* removes the working directory */
 void remove_workdir()
 {
        assert(workdirfd >= 0);
-       clean_dirfd(workdirfd);
+       remove_directory_content_fd(workdirfd);
        close(workdirfd);
        workdirfd = -1;
        rmdir(workdir);
@@ -140,7 +65,7 @@ static int set_real_workdir(const char *name, int create)
                        ERROR("no workdir %s", name);
                        return -1;
                }
-               rc = mkdir(name, mode);
+               rc = mkdir(name, dirmode);
                if (rc) {
                        ERROR("can't create workdir %s", name);
                        return -1;
@@ -206,7 +131,7 @@ static int make_real_workdir_base(const char *root, const char *prefix, int reus
                        errno = EINVAL;
                        return -1;
                }
-               if (!mkdir(workdir, mode))
+               if (!mkdir(workdir, dirmode))
                        break;
                if (errno != EEXIST) {
                        ERROR("error in creation of workdir %s: %m", workdir);
@@ -275,7 +200,7 @@ static int move_real_workdir(const char *dest, int parents, int force)
                        errno = EEXIST;
                        return -1;
                }
-               rc = clean_dir(dest);
+               rc = remove_directory_content(dest);
                if (rc) {
                        ERROR("in move_real_workdir, can't clean dir %s", dest);
                        return rc;
@@ -304,37 +229,9 @@ static int move_real_workdir(const char *dest, int parents, int force)
                                /* parent entry not found but not allowed to create it */
                                ERROR("in move_real_workdir, parent directory '%s' not found: %m", copy);
                                return -1;
-                       } else {
-                               /* parent entries to be created */
-                               l = len;
-                               for(;;) {
-                                       /* backward loop */
-                                       rc = mkdir(copy, mode);
-                                       if (!rc)
-                                               break;
-                                       if (errno != ENOENT) {
-                                               ERROR("in move_real_workdir, mkdir '%s' failed: %m", copy);
-                                               return -1;
-                                       }
-                                       while (l && copy[l] != '/')
-                                               l--;
-                                       if (l == 0) {
-                                               ERROR("in move_real_workdir, internal error");
-                                               errno = EINVAL;
-                                               return -1;
-                                       }
-                                       copy[l] = 0;
-                               }
-                               while(l < len) {
-                                       /* forward loop */
-                                       copy[l] = '/';
-                                       while (copy[++l]);
-                                       rc = mkdir(copy, mode);
-                                       if (rc && errno != EEXIST) {
-                                               ERROR("in move_real_workdir, mkdir '%s' failed: %m", copy);
-                                               return -1;
-                                       }
-                               }
+                       } else if (create_directory(copy, dirmode, 1)) {
+                               ERROR("in move_real_workdir, creation of directory %s failed: %m", copy);
+                               return -1;
                        }
                }
        }