From 6c6177fcf8fdcc62c42a18407e95c7577897e10c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Tue, 15 Dec 2015 11:20:08 +0100 Subject: [PATCH] in progress Change-Id: Ida682c87abc3413e0e84c56f60d54e1c5409fd3a --- .gitignore | 4 +- configure.ac | 1 + src/Makefile.am | 58 ++++++++++----- src/appfwk.c | 187 +++++++++++++++++++++++++++++++++---------------- src/wgtpkg-install.c | 5 +- src/wgtpkg-installer.c | 15 +--- src/wgtpkg-workdir.c | 121 +++----------------------------- 7 files changed, 186 insertions(+), 205 deletions(-) diff --git a/.gitignore b/.gitignore index 96295c2..cee9cf3 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ diff --git a/configure.ac b/configure.ac index 04f21ce..adee3da 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/Makefile.am b/src/Makefile.am index 0826e12..3465049 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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} + diff --git a/src/appfwk.c b/src/appfwk.c index c6a874e..0ede96a 100644 --- a/src/appfwk.c +++ b/src/appfwk.c @@ -27,11 +27,17 @@ #include +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 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; } diff --git a/src/wgtpkg-install.c b/src/wgtpkg-install.c index 6a4a865..096903b 100644 --- a/src/wgtpkg-install.c +++ b/src/wgtpkg-install.c @@ -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; diff --git a/src/wgtpkg-installer.c b/src/wgtpkg-installer.c index 62807aa..3d9c237 100644 --- a/src/wgtpkg-installer.c +++ b/src/wgtpkg-installer.c @@ -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); diff --git a/src/wgtpkg-workdir.c b/src/wgtpkg-workdir.c index 7f2c7e6..1b8684c 100644 --- a/src/wgtpkg-workdir.c +++ b/src/wgtpkg-workdir.c @@ -28,92 +28,17 @@ #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; } } } -- 2.16.6