From e2f138ca6b0f61d1a1cde1fd305dd7f0aaf4aa0e Mon Sep 17 00:00:00 2001 From: José Bollo Date: Tue, 22 Dec 2015 11:45:02 +0100 Subject: allows to add directories Change-Id: I574a09d4ce3dcfe84e4744ea8f0ae4abf1277a1d --- src/af-db.c | 103 ++++++++++++++++++++++++++++++++++---------------- src/af-db.h | 1 + src/afm-user-daemon.c | 89 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 158 insertions(+), 35 deletions(-) diff --git a/src/af-db.c b/src/af-db.c index 1977402..473b118 100644 --- a/src/af-db.c +++ b/src/af-db.c @@ -36,10 +36,21 @@ struct afapps { struct json_object *byapp; }; +enum dir_type { + type_root, + type_app +}; + +struct af_db_dir { + struct af_db_dir *next; + char *path; + enum dir_type type; +}; + struct af_db { int refcount; - int nrroots; - char **roots; + struct af_db_dir *dirhead; + struct af_db_dir *dirtail; struct afapps applications; }; @@ -50,8 +61,8 @@ struct af_db *af_db_create() errno = ENOMEM; else { afdb->refcount = 1; - afdb->nrroots = 0; - afdb->roots = NULL; + afdb->dirhead = NULL; + afdb->dirtail = NULL; afdb->applications.pubarr = NULL; afdb->applications.direct = NULL; afdb->applications.byapp = NULL; @@ -67,22 +78,26 @@ void af_db_addref(struct af_db *afdb) void af_db_unref(struct af_db *afdb) { + struct af_db_dir *dir; assert(afdb); if (!--afdb->refcount) { json_object_put(afdb->applications.pubarr); json_object_put(afdb->applications.direct); json_object_put(afdb->applications.byapp); - while (afdb->nrroots) - free(afdb->roots[--afdb->nrroots]); - free(afdb->roots); + while (afdb->dirhead != NULL) { + dir = afdb->dirhead; + afdb->dirhead = dir->next; + free(dir->path); + free(dir); + } free(afdb); } } -int af_db_add_root(struct af_db *afdb, const char *path) +int add_dir(struct af_db *afdb, const char *path, enum dir_type type) { - int i, n; - char *r, **roots; + struct af_db_dir *dir; + char *r; assert(afdb); @@ -92,28 +107,44 @@ int af_db_add_root(struct af_db *afdb, const char *path) return -1; /* avoiding duplications */ - n = afdb->nrroots; - roots = afdb->roots; - for (i = 0 ; i < n ; i++) { - if (!strcmp(r, roots[i])) { - free(r); - return 0; - } + dir = afdb->dirhead; + while(dir != NULL && (strcmp(dir->path, path) || dir->type != type)) + dir = dir ->next; + if (dir != NULL) { + free(r); + return 0; } - /* add */ - roots = realloc(roots, (n + 1) * sizeof(roots[0])); - if (!roots) { + /* allocates the structure */ + dir = malloc(sizeof * dir); + if (dir == NULL) { free(r); errno = ENOMEM; return -1; } - roots[n++] = r; - afdb->roots = roots; - afdb->nrroots = n; + + /* add */ + dir->next = NULL; + dir->path = r; + dir->type = type; + if (afdb->dirtail == NULL) + afdb->dirhead = dir; + else + afdb->dirtail->next = dir; + afdb->dirtail = dir; return 0; } +int af_db_add_root(struct af_db *afdb, const char *path) +{ + return add_dir(afdb, path, type_root); +} + +int af_db_add_application(struct af_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); @@ -142,8 +173,11 @@ static int addapp(struct afapps *apps, const char *path) /* connect to the widget */ info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0); - if (info == NULL) + if (info == NULL) { + if (errno == ENOENT) + return 0; /* silently ignore bad directories */ goto error; + } desc = wgt_info_desc(info); /* create the application id */ @@ -292,9 +326,10 @@ static int enumvers(struct enumdata *data) /* regenerate the list of applications */ int af_db_update_applications(struct af_db *afdb) { - int rc, iroot; + int rc; struct enumdata edata; struct afapps oldapps; + struct af_db_dir *dir; /* create the result */ edata.apps.pubarr = json_object_new_array(); @@ -305,13 +340,17 @@ int af_db_update_applications(struct af_db *afdb) goto error; } /* for each root */ - for (iroot = 0 ; iroot < afdb->nrroots ; iroot++) { - edata.length = stpcpy(edata.path, afdb->roots[iroot]) - edata.path; - assert(edata.length < sizeof edata.path); - /* enumerate the applications */ - rc = enumentries(&edata, enumvers); - if (rc) - goto error; + for (dir = afdb->dirhead ; dir != NULL ; dir = dir->next) { + if (dir->type == type_root) { + edata.length = stpcpy(edata.path, dir->path) - edata.path; + assert(edata.length < sizeof edata.path); + /* enumerate the applications */ + rc = enumentries(&edata, enumvers); + if (rc) + goto error; + } else { + rc = addapp(&edata.apps, dir->path); + } } /* commit the result */ oldapps = afdb->applications; diff --git a/src/af-db.h b/src/af-db.h index b0002be..ce4d04f 100644 --- a/src/af-db.h +++ b/src/af-db.h @@ -23,6 +23,7 @@ extern void af_db_addref(struct af_db *afdb); extern void af_db_unref(struct af_db *afdb); extern int af_db_add_root(struct af_db *afdb, const char *path); +extern int af_db_add_application(struct af_db *afdb, const char *path); extern int af_db_update_applications(struct af_db *afdb); extern int af_db_ensure_applications(struct af_db *afdb); diff --git a/src/afm-user-daemon.c b/src/afm-user-daemon.c index 4990ff7..346c58b 100644 --- a/src/afm-user-daemon.c +++ b/src/afm-user-daemon.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -27,6 +28,33 @@ #include "af-db.h" #include "af-run.h" +static const char appname[] = "afm-user-daemon"; + +static void usage() +{ + printf( + "usage: %s [-q] [-v] [-r rootdir]... [-a appdir]...\n" + "\n" + " -a appdir adds an application directory\n" + " -r rootdir adds a root directory of applications\n" + " -d run as a daemon\n" + " -q quiet\n" + " -v verbose\n" + "\n", + appname + ); +} + +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' }, + { "help", no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } +}; + static struct jbus *jbus; static struct af_db *afdb; @@ -157,7 +185,38 @@ static int daemonize() int main(int ac, char **av) { - LOGAUTH("afm-main-daemon"); + int i, daemon = 0; + + LOGAUTH(appname); + + /* first interpretation of arguments */ + while ((i = getopt_long(ac, av, "hdqvr:a:", options, NULL)) >= 0) { + switch (i) { + case 'h': + usage(); + return 0; + case 'q': + if (verbosity) + verbosity--; + break; + case 'v': + verbosity++; + break; + case 'd': + daemon = 1; + break; + case 'r': + break; + case 'a': + break; + case ':': + ERROR("missing argument value"); + return 1; + default: + ERROR("unrecognized option"); + return 1; + } + } /* init random generator */ srandom((unsigned int)time(NULL)); @@ -178,11 +237,37 @@ int main(int ac, char **av) 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 (af_db_add_root(afdb, optarg)) { + ERROR("can't add root %s", optarg); + return 1; + } + break; + case 'a': + if (af_db_add_application(afdb, optarg)) { + ERROR("can't add application %s", optarg); + return 1; + } + break; + } + } + + /* update the database */ if (af_db_update_applications(afdb)) { ERROR("af_update_applications failed"); return 1; } + if (daemon && daemonize()) { + ERROR("daemonization failed"); + return 1; + } + /* init service */ jbus = create_jbus(1, "/org/AGL/afmMain"); if (!jbus) { @@ -210,5 +295,3 @@ int main(int ac, char **av) return 0; } - - -- cgit 1.2.3-korg