summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2015-01-27 20:59:16 +0000
committerAlexander Larsson <alexl@redhat.com>2015-01-28 20:03:13 +0100
commitfca4a162093f1389c51a078cda440938c83f6b6a (patch)
treecc89c8625fc016cde6bc9da1ed192db1b535fd63
parent8fdc60ed7a4b5bdda3d5f68ace830467dffeaf56 (diff)
downloadxdg-app-fca4a162093f1389c51a078cda440938c83f6b6a.tar.gz
Add xdg-app-session-helper
This is a small app that makes copies of various system files to a directory in /run so that the app sandbox can receive updates to these. This solves the issue that we can't generally bind-mount say /etc/resolv.conf, because it will be replaced with rename-over.
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am48
-rw-r--r--configure.ac18
-rw-r--r--xdg-app-dbus-interfaces.xml34
-rw-r--r--xdg-app-session-helper.c174
-rw-r--r--xdg-app-session.service.in3
-rw-r--r--xdg-app.gresource.xml6
7 files changed, 285 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index a932aa7..989eafa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,4 +26,9 @@ config.h.in
stamp-*
xdg-app
xdg-app-helper
+xdg-app-session-helper
doc/*.1
+*~
+xdg-app-dbus.[ch]
+xdg-app-resources.c
+*.service
diff --git a/Makefile.am b/Makefile.am
index 6226f8b..c2e80a0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,8 +23,51 @@ bin_PROGRAMS = \
xdg-app \
$(NULL)
+libexec_PROGRAMS = \
+ xdg-app-session-helper \
+ $(NULL)
+
xdg_app_helper_SOURCES = xdg-app-helper.c
+dbus_built_sources = xdg-app-dbus.c xdg-app-dbus.h
+BUILT_SOURCES = $(dbus_built_sources)
+
+$(dbus_built_sources) : Makefile.am xdg-app-dbus-interfaces.xml
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --interface-prefix org.freedesktop.XdgApp. \
+ --c-namespace XdgApp \
+ --generate-c-code xdg-app-dbus \
+ $(srcdir)/xdg-app-dbus-interfaces.xml \
+ $(NULL)
+
+resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/xdg-app.gresource.xml)
+
+xdg-app-resources.h: xdg-app.gresource.xml
+ $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< \
+ --target=$@ --sourcedir=$(srcdir) --c-name _gtk --generate-header
+
+xdg-app-resources.c: xdg-app.gresource.xml $(resource_files)
+ $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< \
+ --target=$@ --sourcedir=$(srcdir) --c-name _gtk --generate-source
+
+# D-BUS service file
+%.service: %.service.in config.log
+ $(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+servicedir = $(DBUS_SERVICE_DIR)
+service_in_files = xdg-app-session.service.in
+service_DATA = xdg-app-session.service
+
+xdg_app_session_helper_SOURCES = \
+ xdg-app-session-helper.c \
+ $(dbus_built_sources) \
+ xdg-app-resources.h \
+ xdg-app-resources.c \
+ $(NULL)
+
+xdg_app_session_helper_LDADD = $(BASE_LIBS)
+xdg_app_session_helper_CFLAGS = $(BASE_CFLAGS)
+
xdg_app_SOURCES = \
xdg-app-main.c \
xdg-app-builtins.h \
@@ -47,8 +90,9 @@ xdg_app_SOURCES = \
xdg-app-utils.h \
xdg-app-utils.c \
$(NULL)
-xdg_app_LDADD = $(OSTREE_LIBS) $(SOUP_LIBS)
-xdg_app_CFLAGS = $(OSTREE_CFLAGS) $(SOUP_CFLAGS)
+
+xdg_app_LDADD = $(BASE_LIBS) $(OSTREE_LIBS) $(SOUP_LIBS)
+xdg_app_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS)
install-exec-hook:
$(SUDO_BIN) chown root $(DESTDIR)$(bindir)/xdg-app-helper
diff --git a/configure.ac b/configure.ac
index c376dc5..fa5a981 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,6 +13,7 @@ AC_CONFIG_SRCDIR([xdg-app-helper.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11 no-define no-dist-gzip dist-bzip2 tar-ustar foreign])
+AC_PROG_SED
# Enable silent rules is available
AM_SILENT_RULES([yes])
@@ -25,10 +26,25 @@ if test "x$GCC" = "xyes"; then
esac
fi
+PKG_PROG_PKG_CONFIG([0.24])
+
+AC_ARG_WITH(dbus_service_dir,
+ AS_HELP_STRING([--with-dbus-service-dir=PATH],[choose directory for dbus service files, [default=PREFIX/share/dbus-1/services]]),
+ with_dbus_service_dir="$withval", with_dbus_service_dir=$datadir/dbus-1/services)
+DBUS_SERVICE_DIR=$with_dbus_service_dir
+AC_SUBST(DBUS_SERVICE_DIR)
+
+
+AC_SUBST([GLIB_COMPILE_RESOURCES], [`$PKG_CONFIG --variable glib_compile_resources gio-2.0`])
+AC_SUBST([GDBUS_CODEGEN], [`$PKG_CONFIG --variable gdbus_codegen gio-2.0`])
+
+PKG_CHECK_MODULES(BASE, [glib-2.0 gio-2.0 gio-unix-2.0])
+AC_SUBST(BASE_CFLAGS)
+AC_SUBST(BASE_LIBS)
PKG_CHECK_MODULES(SOUP, [libsoup-2.4])
AC_SUBST(SOUP_CFLAGS)
AC_SUBST(SOUP_LIBS)
-PKG_CHECK_MODULES(OSTREE, [glib-2.0 libgsystem >= 2015.1 gio-2.0 ostree-1 >= 2015.1])
+PKG_CHECK_MODULES(OSTREE, [libgsystem >= 2015.1 ostree-1 >= 2015.1])
AC_SUBST(OSTREE_CFLAGS)
AC_SUBST(OSTREE_LIBS)
diff --git a/xdg-app-dbus-interfaces.xml b/xdg-app-dbus-interfaces.xml
new file mode 100644
index 0000000..bfa558f
--- /dev/null
+++ b/xdg-app-dbus-interfaces.xml
@@ -0,0 +1,34 @@
+<!DOCTYPE node PUBLIC
+"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<!--
+ Copyright (C) 2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ Author: Alexander Larsson <alexl@redhat.com>
+-->
+
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+ <interface name='org.freedesktop.XdgApp.SessionHelper'>
+
+ <method name="RequestMonitor">
+ <arg type='ay' name='path' direction='out'/>
+ </method>
+ </interface>
+</node>
+
diff --git a/xdg-app-session-helper.c b/xdg-app-session-helper.c
new file mode 100644
index 0000000..46ff806
--- /dev/null
+++ b/xdg-app-session-helper.c
@@ -0,0 +1,174 @@
+#include "config.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gio/gio.h>
+#include "xdg-app-dbus.h"
+
+static GDBusNodeInfo *introspection_data = NULL;
+static char *monitor_dir;
+
+static gboolean
+handle_request_monitor (XdgAppSessionHelper *object,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ xdg_app_session_helper_complete_request_monitor (object, invocation,
+ monitor_dir);
+
+ return TRUE;
+}
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ XdgAppSessionHelper *helper;
+ GError *error = NULL;
+
+ helper = xdg_app_session_helper_skeleton_new ();
+
+ g_signal_connect (helper, "handle-request-monitor", G_CALLBACK (handle_request_monitor), NULL);
+
+ if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (helper),
+ connection,
+ "/org/freedesktop/XdgApp/SessionHelper",
+ &error))
+ {
+ g_warning ("error: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ exit (1);
+}
+
+static void
+copy_file (const char *source,
+ const char *target_dir)
+{
+ char *basename = g_path_get_basename (source);
+ char *dest = g_build_filename (target_dir, basename, NULL);
+ gchar *contents = NULL;
+ gsize len;
+
+ if (g_file_test (source, G_FILE_TEST_IS_SYMLINK))
+ {
+ contents = g_file_read_link (source, NULL);
+ if (contents)
+ {
+ unlink (dest);
+
+ if (strcmp (source, "/etc/localtime") == 0)
+ {
+ char *zoneinfo = g_strrstr (contents, "zoneinfo/");
+ char *new_contents;
+
+ if (zoneinfo)
+ {
+ new_contents = g_build_filename ("/usr/share/zoneinfo", zoneinfo + strlen ("zoneinfo/"), NULL);
+ g_free (contents);
+ contents = new_contents;
+ }
+ }
+
+ symlink (contents, dest);
+ }
+ }
+ else
+ {
+ if (g_file_get_contents (source, &contents, &len, NULL))
+ {
+ g_file_set_contents (dest, contents, len, NULL);
+ }
+ }
+
+ g_free (basename);
+ g_free (dest);
+ g_free (contents);
+}
+
+static void
+file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ char *source)
+{
+ if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT ||
+ event_type == G_FILE_MONITOR_EVENT_CREATED)
+ copy_file (source, monitor_dir);
+}
+
+static void
+setup_file_monitor (const char *source)
+{
+ GFile *s = g_file_new_for_path (source);
+ GFileMonitor *monitor;
+
+ copy_file (source, monitor_dir);
+
+ monitor = g_file_monitor_file (s, G_FILE_MONITOR_NONE, NULL, NULL);
+ if (monitor)
+ g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), (char *)source);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ guint owner_id;
+ GMainLoop *loop;
+ GBytes *introspection_bytes;
+
+ setlocale (LC_ALL, "");
+
+ g_set_prgname (argv[0]);
+
+ monitor_dir = g_build_filename (g_get_user_runtime_dir (), "xdg-app-monitor", NULL);
+ if (g_mkdir_with_parents (monitor_dir, 0755) != 0)
+ {
+ g_print ("Can't create %s\n", monitor_dir);
+ exit (1);
+ }
+
+ setup_file_monitor ("/etc/resolv.conf");
+ setup_file_monitor ("/etc/localtime");
+
+ introspection_bytes = g_resources_lookup_data ("/org/freedesktop/XdgApp/xdg-app-dbus-interfaces.xml", 0, NULL);
+ g_assert (introspection_bytes != NULL);
+
+ introspection_data = g_dbus_node_info_new_for_xml (g_bytes_get_data (introspection_bytes, NULL), NULL);
+
+ owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+ "org.freedesktop.XdgApp.SessionHelper",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ NULL,
+ NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ g_bus_unown_name (owner_id);
+
+ g_dbus_node_info_unref (introspection_data);
+
+ return 0;
+}
diff --git a/xdg-app-session.service.in b/xdg-app-session.service.in
new file mode 100644
index 0000000..a8e7099
--- /dev/null
+++ b/xdg-app-session.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.XdgApp.SessionHelper
+Exec=@libexecdir@/xdg-app-session-helper
diff --git a/xdg-app.gresource.xml b/xdg-app.gresource.xml
new file mode 100644
index 0000000..4887a94
--- /dev/null
+++ b/xdg-app.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<gresources>
+ <gresource prefix='/org/freedesktop/XdgApp'>
+ <file>xdg-app-dbus-interfaces.xml</file>
+ </gresource>
+</gresources>