diff options
Diffstat (limited to 'src/appfwk.c')
-rw-r--r-- | src/appfwk.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/appfwk.c b/src/appfwk.c new file mode 100644 index 0000000..6dc7182 --- /dev/null +++ b/src/appfwk.c @@ -0,0 +1,224 @@ +/* + Copyright 2015 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 <stdlib.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> + +#include <wgt.h> + +struct stringset { + int count; + char **strings; +}; + + +struct appfwk { + int refcount; + struct stringset paths; +}; + +struct appfwk *appfwk_create() +{ + struct appfwk *appfwk = malloc(sizeof * appfwk); + if (!appfwk) + errno = ENOMEM; + else { + appfwk->refcount = 1; + appfwk->paths.count = 0; + appfwk->paths.strings = NULL; + } + return appfwk; +} + +void appfwk_addref(struct appfwk *appfwk) +{ + assert(appfwk); + appfwk->refcount++; +} + +void appfwk_unref(struct appfwk *appfwk) +{ + assert(appfwk); + if (!--appfwk->refcount) { + while (appfwk->paths.count) + free(appfwk->paths.strings[--appfwk->paths.count]); + free(appfwk); + } +} + +int appfwk_add_root(struct appfwk *appfwk, const char *path) +{ + int i, n; + char *r, **roots; + assert(appfwk); + r = realpath(path, NULL); + if (!r) + return -1; + + /* avoiding duplications */ + n = appfwk->paths.count; + roots = appfwk->paths.strings; + for (i = 0 ; i < n ; i++) + if (!strcmp(r, roots[i])) { + free(r); + return 0; + } + + /* add */ + roots = realloc(roots, (n + 1) * sizeof(roots[0])); + if (!roots) { + free(r); + errno = ENOMEM; + return -1; + } + roots[n++] = r; + appfwk->paths.strings = roots; + appfwk->paths.count = n; + return 0; +} + +struct aea { + char *path; + char *appver; + char *ver; + const char *root; + const char *appid; + const char *version; + int (*callback)(struct wgt *wgt, void *data); + void *data; +}; + +struct appfwk_enumerate_applications_context { + const char *dirpath; + const char *appid; + const char *version; + + void *data; +}; + +inline int testd(int dirfd, struct dirent *e) +{ + return e->d_name[0] != '.' || (e->d_name[1] && (e->d_name[1] != '.' || e->d_name[2])); +} + +#include <stdio.h> +static int aea3(int dirfd, struct aea *aea) +{ + printf("aea3 %s *** %s *** %s\n", aea->path, aea->appver, aea->ver); + return 0; +} + +static int aea2(int dirfd, struct aea *aea) +{ + DIR *dir; + int rc, fd; + struct dirent entry, *e; + + dir = fdopendir(dirfd); + if (!dir) + return -1; + + aea->version = entry.d_name; + + rc = readdir_r(dir, &entry, &e); + while (!rc && e) { + if (testd(dirfd, &entry)) { + fd = openat(dirfd, entry.d_name, O_DIRECTORY|O_RDONLY); + if (fd >= 0) { + strcpy(aea->ver, entry.d_name); + rc = aea3(fd, aea); + close(fd); + } + } + rc = readdir_r(dir, &entry, &e); + } + closedir(dir); + return rc; +} + +static int aea1(int dirfd, struct aea *aea) +{ + DIR *dir; + int rc, fd; + struct dirent entry, *e; + + dir = fdopendir(dirfd); + if (!dir) + return -1; + + aea->appid = entry.d_name; + + rc = readdir_r(dir, &entry, &e); + while (!rc && e) { + if (testd(dirfd, &entry)) { + fd = openat(dirfd, entry.d_name, O_DIRECTORY|O_RDONLY); + if (fd >= 0) { + aea->ver = stpcpy(aea->appver, entry.d_name); + *aea->ver++ = '/'; + rc = aea2(fd, aea); + close(fd); + } + } + rc = readdir_r(dir, &entry, &e); + } + closedir(dir); + return rc; +} + +int appfwk_enumerate_applications(struct appfwk *appfwk, int (*callback)(struct wgt *wgt, void *data), void *data) +{ + int rc, iroot, nroots; + char **roots; + int fd; + char buffer[PATH_MAX]; + struct aea aea; + + aea.callback = callback; + aea.data = data; + aea.path = buffer; + + nroots = appfwk->paths.count; + roots = appfwk->paths.strings; + for (iroot = 0 ; iroot < nroots ; iroot++) { + aea.root = roots[iroot]; + fd = openat(AT_FDCWD, aea.root, O_DIRECTORY|O_RDONLY); + if (fd >= 0) { + aea.appver = stpcpy(buffer, aea.root); + *aea.appver++ = '/'; + rc = aea1(fd, &aea); + close(fd); + } + } + return 0; +} +/* + struct wgt *wgt; + wgt = wgt_create(); + if (!wgt) + return -1; + wgt_unref(wgt); + + rfd = AT_FDCWD; + if (pathname) { + rfd = openat(rfd, pathname, O_PATH|O_DIRECTORY); +*/ + |