Switch to use systemd database
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 16 Mar 2017 08:36:13 +0000 (09:36 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 17 Mar 2017 12:01:40 +0000 (13:01 +0100)
Installation now creates unit files.
This commits use these created unit files
to fill the application database of
afm-user-daemon.

Change-Id: Ice39d3ff51b6afe41609f3ce4ff0e89b2f3a0ca7
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
conf/afm-unit.conf
src/CMakeLists.txt
src/afm-udb.c [new file with mode: 0644]
src/afm-udb.h [new file with mode: 0644]
src/afm-user-daemon.c

index 86ab626..4cbfc87 100644 (file)
 ;
 ;             tells to install a link to unit in the wants of NAME
 ;
+; Setting variables:
+;
+;    AFM uses the feature of systemd that completely ignores options prefixed
+;    with X-
+;
+;    Consequently, options starting with X-AFM- are recorded as public data
+;    about the application and options starting starting with X-AFM-- are
+;    recorded as private data.
+;
+;    Examples:
+;
+;        X-AFM-description={{description}}
+;
+;              Records the descritpion of the unit in the field "description"
+;              of both the public and private object describing the unit.
+;
+;        X-AFM--wgtdir={{:#metadata.install-dir}}
+;
+;              Records the installation directory path in the field "wgtdir"
+;              of the private object only.
+;
 ;---------------------------------------------------------------------------------
 {{#targets}}
 %begin systemd-unit
 # auto generated by wgtpkg-unit for {{id}} version {{version}} target {{:#target}}
 %nl
 
-[unit]
+[Unit]
 Description={{description}}
-X-AGL-Name={{name.content}}
-X-AGL-Name-Short={{name.short}}
-X-AGL-Id={{id}}
-X-AGL-Idaver={{idaver}}
-X-AGL-Target-Name={{:#target}}
-X-AGL-Author={{author.content}}
-X-AGL-Author-email={{author.email}}
-X-AGL-HTTP-port={{:#metadata.http-port}}
+X-AFM-description={{description}}
+X-AFM-name={{name.content}}
+X-AFM-shortname={{name.short}}
+X-AFM-id={{idaver}}
+X-AFM-version={{version}}
+X-AFM-author={{author.content}}
+X-AFM-author-email={{author.email}}
+X-AFM-width={{width}}
+X-AFM-height={{height}}
+X-AFM--ID={{id}}
+X-AFM--target-name={{:#target}}
+X-AFM--content={{content.src}}
+X-AFM--type={{content.type}}
+X-AFM--wgtdir={{:#metadata.install-dir}}
+X-AFM--workdir={{&#metadata.app-data-dir}}/{{id}}
 %nl
 
 # Adds check to smack
@@ -92,7 +120,8 @@ SuccessExitStatus=0 SIGKILL
 {{/required-permission}}
 %nl
 
-WorkingDirectory={{&#metadata.app-data-dir}}
+WorkingDirectory=-{{&#metadata.app-data-dir}}/{{id}}
+ExecStartPre=/bin/mkdir -p {{&#metadata.app-data-dir}}/{{id}}
 Environment=AFM_APP_INSTALL_DIR={{:#metadata.install-dir}}
 
 
@@ -103,6 +132,7 @@ Environment=AFM_APP_INSTALL_DIR={{:#metadata.install-dir}}
 
 %systemd-unit service afm-appli-{{idaver}}{{^#target=main}}@{{:#target}}{{/#target=main}}
 
+X-AFM--http-port={{:#metadata.http-port}}
 ExecStart=/usr/bin/afb-daemon --port={{:#metadata.http-port}} --random-token \
        --rootdir={{:#metadata.install-dir}} \
        --workdir={{&#metadata.app-data-dir}}/{{id}} \
@@ -141,6 +171,7 @@ ExecStart=/usr/bin/afb-daemon --port={{:#metadata.http-port}} --random-token \
 
 %systemd-unit user
 %systemd-unit service afm-appli-{{idaver}}{{^#target=main}}@{{:#target}}{{/#target=main}}
+
 Environment=LD_LIBRARY_PATH=$ORIGIN/$LIB
 
 ExecStart={{:#metadata.install-dir}}/{{content.src}}
@@ -174,7 +205,7 @@ ExecStart=/usr/bin/afb-daemon \
 %systemd-unit user
 %systemd-unit socket afm-service-{{:#target}}
 
-[socket]
+[Socket]
 SmackLabel=*
 ListenStream=%t/bindings/{{:#target}}
 FileDescriptorName={{:#target}}
@@ -185,7 +216,7 @@ FileDescriptorName={{:#target}}
 
 ;---------------------------------------------------------------------------------
 {{#required-permission.urn:AGL:permission::system:run-by-default}}
-[install]
+[Install]
 WantedBy=default.target
 %systemd-unit wanted-by default.target
 {{/required-permission.urn:AGL:permission::system:run-by-default}}
index 41c2b1e..b4894b6 100644 (file)
@@ -119,6 +119,7 @@ add_library(secwrp STATIC
 
 add_library(afm STATIC
        afm-db.c
+       afm-udb.c
        afm-launch.c
        afm-launch-mode.c
        afm-run.c
diff --git a/src/afm-udb.c b/src/afm-udb.c
new file mode 100644 (file)
index 0000000..9b1a354
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ Copyright 2015, 2016, 2017 IoT.bzh
+
+ author: José Bollo <jose.bollo@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 <json-c/json.h>
+
+#include "utils-json.h"
+#include "utils-systemd.h"
+#include "utils-file.h"
+
+#include "afm-udb.h"
+
+
+static const char x_afm_prefix[] = "X-AFM-";
+static const char service_extension[] = ".service";
+static const char key_unit_path[] = "-unit-path";
+static const char key_unit_name[] = "-unit-name";
+static const char key_unit_scope[] = "-unit-scope";
+static const char scope_user[] = "user";
+static const char scope_system[] = "system";
+static const char key_id[] = "id";
+
+#define x_afm_prefix_length  (sizeof x_afm_prefix - 1)
+#define service_extension_length  (sizeof service_extension - 1)
+
+/*
+ * The structure afm_apps records the data about applications
+ * for several accesses.
+ */
+struct afm_apps {
+       struct json_object *prvarr; /* array of the private data of apps */
+       struct json_object *pubarr; /* array of the public data of apps */
+       struct json_object *pubobj; /* hash of application's publics */
+       struct json_object *prvobj; /* hash of application's privates */
+};
+
+/*
+ * The structure afm_udb records the applications
+ * for a set of directories recorded as a linked list
+ */
+struct afm_udb {
+       struct afm_apps applications;   /* the data about applications */
+       int refcount;                   /* count of references to the structure */
+       int system;                     /* is managing system units? */
+       int user;                       /* is managing user units? */
+       size_t prefixlen;               /* length of the prefix */
+       char prefix[1];                 /* filtering prefix */
+};
+
+/*
+ * The structure afm_updt is internally used for updates
+ */
+struct afm_updt {
+       struct afm_udb *afudb;
+       struct afm_apps applications;
+};
+
+/*
+ * Release the data of the afm_apps object 'apps'.
+ */
+static void apps_put(struct afm_apps *apps)
+{
+       json_object_put(apps->prvarr);
+       json_object_put(apps->pubarr);
+       json_object_put(apps->pubobj);
+       json_object_put(apps->prvobj);
+}
+
+/*
+ * Adds the field of 'name' and 'value' in 'priv' and also if possible in 'pub'
+ * Returns 0 on success or -1 on error.
+ */
+static int add_field(
+               struct json_object *priv,
+               struct json_object *pub,
+               const char *name,
+               const char *value
+)
+{
+       long int ival;
+       char *end;
+       struct json_object *v;
+
+       /* try to adapt the value to its type */
+       errno = 0;
+       ival = strtol(value, &end, 10);
+       if (*value && !*end && !errno) {
+               /* integer value */
+               v = json_object_new_int64(ival);
+       } else {
+               /* string value */
+               v = json_object_new_string(value);
+       }
+       if (!v) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       /* add the value */
+       if (name[0] == '-') {
+               json_object_object_add(priv, &name[1], v);
+       } else {
+               json_object_object_add(priv, name, json_object_get(v));
+               json_object_object_add(pub, name, v);
+       }
+       return 0;
+}
+
+/*
+ * Adds the field of 'name' and 'value' in 'priv' and also if possible in 'pub'
+ * Returns 0 on success or -1 on error.
+ */
+static int add_fields_of_content(
+               struct json_object *priv,
+               struct json_object *pub,
+               char *content,
+               size_t length
+)
+{
+       char *name, *value, *read, *write;
+
+       read = strstr(content, x_afm_prefix);
+       while (read) {
+               name = read + x_afm_prefix_length;
+               value = strchr(name, '=');
+               if (value == NULL)
+                       read = strstr(name, x_afm_prefix);
+               else {
+                       *value++ = 0;
+                       read = write = value;
+                       while(*read && *read != '\n') {
+                               if (read[0] != '\\')
+                                       *write++ = *read++;
+                               else {
+                                       switch(*++read) {
+                                       case 'n': *write++ = '\n'; break;
+                                       case '\n': *write++ = ' '; break;
+                                       default: *write++ = '\\'; *write++ = *read; break;
+                                       }
+                                       read += !!*read;
+                               }
+                       }
+                       read = strstr(read, x_afm_prefix);
+                       *write = 0;
+                       if (add_field(priv, pub, name, value) < 0)
+                               return -1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * Adds the application widget 'desc' of the directory 'path' to the
+ * afm_apps object 'apps'.
+ * Returns 0 in case of success.
+ * Returns -1 and set errno in case of error
+ */
+static int addunit(
+               struct afm_apps *apps,
+               int isuser,
+               const char *unitpath,
+               const char *unitname,
+               char *content,
+               size_t length
+)
+{
+       struct json_object *priv, *pub, *id;
+       const char *strid;
+
+       /* create the application structure */
+       priv = json_object_new_object();
+       if (!priv)
+               return -1;
+
+       pub = json_object_new_object();
+       if (!pub)
+               goto error;
+
+       /* adds the values */
+       if (add_fields_of_content(priv, pub, content, length)
+        || add_field(priv, pub, key_unit_path, unitpath)
+        || add_field(priv, pub, key_unit_name, unitname)
+        || add_field(priv, pub, key_unit_scope, isuser ? scope_user : scope_system))
+               goto error;
+
+       /* get the id */
+       if (!json_object_object_get_ex(pub, key_id, &id)) {
+               errno = EINVAL;
+               goto error;
+       }
+       strid = json_object_get_string(id);
+
+       /* record the application structure */
+       json_object_get(pub);
+       json_object_array_add(apps->pubarr, pub);
+       json_object_object_add(apps->pubobj, strid, pub);
+       json_object_get(priv);
+       json_object_array_add(apps->prvarr, priv);
+       json_object_object_add(apps->prvobj, strid, priv);
+       return 0;
+
+error:
+       json_object_put(pub);
+       json_object_put(priv);
+       return -1;
+}
+
+/*
+ * called for each unit
+ */
+static int update_cb(void *closure, const char *name, const char *path, int isuser)
+{
+       struct afm_updt *updt = closure;
+       char *content;
+       size_t length;
+       int rc;
+
+       /* prefix filtering */
+       length = updt->afudb->prefixlen;
+       if (length && strncmp(updt->afudb->prefix, name, length))
+               return 0;
+
+       /* only services */
+       length = strlen(name);
+       if (length < service_extension_length || strcmp(service_extension, name + length - service_extension_length))
+               return 0;
+
+       /* reads the file */
+       rc = getfile(path, &content, &length);
+       if (rc < 0)
+               return rc;
+
+       /* process the file */
+       rc = addunit(&updt->applications, isuser, path, name, content, length);
+       free(content);
+       return rc;
+}
+
+/*
+ * Creates an afm_udb object and returns it with one reference added.
+ * Return NULL with errno = ENOMEM if memory exhausted.
+ */
+struct afm_udb *afm_udb_create(int sys, int usr, const char *prefix)
+{
+       size_t length;
+       struct afm_udb *afudb;
+
+       length = prefix ? strlen(prefix) : 0;
+       afudb = malloc(length + sizeof * afudb);
+       if (afudb == NULL)
+               errno = ENOMEM;
+       else {
+               afudb->refcount = 1;
+               afudb->applications.prvarr = NULL;
+               afudb->applications.pubarr = NULL;
+               afudb->applications.pubobj = NULL;
+               afudb->applications.prvobj = NULL;
+               afudb->system = sys;
+               afudb->user = usr;
+               afudb->prefixlen = length;
+               if (length)
+                       memcpy(afudb->prefix, prefix, length);
+               afudb->prefix[length] = 0;
+               if (afm_udb_update(afudb) < 0) {
+                       afm_udb_unref(afudb);
+                       afudb = NULL;
+               }
+       }
+       return afudb;
+}
+
+/*
+ * Adds a reference to an existing afm_udb.
+ */
+void afm_udb_addref(struct afm_udb *afudb)
+{
+       assert(afudb);
+       afudb->refcount++;
+}
+
+/*
+ * Removes a reference to an existing afm_udb object.
+ * Removes the objet if there no more reference to it.
+ */
+void afm_udb_unref(struct afm_udb *afudb)
+{
+       assert(afudb);
+       if (!--afudb->refcount) {
+               /* no more reference, clean the memory used by the object */
+               apps_put(&afudb->applications);
+               free(afudb);
+       }
+}
+
+/*
+ * Regenerate the list of applications of the afm_bd object 'afudb'.
+ * Returns 0 in case of success.
+ * Returns -1 and set errno in case of error
+ */
+int afm_udb_update(struct afm_udb *afudb)
+{
+       struct afm_updt updt;
+       struct afm_apps tmp;
+
+       /* lock the db */
+       afm_udb_addref(afudb);
+       updt.afudb = afudb;
+
+       /* create the result */
+       updt.applications.prvarr = json_object_new_array();
+       updt.applications.pubarr = json_object_new_array();
+       updt.applications.pubobj = json_object_new_object();
+       updt.applications.prvobj = json_object_new_object();
+       if (updt.applications.pubarr == NULL
+        || updt.applications.prvarr == NULL
+        || updt.applications.pubobj == NULL
+        || updt.applications.prvobj == NULL) {
+               errno = ENOMEM;
+               goto error;
+       }
+
+       /* scan the units */
+       if (afudb->user)
+               if (systemd_unit_list(1, update_cb, &updt) < 0)
+                       goto error;
+       if (afudb->system)
+               if (systemd_unit_list(0, update_cb, &updt) < 0)
+                       goto error;
+
+       /* commit the result */
+       tmp = afudb->applications;
+       afudb->applications = updt.applications;
+       apps_put(&tmp);
+       afm_udb_addref(afudb);
+       return 0;
+
+error:
+       apps_put(&updt.applications);
+       afm_udb_addref(afudb);
+       return -1;
+}
+
+/*
+ * Get the list of the applications private data of the afm_udb object 'afudb'.
+ * The list is returned as a JSON-array that must be released using
+ * 'json_object_put'.
+ * Returns NULL in case of error.
+ */
+struct json_object *afm_udb_applications_private(struct afm_udb *afudb)
+{
+       return json_object_get(afudb->applications.prvarr);
+}
+
+/*
+ * Get the list of the applications public data of the afm_udb object 'afudb'.
+ * The list is returned as a JSON-array that must be released using
+ * 'json_object_put'.
+ * Returns NULL in case of error.
+ */
+struct json_object *afm_udb_applications_public(struct afm_udb *afudb)
+{
+       return json_object_get(afudb->applications.pubarr);
+}
+
+/*
+ * Get the private data of the applications of 'id' in the afm_udb object 'afudb'.
+ * It returns a JSON-object that must be released using 'json_object_put'.
+ * Returns NULL in case of error.
+ */
+static struct json_object *get_no_case(struct json_object *object, const char *id)
+{
+       struct json_object *result;
+       struct json_object_iter i;
+
+       /* search case sensitively */
+       if (json_object_object_get_ex(object, id, &result))
+               return json_object_get(result);
+
+       /* fallback to a case insensitive search */
+       json_object_object_foreachC(object, i) {
+               if (!strcasecmp(i.key, id))
+                       return json_object_get(i.val);
+       }
+       return NULL;
+}
+
+/*
+ * Get the private data of the applications of 'id' in the afm_udb object 'afudb'.
+ * It returns a JSON-object that must be released using 'json_object_put'.
+ * Returns NULL in case of error.
+ */
+struct json_object *afm_udb_get_application_private(struct afm_udb *afudb, const char *id)
+{
+       return get_no_case(afudb->applications.prvobj, id);
+}
+
+/*
+ * Get the public data of the applications of 'id' in the afm_udb object 'afudb'.
+ * It returns a JSON-object that must be released using 'json_object_put'.
+ * Returns NULL in case of error.
+ */
+struct json_object *afm_udb_get_application_public(struct afm_udb *afudb,
+                                                       const char *id)
+{
+       return get_no_case(afudb->applications.pubobj, id);
+}
+
+
+
+#if defined(TESTAPPFWK)
+#include <stdio.h>
+int main()
+{
+struct afm_udb *afudb = afm_udb_create(1, 1, NULL);
+printf("array = %s\n", json_object_to_json_string_ext(afudb->applications.pubarr, 3));
+printf("pubobj = %s\n", json_object_to_json_string_ext(afudb->applications.pubobj, 3));
+printf("prvobj = %s\n", json_object_to_json_string_ext(afudb->applications.prvobj, 3));
+return 0;
+}
+#endif
+
diff --git a/src/afm-udb.h b/src/afm-udb.h
new file mode 100644 (file)
index 0000000..672a311
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ Copyright 2015, 2016, 2017 IoT.bzh
+
+ author: José Bollo <jose.bollo@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.
+*/
+
+struct afm_udb;
+struct json_object;
+
+extern struct afm_udb *afm_udb_create(int sys, int usr, const char *prefix);
+extern void afm_udb_addref(struct afm_udb *afdb);
+extern void afm_udb_unref(struct afm_udb *afdb);
+extern int afm_udb_update(struct afm_udb *afdb);
+extern struct json_object *afm_udb_applications_private(struct afm_udb *afdb);
+extern struct json_object *afm_udb_applications_public(struct afm_udb *afdb);
+extern struct json_object *afm_udb_get_application_private(struct afm_udb *afdb, const char *id);
+extern struct json_object *afm_udb_get_application_public(struct afm_udb *afdb, const char *id);
+
index a180be6..7c7824d 100644 (file)
 #include "utils-jbus.h"
 #include "utils-json.h"
 #include "afm.h"
-#include "afm-db.h"
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
+# include "afm-db.h"
+#else
+# include "afm-udb.h"
+#endif
 #include "afm-launch-mode.h"
 #include "afm-run.h"
 
@@ -43,11 +47,16 @@ static const char appname[] = "afm-user-daemon";
  * string for printing usage
  */
 static const char usagestr[] =
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        "usage: %s [-q] [-v] [-m mode] [-r rootdir]... [-a appdir]...\n"
        "\n"
        "   -a appdir    adds an application directory\n"
        "   -r rootdir   adds a root directory of applications\n"
        "   -m mode      set default launch mode (local or remote)\n"
+#else
+       "usage: %s [option(s)]\n"
+       "\n"
+#endif
        "   -d           run as a daemon\n"
        "   -u addr      address of user D-Bus to use\n"
        "   -s addr      address of system D-Bus to use\n"
@@ -58,11 +67,16 @@ static const char usagestr[] =
 /*
  * Option definition for getopt_long
  */
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
 static const char options_s[] = "hdqvr:a:m:";
 static struct option options_l[] = {
        { "root",        required_argument, NULL, 'r' },
        { "application", required_argument, NULL, 'a' },
        { "mode",        required_argument, NULL, 'm' },
+#else
+static const char options_s[] = "hdqv";
+static struct option options_l[] = {
+#endif
        { "user-dbus",   required_argument, NULL, 'u' },
        { "system-dbus", required_argument, NULL, 's' },
        { "daemon",      no_argument,       NULL, 'd' },
@@ -85,7 +99,11 @@ static struct jbus *jbuses[2];
 /*
  * Handle to the database of applications
  */
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
 static struct afm_db *afdb;
+#else
+static struct afm_udb *afudb;
+#endif
 
 /*
  * Returned error strings
@@ -154,7 +172,11 @@ static void on_runnables(struct sd_bus_message *smsg, struct json_object *obj, v
 {
        struct json_object *resp;
        INFO("method runnables called");
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        resp = afm_db_application_list(afdb);
+#else
+       resp = afm_udb_applications_public(afudb);
+#endif
        jbus_reply_j(smsg, resp);
        json_object_put(resp);
 }
@@ -180,7 +202,11 @@ static void on_detail(struct sd_bus_message *smsg, struct json_object *obj, void
 
        /* wants details for appid */
        INFO("method detail called for %s", appid);
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        resp = afm_db_get_application_public(afdb, appid);
+#else
+       resp = afm_udb_get_application_public(afudb, appid);
+#endif
        reply(smsg, resp, error_not_found);
        json_object_put(resp);
 }
@@ -216,7 +242,11 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void
        /* get the application */
        INFO("method start called for %s mode=%s", appid,
                                                name_of_launch_mode(mode));
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        appli = afm_db_get_application(afdb, appid);
+#else
+       appli = afm_udb_get_application_private(afudb, appid);
+#endif
        if (appli == NULL) {
                jbus_reply_error_s(smsg, error_not_found);
                return;
@@ -269,7 +299,11 @@ static void on_once(struct sd_bus_message *smsg, struct json_object *obj, void *
 
        /* get the application */
        INFO("method once called for %s", appid);
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        appli = afm_db_get_application(afdb, appid);
+#else
+       appli = afm_udb_get_application_private(afudb, appid);
+#endif
        if (appli == NULL) {
                jbus_reply_error_s(smsg, error_not_found);
                return;
@@ -417,7 +451,11 @@ static void on_uninstall(struct sd_bus_message *smsg, const char *msg, void *unu
 static void on_signal_changed(struct json_object *obj, void *unused)
 {
        /* update the database */
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        afm_db_update_applications(afdb);
+#else
+       afm_udb_update(afudb);
+#endif
        /* re-propagate now */
        jbus_send_signal_j(user_bus, "changed", obj);
 }
@@ -481,7 +519,9 @@ fail:
 int main(int ac, char **av)
 {
        int i, daemon = 0, rc;
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        enum afm_launch_mode mode;
+#endif
        struct sd_event *evloop;
        struct sd_bus *sysbus, *usrbus;
        const char *sys_bus_addr, *usr_bus_addr;
@@ -506,6 +546,7 @@ int main(int ac, char **av)
                case 'd':
                        daemon = 1;
                        break;
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
                case 'r':
                        break;
                case 'a':
@@ -518,6 +559,7 @@ int main(int ac, char **av)
                        }
                        set_default_launch_mode(mode);
                        break;
+#endif
                case 'u':
                        usr_bus_addr = optarg;
                        break;
@@ -543,9 +585,10 @@ int main(int ac, char **av)
        }
 
        /* init framework */
+#ifdef LEGACY_MODE_WITHOUT_SYSTEMD
        afdb = afm_db_create();
        if (!afdb) {
-               ERROR("afm_create failed");
+               ERROR("afm_db_create failed");
                return 1;
        }
        if (afm_db_add_root(afdb, FWK_APP_DIR)) {
@@ -577,6 +620,13 @@ int main(int ac, char **av)
                ERROR("afm_update_applications failed");
                return 1;
        }
+#else
+       afudb = afm_udb_create(0, 1, "afm-appli-");
+       if (!afudb) {
+               ERROR("afm_udb_create failed");
+               return 1;
+       }
+#endif
 
        /* daemonize if requested */
        if (daemon && daemonize()) {