+static char** session_dirs(void) {
+ const char *home, *e;
+ char *config_home = NULL, *data_home = NULL;
+ char **config_dirs = NULL, **data_dirs = NULL;
+ char **r = NULL, **t;
+
+ /* Implement the mechanisms defined in
+ *
+ * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
+ *
+ * We look in both the config and the data dirs because we
+ * want to encourage that distributors ship their unit files
+ * as data, and allow overriding as configuration.
+ */
+
+ home = getenv("HOME");
+
+ if ((e = getenv("XDG_CONFIG_HOME"))) {
+ if (asprintf(&config_home, "%s/systemd/session", e) < 0)
+ goto fail;
+
+ } else if (home) {
+ if (asprintf(&config_home, "%s/.config/systemd/session", home) < 0)
+ goto fail;
+ }
+
+ if ((e = getenv("XDG_CONFIG_DIRS")))
+ config_dirs = strv_split(e, ":");
+ else
+ config_dirs = strv_new("/etc/xdg", NULL);
+
+ if (!config_dirs)
+ goto fail;
+
+ if ((e = getenv("XDG_DATA_HOME"))) {
+ if (asprintf(&data_home, "%s/systemd/session", e) < 0)
+ goto fail;
+
+ } else if (home) {
+ if (asprintf(&data_home, "%s/.local/share/systemd/session", home) < 0)
+ goto fail;
+ }
+
+ if ((e = getenv("XDG_DATA_DIRS")))
+ data_dirs = strv_split(e, ":");
+ else
+ data_dirs = strv_new("/usr/local/share", "/usr/share", NULL);
+
+ if (!data_dirs)
+ goto fail;
+
+ /* Now merge everything we found. */
+ if (config_home) {
+ if (!(t = strv_append(r, config_home)))
+ goto fail;
+ strv_free(r);
+ r = t;
+ }
+
+ if (!(t = strv_merge_concat(r, config_dirs, "/systemd/session")))
+ goto finish;
+ strv_free(r);
+ r = t;
+
+ if (!(t = strv_append(r, SESSION_CONFIG_UNIT_PATH)))
+ goto fail;
+ strv_free(r);
+ r = t;
+
+ if (data_home) {
+ if (!(t = strv_append(r, data_home)))
+ goto fail;
+ strv_free(r);
+ r = t;
+ }
+
+ if (!(t = strv_merge_concat(r, data_dirs, "/systemd/session")))
+ goto fail;
+ strv_free(r);
+ r = t;
+
+ if (!(t = strv_append(r, SESSION_DATA_UNIT_PATH)))
+ goto fail;
+ strv_free(r);
+ r = t;
+
+ if (!strv_path_make_absolute_cwd(r))
+ goto fail;
+
+finish:
+ free(config_home);
+ strv_free(config_dirs);
+ free(data_home);
+ strv_free(data_dirs);
+
+ return r;
+
+fail:
+ strv_free(r);
+ r = NULL;
+ goto finish;
+}