diff options
author | Alexander Larsson <alexl@redhat.com> | 2015-01-27 20:59:16 +0000 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2015-01-28 20:03:13 +0100 |
commit | fca4a162093f1389c51a078cda440938c83f6b6a (patch) | |
tree | cc89c8625fc016cde6bc9da1ed192db1b535fd63 | |
parent | 8fdc60ed7a4b5bdda3d5f68ace830467dffeaf56 (diff) | |
download | xdg-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-- | .gitignore | 5 | ||||
-rw-r--r-- | Makefile.am | 48 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | xdg-app-dbus-interfaces.xml | 34 | ||||
-rw-r--r-- | xdg-app-session-helper.c | 174 | ||||
-rw-r--r-- | xdg-app-session.service.in | 3 | ||||
-rw-r--r-- | xdg-app.gresource.xml | 6 |
7 files changed, 285 insertions, 3 deletions
@@ -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> |