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.
tingping/wmclass
Alexander Larsson 2015-01-27 20:59:16 +00:00
parent 8fdc60ed7a
commit fca4a16209
7 changed files with 285 additions and 3 deletions

5
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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>

View File

@ -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;
}

View File

@ -0,0 +1,3 @@
[D-BUS Service]
Name=org.freedesktop.XdgApp.SessionHelper
Exec=@libexecdir@/xdg-app-session-helper

View File

@ -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>