mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 05:18:00 +02:00
Add dbus-update-activation-environment tool
If OS builders (distributions) have chosen to use the per-user bus, this provides two possible modes of operation for compatibility with existing X session startup hooks. A legacy-free system can just upload DISPLAY, XAUTHORITY and possibly DBUS_SESSION_BUS_ADDRESS into dbus-daemon's and systemd's activation environments, similar to http://cgit.freedesktop.org/systemd/systemd/tree/xorg/50-systemd-user.sh installed by systemd (but unlike systemctl, dbus-update-activation-environment works for traditional D-Bus-activated services, not just for systemd services). A system where compatibility is required for environment variables exported by snippets in /etc/X11/xinit/xinitrc.d (in Red Hat derivatives, Gentoo, etc.) or /etc/X11/Xsession.d (Debian derivatives) can upload the entire environment of the X session, minus some selected environment variables which are specific to a login session (notably XDG_SESSION_ID). In Debian, I plan to put the former in a new dbus-user-session package that enables a user-session-centric mode of operation for D-Bus, and the latter in the existing dbus-x11 package, with the intention that dbus-x11 eventually becomes a tool for change-averse setups or goes away entirely. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61301 Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
This commit is contained in:
parent
263aca37ec
commit
2a6cefbc3b
7 changed files with 653 additions and 0 deletions
|
|
@ -138,6 +138,7 @@ configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-launch.1.xml.in ${CMAKE_BINARY_DI
|
|||
configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-monitor.1.xml.in ${CMAKE_BINARY_DIR}/doc/dbus-monitor.1.xml)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-send.1.xml.in ${CMAKE_BINARY_DIR}/doc/dbus-send.1.xml)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-test-tool.1.xml.in ${CMAKE_BINARY_DIR}/doc/dbus-test-tool.1.xml)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-update-activation-environment.1.xml.in ${CMAKE_BINARY_DIR}/doc/dbus-update-activation-environment.1.xml)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/../doc/dbus-uuidgen.1.xml.in ${CMAKE_BINARY_DIR}/doc/dbus-uuidgen.1.xml)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-cleanup-sockets.1.xml html-nochunks)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-daemon.1.xml html-nochunks)
|
||||
|
|
@ -146,6 +147,7 @@ DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-monitor.1.xml html-nochunks)
|
|||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-send.1.xml html-nochunks)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-test-tool.1.xml html-nochunks)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-uuidgen.1.xml html-nochunks)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-update-activation-environment.1.xml html-nochunks)
|
||||
if (UNIX)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-daemon.1.xml man)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-monitor.1.xml man)
|
||||
|
|
@ -154,6 +156,7 @@ if (UNIX)
|
|||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-launch.1.xml man)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-uuidgen.1.xml man)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-cleanup-sockets.1.xml man)
|
||||
DOCBOOK(${CMAKE_BINARY_DIR}/doc/dbus-update-activation-environment.1.xml man)
|
||||
endif()
|
||||
#
|
||||
# handle html index file
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ set (dbus_test_tool_SOURCES
|
|||
../../tools/test-tool.h
|
||||
)
|
||||
|
||||
set (dbus_update_activation_environment_SOURCES
|
||||
../../tools/dbus-update-activation-environment.c
|
||||
../../tools/tool-common.c
|
||||
../../tools/tool-common.h
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set (dbus_launch_SOURCES
|
||||
../../tools/dbus-launch-win.c
|
||||
|
|
@ -54,6 +60,10 @@ add_executable(dbus-test-tool ${dbus_test_tool_SOURCES})
|
|||
target_link_libraries(dbus-test-tool ${DBUS_LIBRARIES})
|
||||
install_targets(/bin dbus-test-tool )
|
||||
|
||||
add_executable(dbus-update-activation-environment ${dbus_update_activation_environment_SOURCES})
|
||||
target_link_libraries(dbus-update-activation-environment ${DBUS_LIBRARIES})
|
||||
install_targets(/bin dbus-update-activation-environment )
|
||||
|
||||
add_executable(dbus-launch ${dbus_launch_SOURCES})
|
||||
target_link_libraries(dbus-launch )
|
||||
if (DBUS_BUILD_X11)
|
||||
|
|
|
|||
|
|
@ -1861,6 +1861,7 @@ doc/dbus-monitor.1.xml
|
|||
doc/dbus-run-session.1.xml
|
||||
doc/dbus-send.1.xml
|
||||
doc/dbus-test-tool.1.xml
|
||||
doc/dbus-update-activation-environment.1.xml
|
||||
doc/dbus-uuidgen.1.xml
|
||||
dbus-1.pc
|
||||
dbus-1-uninstalled.pc
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ man_pages = \
|
|||
dbus-run-session.1 \
|
||||
dbus-send.1 \
|
||||
dbus-test-tool.1 \
|
||||
dbus-update-activation-environment.1 \
|
||||
dbus-uuidgen.1 \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
|||
213
doc/dbus-update-activation-environment.1.xml.in
Normal file
213
doc/dbus-update-activation-environment.1.xml.in
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
<refentry id="dbus-update-activation-environment.1">
|
||||
<refentryinfo>
|
||||
<copyright>
|
||||
<year>2015</year>
|
||||
<holder>Collabora Ltd.</holder>
|
||||
</copyright>
|
||||
<legalnotice>
|
||||
<para>This man page is distributed under the same terms as
|
||||
dbus-update-activation-environment (MIT/X11). There is NO WARRANTY,
|
||||
to the extent permitted by law.</para>
|
||||
</legalnotice>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>dbus-update-activation-environment</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="manual">User Commands</refmiscinfo>
|
||||
<refmiscinfo class="source">D-Bus</refmiscinfo>
|
||||
<refmiscinfo class="version">@DBUS_VERSION@</refmiscinfo>
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>dbus-update-activation-environment</refname>
|
||||
<refpurpose>update environment used for D-Bus session services</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv id="synopsis">
|
||||
<cmdsynopsis>
|
||||
<command>dbus-update-activation-environment</command>
|
||||
<arg choice="opt">--systemd</arg>
|
||||
<arg choice="opt">--verbose</arg>
|
||||
<group choice="plain">
|
||||
<arg choice="plain">--all</arg>
|
||||
<arg choice="plain" rep="repeat"><replaceable>VAR</replaceable></arg>
|
||||
<arg choice="plain" rep="repeat"><replaceable>VAR</replaceable>=<replaceable>VAL</replaceable></arg>
|
||||
</group>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1 id="description">
|
||||
<title>DESCRIPTION</title>
|
||||
<para><command>dbus-update-activation-environment</command>
|
||||
updates the list of environment variables used by
|
||||
<command>dbus-daemon --session</command>
|
||||
when it activates session services without using
|
||||
<command>systemd</command>.</para>
|
||||
|
||||
<para>With the <option>--systemd</option> option,
|
||||
if an instance of <command>systemd --user</command> is
|
||||
available on D-Bus, it also updates the list of environment variables
|
||||
used by <command>systemd --user</command>
|
||||
when it activates user services, including D-Bus session services
|
||||
for which <command>dbus-daemon</command> has been configured to
|
||||
delegate activation to <command>systemd</command>.
|
||||
This is very similar to the <option>import-environment</option>
|
||||
command provided by
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||
|
||||
<para>Variables that are special to <command>dbus-daemon</command>
|
||||
or <command>systemd</command> may be set, but their values will
|
||||
be overridden when a service is started. For instance, it is
|
||||
not useful to add <envar>DBUS_SESSION_BUS_ADDRESS</envar> to
|
||||
<command>dbus-daemon</command>'s activation environment,
|
||||
although it might still be useful to add it to
|
||||
<command>systemd</command>'s activation environment.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="options">
|
||||
<title>OPTIONS</title>
|
||||
<variablelist remap="TP">
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--all</option></term>
|
||||
<listitem>
|
||||
<para>Set all environment variables present in
|
||||
the environment used by
|
||||
<command>dbus-update-activation-environment</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--systemd</option></term>
|
||||
<listitem>
|
||||
<para>Set environment variables for systemd user services as well as
|
||||
for traditional D-Bus session services.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--verbose</option></term>
|
||||
<listitem>
|
||||
<para>Output messages to standard error explaining what
|
||||
dbus-update-activation-environment is doing.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>VAR</replaceable></term>
|
||||
<listitem>
|
||||
<para>If <replaceable>VAR</replaceable> is present in the
|
||||
environment of <command>dbus-update-activation-environment</command>,
|
||||
set it to the same value for D-Bus services. Its value must be
|
||||
UTF-8 (if not, it is skipped with a warning). If
|
||||
<replaceable>VAR</replaceable> is not present
|
||||
in the environment, this argument is silently ignored.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>VAR</replaceable>=<replaceable>VAL</replaceable></term>
|
||||
<listitem>
|
||||
<para>Set <replaceable>VAR</replaceable> to <replaceable>VAL</replaceable>,
|
||||
which must be UTF-8.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="examples">
|
||||
<title>EXAMPLES</title>
|
||||
<para>
|
||||
<command>dbus-update-activation-environment</command> is
|
||||
primarily designed to be used in Linux distributions' X11 session
|
||||
startup scripts, in conjunction with the "user bus" design.
|
||||
</para>
|
||||
|
||||
<para>To propagate <envar>DISPLAY</envar> and <envar>XAUTHORITY</envar>
|
||||
to <command>dbus-daemon</command>
|
||||
and, if present, <command>systemd</command>,
|
||||
and propagate <envar>DBUS_SESSION_BUS_ADDRESS</envar> to
|
||||
<command>systemd</command>:
|
||||
<programlisting language="sh">
|
||||
dbus-update-activation-environment --systemd \
|
||||
DBUS_SESSION_BUS_ADDRESS DISPLAY XAUTHORITY
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>To propagate all environment variables except
|
||||
<envar>XDG_SEAT</envar>, <envar>XDG_SESSION_ID</envar>
|
||||
and <envar>XDG_VTNR</envar> to <command>dbus-daemon</command>
|
||||
(and, if present, <command>systemd</command>) for compatibility
|
||||
with legacy X11 session startup scripts:
|
||||
<programlisting language="sh">
|
||||
# in a subshell so the variables remain set in the
|
||||
# parent script
|
||||
(
|
||||
unset XDG_SEAT
|
||||
unset XDG_SESSION_ID
|
||||
unset XDG_VTNR
|
||||
|
||||
dbus-update-activation-environment --systemd --all
|
||||
)
|
||||
</programlisting>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="exit_status">
|
||||
<title>EXIT STATUS</title>
|
||||
<para>
|
||||
<command>dbus-update-activation-environment</command>
|
||||
exits with status 0 on success, EX_USAGE (64) on invalid
|
||||
command-line options, EX_OSERR (71) if unable to connect
|
||||
to the session bus, or EX_UNAVAILABLE (69) if unable to
|
||||
set the environment variables. Other nonzero exit codes might be
|
||||
added in future versions.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="environment">
|
||||
<title>ENVIRONMENT</title>
|
||||
<para><envar>DBUS_SESSION_BUS_ADDRESS</envar>,
|
||||
<envar>XDG_RUNTIME_DIR</envar> and/or <envar>DISPLAY</envar>
|
||||
are used to find the address of the session bus.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="limitations">
|
||||
<title>LIMITATIONS</title>
|
||||
<para>
|
||||
<command>dbus-daemon</command> does not provide a way to unset
|
||||
environment variables after they have been set (although
|
||||
<command>systemd</command> does), so
|
||||
<command>dbus-update-activation-environment</command> does not
|
||||
offer this functionality either.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
POSIX does not specify the encoding of non-ASCII environment variable
|
||||
names or values and allows them to contain any non-zero byte, but
|
||||
neither <command>dbus-daemon</command> nor <command>systemd</command>
|
||||
supports environment variables with non-UTF-8 names or values.
|
||||
Accordingly, <command>dbus-update-activation-environment</command>
|
||||
assumes that any name or value that appears to be valid UTF-8 is
|
||||
intended to be UTF-8, and ignores other names or values with a warning.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="bugs">
|
||||
<title>BUGS</title>
|
||||
<para>Please send bug reports to the D-Bus bug tracker or mailing list.
|
||||
See <ulink url="http://www.freedesktop.org/software/dbus/">http://www.freedesktop.org/software/dbus/</ulink>.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="see_also">
|
||||
<title>SEE ALSO</title>
|
||||
<para><citerefentry><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
the <option>import-environment</option> command of
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
|
|
@ -16,6 +16,7 @@ bin_PROGRAMS = \
|
|||
dbus-monitor \
|
||||
dbus-send \
|
||||
dbus-test-tool \
|
||||
dbus-update-activation-environment \
|
||||
$(NULL)
|
||||
|
||||
if DBUS_UNIX
|
||||
|
|
@ -98,6 +99,13 @@ dbus_test_tool_SOURCES = \
|
|||
$(NULL)
|
||||
dbus_test_tool_LDADD = $(top_builddir)/dbus/libdbus-1.la
|
||||
|
||||
dbus_update_activation_environment_SOURCES = \
|
||||
dbus-update-activation-environment.c \
|
||||
tool-common.c \
|
||||
tool-common.h \
|
||||
$(NULL)
|
||||
dbus_update_activation_environment_LDADD = $(top_builddir)/dbus/libdbus-1.la
|
||||
|
||||
EXTRA_DIST = run-with-tmp-session-bus.sh strtoll.c strtoull.c
|
||||
CLEANFILES = \
|
||||
run-with-tmp-session-bus.conf
|
||||
|
|
|
|||
417
tools/dbus-update-activation-environment.c
Normal file
417
tools/dbus-update-activation-environment.c
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* dbus-update-activation-environment - update D-Bus, and optionally
|
||||
* systemd, activation environment
|
||||
*
|
||||
* Copyright © 2014-2015 Collabora Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SYSEXITS_H
|
||||
# include <sysexits.h>
|
||||
#endif
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#ifdef DBUS_UNIX
|
||||
# include <unistd.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "tool-common.h"
|
||||
|
||||
#define PROGNAME "dbus-update-activation-environment"
|
||||
|
||||
#ifndef EX_USAGE
|
||||
# define EX_USAGE 64
|
||||
#endif
|
||||
|
||||
#ifndef EX_UNAVAILABLE
|
||||
# define EX_UNAVAILABLE 69
|
||||
#endif
|
||||
|
||||
#ifndef EX_OSERR
|
||||
# define EX_OSERR 71
|
||||
#endif
|
||||
|
||||
/* apparently this is the portable way to get the entire environment... */
|
||||
extern char **environ;
|
||||
|
||||
/* we don't really have anything useful to say about the stage at which we
|
||||
* failed */
|
||||
#define oom() tool_oom ("updating environment")
|
||||
|
||||
static dbus_bool_t verbose = FALSE;
|
||||
|
||||
static void say (const char *format, ...) _DBUS_GNUC_PRINTF (1, 2);
|
||||
|
||||
static void
|
||||
say (const char *format,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
fprintf (stderr, "%s: ", PROGNAME);
|
||||
va_start (ap, format);
|
||||
vfprintf (stderr, format, ap);
|
||||
fputc ('\n', stderr);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static dbus_bool_t
|
||||
systemd_user_running (void)
|
||||
{
|
||||
char *xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
|
||||
char *path;
|
||||
struct stat buf;
|
||||
dbus_bool_t ret = FALSE;
|
||||
|
||||
if (xdg_runtime_dir == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Assume that XDG_RUNTIME_DIR/systemd exists if and only if
|
||||
* "systemd --user" is running. It's OK to use asprintf() here
|
||||
* because we know we're on Linux. */
|
||||
if (asprintf (&path, "%s/systemd", xdg_runtime_dir) < 0)
|
||||
oom ();
|
||||
|
||||
if (stat (path, &buf) == 0)
|
||||
ret = TRUE;
|
||||
|
||||
free (path);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
DBusConnection *conn;
|
||||
DBusMessage *msg;
|
||||
DBusMessage *reply;
|
||||
DBusError error = DBUS_ERROR_INIT;
|
||||
DBusMessageIter msg_iter;
|
||||
DBusMessageIter array_iter;
|
||||
int i;
|
||||
int first_non_option = argc;
|
||||
dbus_bool_t all = FALSE;
|
||||
#ifdef __linux__
|
||||
DBusMessage *sd_msg = NULL;
|
||||
DBusMessageIter sd_msg_iter;
|
||||
DBusMessageIter sd_array_iter;
|
||||
dbus_bool_t systemd = FALSE;
|
||||
#endif
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] != '-')
|
||||
{
|
||||
first_non_option = i;
|
||||
break;
|
||||
}
|
||||
else if (strcmp (argv[i], "--") == 0)
|
||||
{
|
||||
first_non_option = i + 1;
|
||||
break;
|
||||
}
|
||||
else if (strcmp (argv[i], "--all") == 0)
|
||||
{
|
||||
all = TRUE;
|
||||
}
|
||||
else if (strcmp (argv[i], "--systemd") == 0)
|
||||
{
|
||||
#ifdef __linux__
|
||||
systemd = TRUE;
|
||||
#else
|
||||
say ("not on Linux, ignoring --systemd argument");
|
||||
#endif
|
||||
}
|
||||
else if (strcmp (argv[i], "--verbose") == 0)
|
||||
{
|
||||
verbose = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%1$s: update environment variables that will be set for D-Bus\n"
|
||||
" session services\n"
|
||||
"\n"
|
||||
"%1$s [options] VAR[=VAL] [VAR2[=VAL2] ...]\n"
|
||||
" Add specified variables to D-Bus activation environment.\n"
|
||||
" If omitted, values are taken from current environment;\n"
|
||||
" variables not found in the environment are ignored.\n"
|
||||
"%1$s --all\n"
|
||||
" Add entire current environment to D-Bus activation\n"
|
||||
" environment.\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
"\n"
|
||||
"--all\n"
|
||||
" Upload all environment variables.\n"
|
||||
"--systemd\n"
|
||||
" Also update the 'systemd --user' environment\n"
|
||||
" if possible.\n"
|
||||
"--verbose\n"
|
||||
" Talk about it.\n"
|
||||
,
|
||||
PROGNAME);
|
||||
exit (EX_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
if (all && first_non_option < argc)
|
||||
{
|
||||
fprintf (stderr, "%s: error: --all cannot be used with VAR or "
|
||||
"VAR=VAL arguments\n", PROGNAME);
|
||||
exit (EX_USAGE);
|
||||
}
|
||||
|
||||
conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
|
||||
|
||||
if (conn == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: error: unable to connect to D-Bus: %s\n", PROGNAME,
|
||||
error.message);
|
||||
exit (EX_OSERR);
|
||||
}
|
||||
|
||||
msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS, "UpdateActivationEnvironment");
|
||||
|
||||
if (msg == NULL)
|
||||
oom ();
|
||||
|
||||
dbus_message_iter_init_append (msg, &msg_iter);
|
||||
|
||||
if (!dbus_message_iter_open_container (&msg_iter, DBUS_TYPE_ARRAY,
|
||||
"{ss}", &array_iter))
|
||||
oom ();
|
||||
|
||||
#ifdef __linux__
|
||||
if (systemd)
|
||||
{
|
||||
if (!systemd_user_running ())
|
||||
{
|
||||
/* This is only best-effort. */
|
||||
say ("systemd --user not found, ignoring --systemd argument");
|
||||
systemd = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (systemd)
|
||||
{
|
||||
sd_msg = dbus_message_new_method_call ("org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager",
|
||||
"SetEnvironment");
|
||||
|
||||
if (sd_msg == NULL)
|
||||
oom ();
|
||||
|
||||
dbus_message_iter_init_append (sd_msg, &sd_msg_iter);
|
||||
|
||||
if (!dbus_message_iter_open_container (&sd_msg_iter, DBUS_TYPE_ARRAY,
|
||||
"s", &sd_array_iter))
|
||||
oom ();
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = all ? 0 : first_non_option;
|
||||
all ? environ[i] != NULL : i < argc;
|
||||
i++)
|
||||
{
|
||||
const char *var;
|
||||
char *copy;
|
||||
char *eq;
|
||||
const char *val;
|
||||
DBusMessageIter pair_iter;
|
||||
|
||||
if (all)
|
||||
var = environ[i];
|
||||
else
|
||||
var = argv[i];
|
||||
|
||||
copy = strdup (var);
|
||||
|
||||
if (copy == NULL)
|
||||
oom ();
|
||||
|
||||
if (!dbus_validate_utf8 (var, NULL))
|
||||
{
|
||||
/* var is either of the form VAR or VAR=VAL */
|
||||
fprintf (stderr,
|
||||
"%s: warning: environment variable not UTF-8: %s\n",
|
||||
PROGNAME, var);
|
||||
goto next;
|
||||
}
|
||||
|
||||
eq = strchr (copy, '=');
|
||||
|
||||
if (eq == NULL)
|
||||
{
|
||||
if (all)
|
||||
{
|
||||
/* items in the environment block should be of the form
|
||||
* VAR=VAL */
|
||||
fprintf (stderr,
|
||||
"%s: warning: environment variable without '=': %s\n",
|
||||
PROGNAME, var);
|
||||
goto next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* items on the command-line may be of the form VAR
|
||||
* in which case we infer the value from the environment */
|
||||
val = getenv (var);
|
||||
|
||||
if (val == NULL)
|
||||
{
|
||||
/* nothing to be done here */
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!dbus_validate_utf8 (val, NULL))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: warning: environment variable not UTF-8: %s=%s\n",
|
||||
PROGNAME, var, val);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* split VAR=VAL into VAR and VAL */
|
||||
*eq = '\0';
|
||||
val = eq + 1;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
if (systemd)
|
||||
{
|
||||
char *combined;
|
||||
|
||||
/* recombine if necessary */
|
||||
if (asprintf (&combined, "%s=%s", copy, val) < 0)
|
||||
oom ();
|
||||
|
||||
if (!dbus_message_iter_append_basic (&sd_array_iter,
|
||||
DBUS_TYPE_STRING, &combined))
|
||||
oom ();
|
||||
|
||||
free (combined);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dbus_message_iter_open_container (&array_iter,
|
||||
DBUS_TYPE_DICT_ENTRY, NULL, &pair_iter))
|
||||
oom ();
|
||||
|
||||
say ("setting %s=%s", copy, val);
|
||||
|
||||
if (!dbus_message_iter_append_basic (&pair_iter, DBUS_TYPE_STRING,
|
||||
©))
|
||||
oom ();
|
||||
|
||||
if (!dbus_message_iter_append_basic (&pair_iter, DBUS_TYPE_STRING,
|
||||
&val))
|
||||
oom ();
|
||||
|
||||
if (!dbus_message_iter_close_container (&array_iter, &pair_iter))
|
||||
oom ();
|
||||
|
||||
next:
|
||||
free (copy);
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_close_container (&msg_iter, &array_iter))
|
||||
oom ();
|
||||
|
||||
#ifdef __linux__
|
||||
if (systemd &&
|
||||
!dbus_message_iter_close_container (&sd_msg_iter, &sd_array_iter))
|
||||
oom ();
|
||||
#endif
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
|
||||
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: error sending to dbus-daemon: %s: %s\n",
|
||||
PROGNAME, error.name, error.message);
|
||||
exit (EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if (!dbus_message_get_args (msg, &error, DBUS_TYPE_INVALID))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: error from dbus-daemon: %s: %s\n",
|
||||
PROGNAME, error.name, error.message);
|
||||
exit (EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
dbus_message_unref (reply);
|
||||
|
||||
#ifdef __linux__
|
||||
if (systemd)
|
||||
{
|
||||
reply = dbus_connection_send_with_reply_and_block (conn, sd_msg, -1,
|
||||
&error);
|
||||
|
||||
/* non-fatal, the main purpose of this thing is to communicate
|
||||
* with dbus-daemon */
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: warning: error sending to systemd: %s: %s\n",
|
||||
PROGNAME, error.name, error.message);
|
||||
}
|
||||
else if (!dbus_message_get_args (msg, &error, DBUS_TYPE_INVALID))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"%s: warning: error from systemd: %s: %s\n",
|
||||
PROGNAME, error.name, error.message);
|
||||
}
|
||||
|
||||
if (reply != NULL)
|
||||
dbus_message_unref (reply);
|
||||
|
||||
dbus_message_unref (sd_msg);
|
||||
dbus_error_free (&error);
|
||||
}
|
||||
#endif
|
||||
|
||||
dbus_message_unref (msg);
|
||||
dbus_connection_unref (conn);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue