topdir=$(dirname $0)
cd $topdir
-if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
- # This part is allowed to fail
- cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
- chmod +x .git/hooks/pre-commit && \
- echo "Activated pre-commit hook." || :
-fi
-
+# We do not need this, we are not systemd upstream!
+#if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
+# # This part is allowed to fail
+# cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
+# chmod +x .git/hooks/pre-commit && \
+# echo "Activated pre-commit hook." || :
+#fi
intltoolize --force --automake
autoreconf --force --install --symlink
-libdir() {
- echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd)
-}
-
-args="\
---sysconfdir=/etc \
---localstatedir=/var \
---libdir=$(libdir /usr/lib) \
-"
-
-if [ -f "$topdir/.config.args" ]; then
- args="$args $(cat $topdir/.config.args)"
-fi
-
-if [ ! -L /bin ]; then
-args="$args \
---with-rootprefix=/ \
---with-rootlibdir=$(libdir /lib) \
-"
-fi
-
cd $oldpwd
-
-if [ "x$1" = "xc" ]; then
- $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
- make clean
-elif [ "x$1" = "xt" ]; then
- $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus --enable-terminal $args
- make clean
-elif [ "x$1" = "xg" ]; then
- $topdir/configure CFLAGS='-g -Og -ftrapv' --enable-compat-libs --enable-kdbus $args
- make clean
-elif [ "x$1" = "xa" ]; then
- $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-compat-libs --enable-kdbus $args
- make clean
-elif [ "x$1" = "xl" ]; then
- $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args
- make clean
-elif [ "x$1" = "xs" ]; then
- scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' --enable-kdbus $args
- scan-build make
-else
- echo
- echo "----------------------------------------------------------------"
- echo "Initialized build system. For a common configuration please run:"
- echo "----------------------------------------------------------------"
- echo
- echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-compat-libs --enable-kdbus $args"
- echo
-fi
--- /dev/null
+../src/Makefile
\ No newline at end of file
+++ /dev/null
-# This file is part of systemd.
-#
-# The lookup keys are composed in:
-# 60-evdev.rules
-#
-# Note: The format of the "evdev:" prefix match key is a
-# contract between the rules file and the hardware data, it might
-# change in later revisions to support more or better matches, it
-# is not necessarily expected to be a stable ABI.
-#
-# Match string formats:
-# evdev:<modalias>
-# evdev:name:<device name>:dmi:<dmi string>
-#
-# To add local entries, create a new file
-# /etc/udev/hwdb.d/61-evdev-local.hwdb
-# and add your rules there. To load the new rules execute (as root):
-# udevadm hwdb --update
-# udevadm trigger /dev/input/eventXX
-# where /dev/input/eventXX is the device in question. If in
-# doubt, simply use /dev/input/event* to reload all input rules.
-#
-# If your changes are generally applicable, open a bug report on
-# http://bugs.freedesktop.org/enter_bug.cgi?product=systemd
-# and include your new rules, a description of the device, and the
-# output of
-# udevadm info /dev/input/eventXX
-# (or /dev/input/event*).
-#
-# Allowed properties are:
-# EVDEV_ABS_<axis>=<min>:<max>:<res>:<fuzz>:<flat>
-#
-# where <axis> is the hexadecimal EV_ABS code as listed in linux/input.h
-# and min, max, res, fuzz, flat are the decimal values to the respective
-# fields of the struct input_absinfo as listed in linux/input.h.
-# If a field is missing the field will be left as-is. Not all fields need to
-# be present. e.g. ::45 sets the resolution to 45 units/mm.
-
-#
-# Sort by brand, model
-
-#########################################
-# Apple
-#########################################
-
-# Macbook2,1 (late 2006), single-button touchpad
-evdev:input:b0003v05ACp021B*
- EVDEV_ABS_00=256:1471:12
- EVDEV_ABS_01=256:831:12
-
-# Macbook5,1 (unibody), aka wellspring3
-evdev:input:b0003v05ACp0236*
-evdev:input:b0003v05ACp0237*
-evdev:input:b0003v05ACp0238*
- EVDEV_ABS_00=::92
- EVDEV_ABS_01=::90
- EVDEV_ABS_35=::92
- EVDEV_ABS_36=::90
-
-# Macbook8 (unibody, March 2011)
-evdev:input:b0003v05ACp0245*
-evdev:input:b0003v05ACp0246*
-evdev:input:b0003v05ACp0247*
- EVDEV_ABS_00=::92
- EVDEV_ABS_01=::91
- EVDEV_ABS_35=::92
- EVDEV_ABS_36=::91
-
-# Macbook8,2 (unibody)
-evdev:input:b0003v05ACp0252*
-evdev:input:b0003v05ACp0253*
-evdev:input:b0003v05ACp0254*
- EVDEV_ABS_00=::94
- EVDEV_ABS_01=::92
- EVDEV_ABS_35=::94
- EVDEV_ABS_36=::92
-
-# MacbookPro10,1 (unibody, June 2012)
-evdev:input:b0003v05ACp0259*
-evdev:input:b0003v05ACp025a*
-evdev:input:b0003v05ACp025b*
-# MacbookPro10,2 (unibody, October 2012)
-evdev:input:b0003v05ACp0259*
-evdev:input:b0003v05ACp025a*
-evdev:input:b0003v05ACp025b*
- EVDEV_ABS_00=::94
- EVDEV_ABS_01=::92
- EVDEV_ABS_35=::94
- EVDEV_ABS_36=::92
-
-#########################################
-# ASUS
-#########################################
-# Asus K52JT
-evdev:name:ETPS/2 Elantech Touchpad:dmi:bvn*:bvr*:bd*:svnASUSTeKComputerInc.:pnK52JT:*
- EVDEV_ABS_00=::18
- EVDEV_ABS_01=::16
- EVDEV_ABS_35=::18
- EVDEV_ABS_36=::16
-
-#########################################
-# Google
-#########################################
-
-# Chromebook Pixel (2015) - Samus
-evdev:name:Atmel maXTouch Touch*:dmi:bvn*:bvr*:bd*:svnGOOGLE:pnSamus*
- EVDEV_ABS_00=::10
- EVDEV_ABS_01=::10
- EVDEV_ABS_35=::10
- EVDEV_ABS_36=::10
-
-#########################################
-# Lenovo
-#########################################
-
-# Lenovo X230 series
-evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*X230*
- EVDEV_ABS_01=::100
- EVDEV_ABS_36=::100
<xsl:text>elogind.directives.html</xsl:text>
</xsl:attribute>
<xsl:text>Directives </xsl:text>
- </a>·
- <a>
- <xsl:attribute name="href">
- <xsl:text>../python-elogind/index.html</xsl:text>
- </xsl:attribute>
- <xsl:text>Python </xsl:text>
</a>
<span style="float:right">
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<refsect1>
+ <title>Environment</title>
+
+ <variablelist class='environment-variables'>
+ <varlistentry id='pager'>
+ <term><varname>$SYSTEMD_PAGER</varname></term>
+
+ <listitem><para>Pager to use when
+ <option>--no-pager</option> is not given;
+ overrides <varname>$PAGER</varname>. Setting
+ this to an empty string or the value
+ <literal>cat</literal> is equivalent to passing
+ <option>--no-pager</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='less'>
+ <term><varname>$SYSTEMD_LESS</varname></term>
+
+ <listitem><para>Override the default
+ options passed to
+ <command>less</command>
+ (<literal>FRSXMK</literal>).</para></listitem>
+ </varlistentry>
+ </variablelist>
+</refsect1>
+++ /dev/null
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
- This file is part of systemd.
-
- Copyright 2010 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
--->
-
-<refentry id="sd_pid_get_session" conditional='HAVE_PAM'>
-
- <refentryinfo>
- <title>sd_pid_get_session</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Lennart</firstname>
- <surname>Poettering</surname>
- <email>lennart@poettering.net</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>sd_pid_get_session</refentrytitle>
- <manvolnum>3</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>sd_pid_get_session</refname>
- <refname>sd_pid_get_unit</refname>
- <refname>sd_pid_get_user_unit</refname>
- <refname>sd_pid_get_owner_uid</refname>
- <refname>sd_pid_get_machine_name</refname>
- <refname>sd_pid_get_slice</refname>
- <refname>sd_peer_get_session</refname>
- <refname>sd_peer_get_unit</refname>
- <refname>sd_peer_get_user_unit</refname>
- <refname>sd_peer_get_owner_uid</refname>
- <refname>sd_peer_get_machine_name</refname>
- <refname>sd_peer_get_slice</refname>
- <refpurpose>Determine session, service, owner of a
- session, container/VM or slice of a specific
- PID or socket peer</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <funcsynopsis>
- <funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_session</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>char **<parameter>session</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_unit</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>char **<parameter>unit</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_user_unit</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>char **<parameter>unit</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>uid_t *<parameter>uid</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_machine_name</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>char **<parameter>name</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_pid_get_slice</function></funcdef>
- <paramdef>pid_t <parameter>pid</parameter></paramdef>
- <paramdef>char **<parameter>slice</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_session</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>char **<parameter>session</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_unit</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>char **<parameter>unit</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_user_unit</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>char **<parameter>unit</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_owner_uid</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>uid_t *<parameter>uid</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_machine_name</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>char **<parameter>name</parameter></paramdef>
- </funcprototype>
-
- <funcprototype>
- <funcdef>int <function>sd_peer_get_slice</function></funcdef>
- <paramdef>int <parameter>fd</parameter></paramdef>
- <paramdef>char **<parameter>slice</parameter></paramdef>
- </funcprototype>
- </funcsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><function>sd_pid_get_session()</function> may be used to
- determine the login session identifier of a process identified by
- the specified process identifier. The session identifier is a
- short string, suitable for usage in file system paths. Note that
- not all processes are part of a login session (e.g. system service
- processes, user processes that are shared between multiple
- sessions of the same user, or kernel threads). For processes not
- being part of a login session this function will fail with
- -ENXIO. The returned string needs to be freed with the libc
- <citerefentry
- project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use.</para>
-
- <para><function>sd_pid_get_unit()</function> may be used to
- determine the systemd system unit (i.e. system service) identifier
- of a process identified by the specified PID. The unit name is a
- short string, suitable for usage in file system paths. Note that
- not all processes are part of a system unit/service (e.g. user
- processes, or kernel threads). For processes not being part of a
- systemd system unit this function will fail with -ENXIO (More
- specifically: this call will not work for processes that are part
- of user units, use <function>sd_pid_get_user_unit()</function> for
- that.) The returned string needs to be freed with the libc
- <citerefentry
- project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use.</para>
-
- <para><function>sd_pid_get_user_unit()</function> may be used to
- determine the systemd user unit (i.e. user service) identifier of
- a process identified by the specified PID. This is similar to
- <function>sd_pid_get_unit()</function> but applies to user units
- instead of system units.</para>
-
- <para><function>sd_pid_get_owner_uid()</function> may be used to
- determine the Unix user identifier of the owner of the session of
- a process identified the specified PID. Note that this function
- will succeed for user processes which are shared between multiple
- login sessions of the same user, where
- <function>sd_pid_get_session()</function> will fail. For processes
- not being part of a login session and not being a shared process
- of a user this function will fail with -ENXIO.</para>
-
- <para><function>sd_pid_get_machine_name()</function> may be used
- to determine the name of the VM or container is a member of. The
- machine name is a short string, suitable for usage in file system
- paths. The returned string needs to be freed with the libc
- <citerefentry
- project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use. For processes not part of a VM or containers this
- function fails with -ENXIO.</para>
-
- <para><function>sd_pid_get_slice()</function> may be used to
- determine the slice unit the process is a member of. See
- <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for details about slices. The returned string needs to be freed
- with the libc
- <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- call after use.</para>
-
- <para>If the <varname>pid</varname> parameter of any of these
- functions is passed as 0, the operation is executed for the
- calling process.</para>
-
- <para>The <function>sd_peer_get_session()</function>,
- <function>sd_peer_get_unit()</function>,
- <function>sd_peer_get_user_unit()</function>,
- <function>sd_peer_get_owner_uid()</function>,
- <function>sd_peer_get_machine_name()</function> and
- <function>sd_peer_get_slice()</function> calls operate similar to
- their PID counterparts, but operate on a connected AF_UNIX socket
- and retrieve information about the connected peer process.</para>
- </refsect1>
-
- <refsect1>
- <title>Return Value</title>
-
- <para>On success, these calls return 0 or a positive integer. On
- failure, these calls return a negative errno-style error
- code.</para>
- </refsect1>
-
- <refsect1>
- <title>Errors</title>
-
- <para>Returned errors may indicate the following problems:</para>
-
- <variablelist>
-
- <varlistentry>
- <term><constant>-ENXIO</constant></term>
-
- <listitem><para>Given field is not specified for the described
- process or peer.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>-ESRCH</constant></term>
-
- <listitem><para>The specified PID does not refer to a running
- process.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><constant>-ENOMEM</constant></term>
-
- <listitem><para>Memory allocation failed.</para></listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Notes</title>
-
- <para>The <function>sd_pid_get_session()</function>,
- <function>sd_pid_get_unit()</function>,
- <function>sd_pid_get_user_unit()</function>,
- <function>sd_pid_get_owner_uid()</function>,
- <function>sd_pid_get_machine_name()</function>,
- <function>sd_pid_get_slice()</function>,
- <function>sd_peer_get_session()</function>,
- <function>sd_peer_get_unit()</function>,
- <function>sd_peer_get_user_unit()</function>,
- <function>sd_peer_get_owner_uid()</function>,
- <function>sd_peer_get_machine_name()</function> and
- <function>sd_peer_get_slice()</function> interfaces are
- available as a shared library, which can be compiled
- and linked to with the
- <constant>libelogind</constant>Â <citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- file.</para>
-
- <para>Note that the login session identifier as
- returned by <function>sd_pid_get_session()</function>
- is completely unrelated to the process session
- identifier as returned by
- <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
-
- <para>
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-machined.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- </para>
- </refsect1>
-
-</refentry>
--- /dev/null
+<?xml version="1.0"?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refsection PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<refsection>
+ <refsection id='confd'>
+ <title>Configuration Directories and Precedence</title>
+
+ <para>Configuration files are read from directories in
+ <filename>/etc/</filename>, <filename>/run/</filename>, and
+ <filename>/usr/lib/</filename>, in order of precedence.
+ Each configuration file in these configuration directories shall be named in
+ the style of <filename><replaceable>filename</replaceable>.conf</filename>.
+ Files in <filename>/etc/</filename> override files with the same name in
+ <filename>/run/</filename> and <filename>/usr/lib/</filename>. Files in
+ <filename>/run/</filename> override files with the same name in
+ <filename>/usr/lib/</filename>.</para>
+
+ <para>Packages should install their configuration files in
+ <filename>/usr/lib/</filename>. Files in <filename>/etc/</filename> are
+ reserved for the local administrator, who may use this logic to override the
+ configuration files installed by vendor packages. All configuration files
+ are sorted by their filename in lexicographic order, regardless of which of
+ the directories they reside in. If multiple files specify the same option,
+ the entry in the file with the lexicographically latest name will take
+ precedence. It is recommended to prefix all filenames with a two-digit number
+ and a dash, to simplify the ordering of the files.</para>
+
+ <para>If the administrator wants to disable a configuration file supplied by
+ the vendor, the recommended way is to place a symlink to
+ <filename>/dev/null</filename> in the configuration directory in
+ <filename>/etc/</filename>, with the same filename as the vendor
+ configuration file. If the vendor configuration file is included in
+ the initrd image, the image has to be regenerated.</para>
+
+ </refsection>
+
+ <refsection id='main-conf'>
+ <title>Configuration Directories and Precedence</title>
+
+ <para>Default configuration is defined during compilation, so a
+ configuration file is only needed when it is necessary to deviate
+ from those defaults. By default the configuration file in
+ <filename>/etc/elogind/</filename> contains commented out entries
+ showing the defaults as a guide to the administrator. This file
+ can be edited to create local overrides.
+ </para>
+
+ <para>When packages need to customize the configuration, they can
+ install configuration snippets in
+ <filename>/usr/lib/elogind/*.conf.d/</filename>. Files in
+ <filename>/etc/</filename> are reserved for the local
+ administrator, who may use this logic to override the
+ configuration files installed by vendor packages. The main
+ configuration file is read before any of the configuration
+ directories, and has the lowest precedence; entries in a file in
+ any configuration directory override entries in the single
+ configuration file. Files in the
+ <filename>*.conf.d/</filename> configuration subdirectories
+ are sorted by their filename in lexicographic order, regardless of
+ which of the subdirectories they reside in. If multiple files
+ specify the same option, the entry in the file with the
+ lexicographically latest name takes precedence. It is recommended
+ to prefix all filenames in those subdirectories with a two-digit
+ number and a dash, to simplify the ordering of the files.</para>
+
+ <para>To disable a configuration file supplied by the vendor, the
+ recommended way is to place a symlink to
+ <filename>/dev/null</filename> in the configuration directory in
+ <filename>/etc/</filename>, with the same filename as the vendor
+ configuration file.</para>
+ </refsection>
+</refsection>
--- /dev/null
+<?xml version="1.0"?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<variablelist>
+ <varlistentry id='help'>
+ <term><option>-h</option></term>
+ <term><option>--help</option></term>
+
+ <listitem id='help-text'>
+ <para>Print a short help text and exit.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry id='version'>
+ <term><option>--version</option></term>
+
+ <listitem id='version-text'>
+ <para>Print a short version string and exit.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='no-pager'>
+ <term><option>--no-pager</option></term>
+
+ <listitem>
+ <para>Do not pipe output into a pager.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='no-legend'>
+ <term><option>--no-legend</option></term>
+
+ <listitem>
+ <para>Do not print the legend, i.e. column headers and the
+ footer with hints.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<variablelist>
+ <varlistentry id='user'>
+ <term><option>--user</option></term>
+
+ <listitem id='user-text'>
+ <para>Talk to the service manager of the calling user,
+ rather than the service manager of the system.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='system'>
+ <term><option>--system</option></term>
+
+ <listitem id='system-text'>
+ <para>Talk to the service manager of the system. This is the
+ implied default.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='host'>
+ <term><option>-H</option></term>
+ <term><option>--host=</option></term>
+
+ <listitem id='host-text'>
+ <para>Execute the operation remotely. Specify a hostname, or a
+ username and hostname separated by <literal>@</literal>, to
+ connect to. The hostname may optionally be suffixed by a
+ container name, separated by <literal>:</literal>, which
+ connects directly to a specific container on the specified
+ host. This will use SSH to talk to the remote machine manager
+ instance. Container names may be enumerated with
+ <command>machinectl -H
+ <replaceable>HOST</replaceable></command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='machine'>
+ <term><option>-M</option></term>
+ <term><option>--machine=</option></term>
+
+ <listitem id='machine-text'>
+ <para>Execute operation on a local container. Specify a
+ container name to connect to.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
{-h,--help}'[Show this help]' \
'--version[Show package version]' \
'--what=[Operations to inhibit]:options:_inhibit_what' \
- '--who=[A descriptive string who is inhibiting]' \
- '--why=[A descriptive string why is being inhibited]' \
- '--mode=[One of block or delay]' \
+ '--who=[A descriptive string who is inhibiting]:who is inhibiting:' \
+ '--why=[A descriptive string why is being inhibited]:reason for the lock:' \
+ '--mode=[One of block or delay]:lock mode:( block delay )' \
'--list[List active inhibitors]' \
'*:commands:_systemd_inhibit_command'
snprintf(c, sizeof(c), PID_FMT"\n", pid);
- return write_string_file_no_create(fs, c);
+ return write_string_file(fs, c, 0);
}
int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
sc = strstrip(contents);
if (isempty(sc)) {
- r = write_string_file_no_create(fs, agent);
+ r = write_string_file(fs, agent, 0);
if (r < 0)
return r;
} else if (!path_equal(sc, agent))
sc = strstrip(contents);
if (streq(sc, "0")) {
- r = write_string_file_no_create(fs, "1");
+ r = write_string_file(fs, "1", 0);
if (r < 0)
return r;
if (r < 0)
return r;
- r = write_string_file_no_create(fs, "0");
+ r = write_string_file(fs, "0", 0);
if (r < 0)
return r;
if (r < 0)
return r;
- r = write_string_file_no_create(fs, "");
+ r = write_string_file(fs, "", 0);
if (r < 0)
return r;
if (r < 0)
return r;
- return write_string_file_no_create(p, value);
+ return write_string_file(p, value, 0);
}
/// UNNEEDED by elogind
#define BTRFS_FIRST_FREE_OBJECTID 256
#endif
+#ifndef BTRFS_LAST_FREE_OBJECTID
+#define BTRFS_LAST_FREE_OBJECTID -256ULL
+#endif
+
#ifndef BTRFS_ROOT_TREE_OBJECTID
#define BTRFS_ROOT_TREE_OBJECTID 1
#endif
#define BTRFS_QGROUP_LIMIT_KEY 244
#endif
+#ifndef BTRFS_ROOT_BACKREF_KEY
+#define BTRFS_ROOT_BACKREF_KEY 144
+#endif
+
#ifndef BTRFS_SUPER_MAGIC
#define BTRFS_SUPER_MAGIC 0x9123683E
#endif
#define LOOPBACK_IFINDEX 1
#endif
+#if !HAVE_DECL_IFA_FLAGS
+#define IFA_FLAGS 8
+#endif
+
+#ifndef IFA_F_NOPREFIXROUTE
+#define IFA_F_NOPREFIXROUTE 0x200
+#endif
+
#ifndef MAX_AUDIT_MESSAGE_LENGTH
#define MAX_AUDIT_MESSAGE_LENGTH 8970
#endif
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
+
+#if !HAVE_DECL_KCMP
+static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
+ return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
+}
+#endif
+
+#ifndef KCMP_FILE
+#define KCMP_FILE 0
+#endif
+
+#ifndef INPUT_PROP_POINTING_STICK
+#define INPUT_PROP_POINTING_STICK 0x05
+#endif
+
+#ifndef INPUT_PROP_ACCELEROMETER
+#define INPUT_PROP_ACCELEROMETER 0x06
+#endif
REMOVE_ONLY_DIRECTORIES = 1,
REMOVE_ROOT = 2,
REMOVE_PHYSICAL = 4, /* if not set, only removes files on tmpfs, never physical file systems */
+ REMOVE_SUBVOLUME = 8,
} RemoveFlags;
int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "in-addr-util.h"
+#define VERB_ANY ((unsigned) -1)
+#define VERB_DEFAULT 1
-typedef struct DnsServer DnsServer;
-typedef enum DnsServerSource DnsServerSource;
+typedef struct {
+ const char *verb;
+ unsigned min_args, max_args;
+ unsigned flags;
+ int (* const dispatch)(int argc, char *argv[], void *userdata);
+} Verb;
-typedef enum DnsServerType {
- DNS_SERVER_SYSTEM,
- DNS_SERVER_FALLBACK,
- DNS_SERVER_LINK,
-} DnsServerType;
-
-#include "resolved-link.h"
-
-struct DnsServer {
- Manager *manager;
-
- unsigned n_ref;
-
- DnsServerType type;
-
- Link *link;
-
- int family;
- union in_addr_union address;
-
- bool marked:1;
-
- LIST_FIELDS(DnsServer, servers);
-};
-
-int dns_server_new(
- Manager *m,
- DnsServer **s,
- DnsServerType type,
- Link *l,
- int family,
- const union in_addr_union *address);
-
-DnsServer* dns_server_ref(DnsServer *s);
-DnsServer* dns_server_unref(DnsServer *s);
-
-extern const struct hash_ops dns_server_hash_ops;
+int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);
+++ /dev/null
-../Makefile
\ No newline at end of file
LIBSYSTEMD_209 {
global:
/* sd-journal */
- sd_journal_print;
- sd_journal_printv;
- sd_journal_send;
- sd_journal_sendv;
- sd_journal_stream_fd;
- sd_journal_open;
- sd_journal_close;
- sd_journal_previous;
- sd_journal_next;
- sd_journal_previous_skip;
- sd_journal_next_skip;
- sd_journal_get_realtime_usec;
- sd_journal_get_monotonic_usec;
- sd_journal_get_data;
- sd_journal_enumerate_data;
- sd_journal_restart_data;
- sd_journal_add_match;
- sd_journal_flush_matches;
- sd_journal_seek_head;
- sd_journal_seek_tail;
- sd_journal_seek_monotonic_usec;
- sd_journal_seek_realtime_usec;
- sd_journal_seek_cursor;
- sd_journal_get_cursor;
- sd_journal_get_fd;
- sd_journal_process;
- sd_journal_print_with_location;
- sd_journal_printv_with_location;
- sd_journal_send_with_location;
- sd_journal_sendv_with_location;
- sd_journal_get_cutoff_realtime_usec;
- sd_journal_get_cutoff_monotonic_usec;
- sd_journal_wait;
- sd_journal_open_directory;
- sd_journal_add_disjunction;
- sd_journal_perror;
- sd_journal_perror_with_location;
- sd_journal_get_usage;
- sd_journal_test_cursor;
- sd_journal_query_unique;
- sd_journal_enumerate_unique;
- sd_journal_restart_unique;
- sd_journal_get_catalog;
- sd_journal_get_catalog_for_message_id;
- sd_journal_set_data_threshold;
- sd_journal_get_data_threshold;
- sd_journal_reliable_fd;
- sd_journal_get_events;
- sd_journal_get_timeout;
- sd_journal_add_conjunction;
- sd_journal_open_files;
- sd_journal_open_container;
+ /* sd_journal_print; */
+ /* sd_journal_printv; */
+ /* sd_journal_send; */
+ /* sd_journal_sendv; */
+ /* sd_journal_stream_fd; */
+ /* sd_journal_open; */
+ /* sd_journal_close; */
+ /* sd_journal_previous; */
+ /* sd_journal_next; */
+ /* sd_journal_previous_skip; */
+ /* sd_journal_next_skip; */
+ /* sd_journal_get_realtime_usec; */
+ /* sd_journal_get_monotonic_usec; */
+ /* sd_journal_get_data; */
+ /* sd_journal_enumerate_data; */
+ /* sd_journal_restart_data; */
+ /* sd_journal_add_match; */
+ /* sd_journal_flush_matches; */
+ /* sd_journal_seek_head; */
+ /* sd_journal_seek_tail; */
+ /* sd_journal_seek_monotonic_usec; */
+ /* sd_journal_seek_realtime_usec; */
+ /* sd_journal_seek_cursor; */
+ /* sd_journal_get_cursor; */
+ /* sd_journal_get_fd; */
+ /* sd_journal_process; */
+ /* sd_journal_print_with_location; */
+ /* sd_journal_printv_with_location; */
+ /* sd_journal_send_with_location; */
+ /* sd_journal_sendv_with_location; */
+ /* sd_journal_get_cutoff_realtime_usec; */
+ /* sd_journal_get_cutoff_monotonic_usec; */
+ /* sd_journal_wait; */
+ /* sd_journal_open_directory; */
+ /* sd_journal_add_disjunction; */
+ /* sd_journal_perror; */
+ /* sd_journal_perror_with_location; */
+ /* sd_journal_get_usage; */
+ /* sd_journal_test_cursor; */
+ /* sd_journal_query_unique; */
+ /* sd_journal_enumerate_unique; */
+ /* sd_journal_restart_unique; */
+ /* sd_journal_get_catalog; */
+ /* sd_journal_get_catalog_for_message_id; */
+ /* sd_journal_set_data_threshold; */
+ /* sd_journal_get_data_threshold; */
+ /* sd_journal_reliable_fd; */
+ /* sd_journal_get_events; */
+ /* sd_journal_get_timeout; */
+ /* sd_journal_add_conjunction; */
+ /* sd_journal_open_files; */
+ /* sd_journal_open_container; */
/* sd-daemon */
/* sd_booted; */
sd_bus_new;
sd_bus_set_address;
sd_bus_set_fd;
- sd_bus_set_exec;
- sd_bus_get_address;
- sd_bus_set_bus_client;
- sd_bus_is_bus_client;
+ /* sd_bus_set_exec; */
+ /* sd_bus_get_address; */
+ /* sd_bus_set_bus_client; */
+ /* sd_bus_is_bus_client; */
sd_bus_set_server;
- sd_bus_is_server;
- sd_bus_set_anonymous;
- sd_bus_is_anonymous;
- sd_bus_set_trusted;
- sd_bus_is_trusted;
- sd_bus_set_monitor;
- sd_bus_is_monitor;
- sd_bus_set_description;
- sd_bus_get_description;
+ /* sd_bus_is_server; */
+ /* sd_bus_set_anonymous; */
+ /* sd_bus_is_anonymous; */
+ /* sd_bus_set_trusted; */
+ /* sd_bus_is_trusted; */
+ /* sd_bus_set_monitor; */
+ /* sd_bus_is_monitor; */
+ /* sd_bus_set_description; */
+ /* sd_bus_get_description; */
sd_bus_negotiate_creds;
- sd_bus_negotiate_timestamp;
- sd_bus_negotiate_fds;
+ /* sd_bus_negotiate_timestamp; */
+ /* sd_bus_negotiate_fds; */
sd_bus_can_send;
- sd_bus_get_creds_mask;
+ /* sd_bus_get_creds_mask; */
sd_bus_set_allow_interactive_authorization;
- sd_bus_get_allow_interactive_authorization;
+ /* sd_bus_get_allow_interactive_authorization; */
sd_bus_start;
sd_bus_close;
sd_bus_try_close;
sd_bus_ref;
sd_bus_unref;
- sd_bus_is_open;
- sd_bus_get_bus_id;
- sd_bus_get_scope;
- sd_bus_get_tid;
+ /* sd_bus_is_open; */
+ /* sd_bus_get_bus_id; */
+ /* sd_bus_get_scope; */
+ /* sd_bus_get_tid; */
sd_bus_get_owner_creds;
sd_bus_send;
sd_bus_send_to;
sd_bus_get_events;
sd_bus_get_timeout;
sd_bus_process;
- sd_bus_process_priority;
+ /* sd_bus_process_priority; */
sd_bus_wait;
sd_bus_flush;
- sd_bus_get_current_slot;
+ /* sd_bus_get_current_slot; */
sd_bus_get_current_message;
sd_bus_get_current_handler;
sd_bus_get_current_userdata;
sd_bus_add_object_vtable;
sd_bus_add_fallback_vtable;
sd_bus_add_node_enumerator;
- sd_bus_add_object_manager;
+ /* sd_bus_add_object_manager; */
sd_bus_slot_ref;
sd_bus_slot_unref;
- sd_bus_slot_get_bus;
- sd_bus_slot_get_userdata;
- sd_bus_slot_set_userdata;
- sd_bus_slot_get_description;
- sd_bus_slot_set_description;
- sd_bus_slot_get_current_message;
- sd_bus_slot_get_current_handler;
- sd_bus_slot_get_current_userdata;
+ /* sd_bus_slot_get_bus; */
+ /* sd_bus_slot_get_userdata; */
+ /* sd_bus_slot_set_userdata; */
+ /* sd_bus_slot_get_description; */
+ /* sd_bus_slot_set_description; */
+ /* sd_bus_slot_get_current_message; */
+ /* sd_bus_slot_get_current_handler; */
+ /* sd_bus_slot_get_current_userdata; */
sd_bus_message_new_signal;
sd_bus_message_new_method_call;
sd_bus_message_new_method_return;
sd_bus_message_new_method_error;
sd_bus_message_new_method_errorf;
sd_bus_message_new_method_errno;
- sd_bus_message_new_method_errnof;
+ /* sd_bus_message_new_method_errnof; */
sd_bus_message_ref;
sd_bus_message_unref;
- sd_bus_message_get_type;
- sd_bus_message_get_cookie;
- sd_bus_message_get_reply_cookie;
- sd_bus_message_get_priority;
- sd_bus_message_get_expect_reply;
- sd_bus_message_get_auto_start;
+ /* sd_bus_message_get_type; */
+ /* sd_bus_message_get_cookie; */
+ /* sd_bus_message_get_reply_cookie; */
+ /* sd_bus_message_get_priority; */
+ /* sd_bus_message_get_expect_reply; */
+ /* sd_bus_message_get_auto_start; */
sd_bus_message_get_allow_interactive_authorization;
sd_bus_message_get_signature;
sd_bus_message_get_path;
sd_bus_message_get_sender;
sd_bus_message_get_error;
sd_bus_message_get_errno;
- sd_bus_message_get_monotonic_usec;
- sd_bus_message_get_realtime_usec;
- sd_bus_message_get_seqnum;
+ /* sd_bus_message_get_monotonic_usec; */
+ /* sd_bus_message_get_realtime_usec; */
+ /* sd_bus_message_get_seqnum; */
sd_bus_message_get_bus;
sd_bus_message_get_creds;
- sd_bus_message_is_signal;
+ /* sd_bus_message_is_signal; */
sd_bus_message_is_method_call;
sd_bus_message_is_method_error;
- sd_bus_message_is_empty;
- sd_bus_message_has_signature;
- sd_bus_message_set_expect_reply;
+ /* sd_bus_message_is_empty; */
+ /* sd_bus_message_has_signature; */
+ /* sd_bus_message_set_expect_reply; */
sd_bus_message_set_auto_start;
- sd_bus_message_set_allow_interactive_authorization;
+ /* sd_bus_message_set_allow_interactive_authorization; */
sd_bus_message_set_destination;
- sd_bus_message_set_priority;
+ /* sd_bus_message_set_priority; */
sd_bus_message_append;
sd_bus_message_append_basic;
sd_bus_message_append_array;
sd_bus_message_append_array_space;
- sd_bus_message_append_array_iovec;
- sd_bus_message_append_array_memfd;
+ /* sd_bus_message_append_array_iovec; */
+ /* sd_bus_message_append_array_memfd; */
sd_bus_message_append_string_space;
- sd_bus_message_append_string_iovec;
- sd_bus_message_append_string_memfd;
+ /* sd_bus_message_append_string_iovec; */
+ /* sd_bus_message_append_string_memfd; */
sd_bus_message_append_strv;
sd_bus_message_open_container;
sd_bus_message_close_container;
sd_bus_message_enter_container;
sd_bus_message_exit_container;
sd_bus_message_peek_type;
- sd_bus_message_verify_type;
- sd_bus_message_at_end;
+ /* sd_bus_message_verify_type; */
+ /* sd_bus_message_at_end; */
sd_bus_message_rewind;
sd_bus_get_unique_name;
sd_bus_request_name;
sd_bus_release_name;
sd_bus_list_names;
sd_bus_get_name_creds;
- sd_bus_get_name_machine_id;
+ /* sd_bus_get_name_machine_id; */
sd_bus_call_method;
- sd_bus_call_method_async;
+ /* sd_bus_call_method_async; */
sd_bus_get_property;
- sd_bus_get_property_trivial;
+ /* sd_bus_get_property_trivial; */
sd_bus_get_property_string;
- sd_bus_get_property_strv;
- sd_bus_set_property;
+ /* sd_bus_get_property_strv; */
+ /* sd_bus_set_property; */
sd_bus_reply_method_return;
sd_bus_reply_method_error;
sd_bus_reply_method_errorf;
sd_bus_reply_method_errno;
- sd_bus_reply_method_errnof;
+ /* sd_bus_reply_method_errnof; */
sd_bus_emit_signal;
sd_bus_emit_properties_changed_strv;
sd_bus_emit_properties_changed;
sd_bus_emit_interfaces_removed;
sd_bus_query_sender_creds;
sd_bus_query_sender_privilege;
- sd_bus_creds_new_from_pid;
+ /* sd_bus_creds_new_from_pid; */
sd_bus_creds_ref;
sd_bus_creds_unref;
- sd_bus_creds_get_mask;
+ /* sd_bus_creds_get_mask; */
sd_bus_creds_get_augmented_mask;
sd_bus_creds_get_pid;
- sd_bus_creds_get_ppid;
+ /* sd_bus_creds_get_ppid; */
sd_bus_creds_get_tid;
sd_bus_creds_get_uid;
sd_bus_creds_get_euid;
- sd_bus_creds_get_suid;
- sd_bus_creds_get_fsuid;
- sd_bus_creds_get_gid;
+ /* sd_bus_creds_get_suid; */
+ /* sd_bus_creds_get_fsuid; */
+ /* sd_bus_creds_get_gid; */
sd_bus_creds_get_egid;
- sd_bus_creds_get_sgid;
- sd_bus_creds_get_fsgid;
- sd_bus_creds_get_supplementary_gids;
- sd_bus_creds_get_comm;
- sd_bus_creds_get_tid_comm;
- sd_bus_creds_get_exe;
+ /* sd_bus_creds_get_sgid; */
+ /* sd_bus_creds_get_fsgid; */
+ /* sd_bus_creds_get_supplementary_gids; */
+ /* sd_bus_creds_get_comm; */
+ /* sd_bus_creds_get_tid_comm; */
+ /* sd_bus_creds_get_exe; */
sd_bus_creds_get_cmdline;
- sd_bus_creds_get_cgroup;
- sd_bus_creds_get_unit;
- sd_bus_creds_get_slice;
- sd_bus_creds_get_user_unit;
- sd_bus_creds_get_user_slice;
+ /* sd_bus_creds_get_cgroup; */
+ /* sd_bus_creds_get_unit; */
+ /* sd_bus_creds_get_slice; */
+ /* sd_bus_creds_get_user_unit; */
+ /* sd_bus_creds_get_user_slice; */
sd_bus_creds_get_session;
sd_bus_creds_get_owner_uid;
sd_bus_creds_has_effective_cap;
- sd_bus_creds_has_permitted_cap;
- sd_bus_creds_has_inheritable_cap;
- sd_bus_creds_has_bounding_cap;
+ /* sd_bus_creds_has_permitted_cap; */
+ /* sd_bus_creds_has_inheritable_cap; */
+ /* sd_bus_creds_has_bounding_cap; */
sd_bus_creds_get_selinux_context;
- sd_bus_creds_get_audit_session_id;
+ /* sd_bus_creds_get_audit_session_id; */
sd_bus_creds_get_audit_login_uid;
sd_bus_creds_get_tty;
- sd_bus_creds_get_unique_name;
- sd_bus_creds_get_well_known_names;
- sd_bus_creds_get_description;
+ /* sd_bus_creds_get_unique_name; */
+ /* sd_bus_creds_get_well_known_names; */
+ /* sd_bus_creds_get_description; */
sd_bus_error_free;
sd_bus_error_set;
sd_bus_error_setf;
sd_bus_error_is_set;
sd_bus_error_has_name;
sd_bus_error_add_map;
- sd_bus_path_encode;
- sd_bus_path_decode;
+ /* sd_bus_path_encode; */
+ /* sd_bus_path_decode; */
sd_bus_track_new;
sd_bus_track_ref;
sd_bus_track_unref;
sd_bus_track_get_bus;
- sd_bus_track_get_userdata;
- sd_bus_track_set_userdata;
+ /* sd_bus_track_get_userdata; */
+ /* sd_bus_track_set_userdata; */
sd_bus_track_add_sender;
sd_bus_track_remove_sender;
sd_bus_track_add_name;
sd_event_wait;
sd_event_dispatch;
sd_event_run;
- sd_event_loop;
+ /* sd_event_loop; */
sd_event_exit;
- sd_event_now;
- sd_event_get_fd;
+ /* sd_event_now; */
+ /* sd_event_get_fd; */
sd_event_get_state;
sd_event_get_tid;
sd_event_get_exit_code;
sd_event_set_watchdog;
- sd_event_get_watchdog;
- sd_event_source_ref;
+ /* sd_event_get_watchdog; */
+ /* sd_event_source_ref; */
sd_event_source_unref;
sd_event_source_get_event;
- sd_event_source_get_userdata;
- sd_event_source_set_userdata;
+ /* sd_event_source_get_userdata; */
+ /* sd_event_source_set_userdata; */
sd_event_source_set_description;
- sd_event_source_get_description;
+ /* sd_event_source_get_description; */
sd_event_source_set_prepare;
- sd_event_source_get_pending;
- sd_event_source_get_priority;
+ /* sd_event_source_get_pending; */
+ /* sd_event_source_get_priority; */
sd_event_source_set_priority;
- sd_event_source_get_enabled;
+ /* sd_event_source_get_enabled; */
sd_event_source_set_enabled;
- sd_event_source_get_io_fd;
+ /* sd_event_source_get_io_fd; */
sd_event_source_set_io_fd;
- sd_event_source_get_io_events;
+ /* sd_event_source_get_io_events; */
sd_event_source_set_io_events;
- sd_event_source_get_io_revents;
+ /* sd_event_source_get_io_revents; */
sd_event_source_get_time;
sd_event_source_set_time;
- sd_event_source_set_time_accuracy;
- sd_event_source_get_time_accuracy;
- sd_event_source_get_time_clock;
- sd_event_source_get_signal;
- sd_event_source_get_child_pid;
+ /* sd_event_source_set_time_accuracy; */
+ /* sd_event_source_get_time_accuracy; */
+ /* sd_event_source_get_time_clock; */
+ /* sd_event_source_get_signal; */
+ /* sd_event_source_get_child_pid; */
} LIBSYSTEMD_220;
LIBSYSTEMD_222 {
global:
/* sd-bus */
sd_bus_emit_object_added;
- sd_bus_emit_object_removed;
+ /* sd_bus_emit_object_removed; */
sd_bus_flush_close_unref;
} LIBSYSTEMD_221;
+++ /dev/null
-/***
- This file is part of systemd.
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-***/
-
-LIBSYSTEMD_209 {
-global:
- /* sd-journal */
- sd_journal_print;
- sd_journal_printv;
- sd_journal_send;
- sd_journal_sendv;
- sd_journal_stream_fd;
- sd_journal_open;
- sd_journal_close;
- sd_journal_previous;
- sd_journal_next;
- sd_journal_previous_skip;
- sd_journal_next_skip;
- sd_journal_get_realtime_usec;
- sd_journal_get_monotonic_usec;
- sd_journal_get_data;
- sd_journal_enumerate_data;
- sd_journal_restart_data;
- sd_journal_add_match;
- sd_journal_flush_matches;
- sd_journal_seek_head;
- sd_journal_seek_tail;
- sd_journal_seek_monotonic_usec;
- sd_journal_seek_realtime_usec;
- sd_journal_seek_cursor;
- sd_journal_get_cursor;
- sd_journal_get_fd;
- sd_journal_process;
- sd_journal_print_with_location;
- sd_journal_printv_with_location;
- sd_journal_send_with_location;
- sd_journal_sendv_with_location;
- sd_journal_get_cutoff_realtime_usec;
- sd_journal_get_cutoff_monotonic_usec;
- sd_journal_wait;
- sd_journal_open_directory;
- sd_journal_add_disjunction;
- sd_journal_perror;
- sd_journal_perror_with_location;
- sd_journal_get_usage;
- sd_journal_test_cursor;
- sd_journal_query_unique;
- sd_journal_enumerate_unique;
- sd_journal_restart_unique;
- sd_journal_get_catalog;
- sd_journal_get_catalog_for_message_id;
- sd_journal_set_data_threshold;
- sd_journal_get_data_threshold;
- sd_journal_reliable_fd;
- sd_journal_get_events;
- sd_journal_get_timeout;
- sd_journal_add_conjunction;
- sd_journal_open_files;
- sd_journal_open_container;
-
- /* sd-daemon */
- sd_booted;
- sd_is_fifo;
- sd_is_mq;
- sd_is_socket;
- sd_is_socket_inet;
- sd_is_socket_unix;
- sd_is_special;
- sd_listen_fds;
- sd_notify;
- sd_notifyf;
- sd_watchdog_enabled;
-
- /* sd-id128 */
- sd_id128_to_string;
- sd_id128_from_string;
- sd_id128_randomize;
- sd_id128_get_machine;
- sd_id128_get_boot;
-
- /* sd-login */
- sd_get_seats;
- sd_get_sessions;
- sd_get_uids;
- sd_login_monitor_flush;
- sd_login_monitor_get_fd;
- sd_login_monitor_new;
- sd_login_monitor_unref;
- sd_pid_get_owner_uid;
- sd_pid_get_session;
- sd_seat_can_multi_session;
- sd_seat_get_active;
- sd_seat_get_sessions;
- sd_session_get_seat;
- sd_session_get_uid;
- sd_session_is_active;
- sd_uid_get_seats;
- sd_uid_get_sessions;
- sd_uid_get_state;
- sd_uid_is_on_seat;
- sd_pid_get_unit;
- sd_session_get_service;
- sd_session_get_type;
- sd_session_get_class;
- sd_session_get_display;
- sd_session_get_state;
- sd_seat_can_tty;
- sd_seat_can_graphical;
- sd_session_get_tty;
- sd_login_monitor_get_events;
- sd_login_monitor_get_timeout;
- sd_pid_get_user_unit;
- sd_pid_get_machine_name;
- sd_get_machine_names;
- sd_pid_get_slice;
- sd_session_get_vt;
- sd_session_is_remote;
- sd_session_get_remote_user;
- sd_session_get_remote_host;
-local:
- *;
-};
-
-LIBSYSTEMD_211 {
-global:
- sd_machine_get_class;
- sd_peer_get_session;
- sd_peer_get_owner_uid;
- sd_peer_get_unit;
- sd_peer_get_user_unit;
- sd_peer_get_machine_name;
- sd_peer_get_slice;
-} LIBSYSTEMD_209;
-
-LIBSYSTEMD_213 {
-global:
- sd_uid_get_display;
-} LIBSYSTEMD_211;
-
-LIBSYSTEMD_214 {
-global:
- sd_pid_notify;
- sd_pid_notifyf;
-} LIBSYSTEMD_213;
-
-LIBSYSTEMD_216 {
-global:
- sd_machine_get_ifindices;
-} LIBSYSTEMD_214;
-
-LIBSYSTEMD_217 {
-global:
- sd_session_get_desktop;
-} LIBSYSTEMD_216;
-
-LIBSYSTEMD_219 {
-global:
- sd_pid_notify_with_fds;
-} LIBSYSTEMD_217;
-
-LIBSYSTEMD_220 {
-global:
- sd_pid_get_user_slice;
- sd_peer_get_user_slice;
-} LIBSYSTEMD_219;
-
-LIBSYSTEMD_221 {
-global:
- /* sd-bus */
- sd_bus_default;
- sd_bus_default_user;
- sd_bus_default_system;
- sd_bus_open;
- sd_bus_open_user;
- sd_bus_open_system;
- sd_bus_open_system_remote;
- sd_bus_open_system_machine;
- sd_bus_new;
- sd_bus_set_address;
- sd_bus_set_fd;
- sd_bus_set_exec;
- sd_bus_get_address;
- sd_bus_set_bus_client;
- sd_bus_is_bus_client;
- sd_bus_set_server;
- sd_bus_is_server;
- sd_bus_set_anonymous;
- sd_bus_is_anonymous;
- sd_bus_set_trusted;
- sd_bus_is_trusted;
- sd_bus_set_monitor;
- sd_bus_is_monitor;
- sd_bus_set_description;
- sd_bus_get_description;
- sd_bus_negotiate_creds;
- sd_bus_negotiate_timestamp;
- sd_bus_negotiate_fds;
- sd_bus_can_send;
- sd_bus_get_creds_mask;
- sd_bus_set_allow_interactive_authorization;
- sd_bus_get_allow_interactive_authorization;
- sd_bus_start;
- sd_bus_close;
- sd_bus_try_close;
- sd_bus_ref;
- sd_bus_unref;
- sd_bus_is_open;
- sd_bus_get_bus_id;
- sd_bus_get_scope;
- sd_bus_get_tid;
- sd_bus_get_owner_creds;
- sd_bus_send;
- sd_bus_send_to;
- sd_bus_call;
- sd_bus_call_async;
- sd_bus_get_fd;
- sd_bus_get_events;
- sd_bus_get_timeout;
- sd_bus_process;
- sd_bus_process_priority;
- sd_bus_wait;
- sd_bus_flush;
- sd_bus_get_current_slot;
- sd_bus_get_current_message;
- sd_bus_get_current_handler;
- sd_bus_get_current_userdata;
- sd_bus_attach_event;
- sd_bus_detach_event;
- sd_bus_get_event;
- sd_bus_add_filter;
- sd_bus_add_match;
- sd_bus_add_object;
- sd_bus_add_fallback;
- sd_bus_add_object_vtable;
- sd_bus_add_fallback_vtable;
- sd_bus_add_node_enumerator;
- sd_bus_add_object_manager;
- sd_bus_slot_ref;
- sd_bus_slot_unref;
- sd_bus_slot_get_bus;
- sd_bus_slot_get_userdata;
- sd_bus_slot_set_userdata;
- sd_bus_slot_get_description;
- sd_bus_slot_set_description;
- sd_bus_slot_get_current_message;
- sd_bus_slot_get_current_handler;
- sd_bus_slot_get_current_userdata;
- sd_bus_message_new_signal;
- sd_bus_message_new_method_call;
- sd_bus_message_new_method_return;
- sd_bus_message_new_method_error;
- sd_bus_message_new_method_errorf;
- sd_bus_message_new_method_errno;
- sd_bus_message_new_method_errnof;
- sd_bus_message_ref;
- sd_bus_message_unref;
- sd_bus_message_get_type;
- sd_bus_message_get_cookie;
- sd_bus_message_get_reply_cookie;
- sd_bus_message_get_priority;
- sd_bus_message_get_expect_reply;
- sd_bus_message_get_auto_start;
- sd_bus_message_get_allow_interactive_authorization;
- sd_bus_message_get_signature;
- sd_bus_message_get_path;
- sd_bus_message_get_interface;
- sd_bus_message_get_member;
- sd_bus_message_get_destination;
- sd_bus_message_get_sender;
- sd_bus_message_get_error;
- sd_bus_message_get_errno;
- sd_bus_message_get_monotonic_usec;
- sd_bus_message_get_realtime_usec;
- sd_bus_message_get_seqnum;
- sd_bus_message_get_bus;
- sd_bus_message_get_creds;
- sd_bus_message_is_signal;
- sd_bus_message_is_method_call;
- sd_bus_message_is_method_error;
- sd_bus_message_is_empty;
- sd_bus_message_has_signature;
- sd_bus_message_set_expect_reply;
- sd_bus_message_set_auto_start;
- sd_bus_message_set_allow_interactive_authorization;
- sd_bus_message_set_destination;
- sd_bus_message_set_priority;
- sd_bus_message_append;
- sd_bus_message_append_basic;
- sd_bus_message_append_array;
- sd_bus_message_append_array_space;
- sd_bus_message_append_array_iovec;
- sd_bus_message_append_array_memfd;
- sd_bus_message_append_string_space;
- sd_bus_message_append_string_iovec;
- sd_bus_message_append_string_memfd;
- sd_bus_message_append_strv;
- sd_bus_message_open_container;
- sd_bus_message_close_container;
- sd_bus_message_copy;
- sd_bus_message_read;
- sd_bus_message_read_basic;
- sd_bus_message_read_array;
- sd_bus_message_read_strv;
- sd_bus_message_skip;
- sd_bus_message_enter_container;
- sd_bus_message_exit_container;
- sd_bus_message_peek_type;
- sd_bus_message_verify_type;
- sd_bus_message_at_end;
- sd_bus_message_rewind;
- sd_bus_get_unique_name;
- sd_bus_request_name;
- sd_bus_release_name;
- sd_bus_list_names;
- sd_bus_get_name_creds;
- sd_bus_get_name_machine_id;
- sd_bus_call_method;
- sd_bus_call_method_async;
- sd_bus_get_property;
- sd_bus_get_property_trivial;
- sd_bus_get_property_string;
- sd_bus_get_property_strv;
- sd_bus_set_property;
- sd_bus_reply_method_return;
- sd_bus_reply_method_error;
- sd_bus_reply_method_errorf;
- sd_bus_reply_method_errno;
- sd_bus_reply_method_errnof;
- sd_bus_emit_signal;
- sd_bus_emit_properties_changed_strv;
- sd_bus_emit_properties_changed;
- sd_bus_emit_interfaces_added_strv;
- sd_bus_emit_interfaces_added;
- sd_bus_emit_interfaces_removed_strv;
- sd_bus_emit_interfaces_removed;
- sd_bus_query_sender_creds;
- sd_bus_query_sender_privilege;
- sd_bus_creds_new_from_pid;
- sd_bus_creds_ref;
- sd_bus_creds_unref;
- sd_bus_creds_get_mask;
- sd_bus_creds_get_augmented_mask;
- sd_bus_creds_get_pid;
- sd_bus_creds_get_ppid;
- sd_bus_creds_get_tid;
- sd_bus_creds_get_uid;
- sd_bus_creds_get_euid;
- sd_bus_creds_get_suid;
- sd_bus_creds_get_fsuid;
- sd_bus_creds_get_gid;
- sd_bus_creds_get_egid;
- sd_bus_creds_get_sgid;
- sd_bus_creds_get_fsgid;
- sd_bus_creds_get_supplementary_gids;
- sd_bus_creds_get_comm;
- sd_bus_creds_get_tid_comm;
- sd_bus_creds_get_exe;
- sd_bus_creds_get_cmdline;
- sd_bus_creds_get_cgroup;
- sd_bus_creds_get_unit;
- sd_bus_creds_get_slice;
- sd_bus_creds_get_user_unit;
- sd_bus_creds_get_user_slice;
- sd_bus_creds_get_session;
- sd_bus_creds_get_owner_uid;
- sd_bus_creds_has_effective_cap;
- sd_bus_creds_has_permitted_cap;
- sd_bus_creds_has_inheritable_cap;
- sd_bus_creds_has_bounding_cap;
- sd_bus_creds_get_selinux_context;
- sd_bus_creds_get_audit_session_id;
- sd_bus_creds_get_audit_login_uid;
- sd_bus_creds_get_tty;
- sd_bus_creds_get_unique_name;
- sd_bus_creds_get_well_known_names;
- sd_bus_creds_get_description;
- sd_bus_error_free;
- sd_bus_error_set;
- sd_bus_error_setf;
- sd_bus_error_set_const;
- sd_bus_error_set_errno;
- sd_bus_error_set_errnof;
- sd_bus_error_set_errnofv;
- sd_bus_error_get_errno;
- sd_bus_error_copy;
- sd_bus_error_is_set;
- sd_bus_error_has_name;
- sd_bus_error_add_map;
- sd_bus_path_encode;
- sd_bus_path_decode;
- sd_bus_track_new;
- sd_bus_track_ref;
- sd_bus_track_unref;
- sd_bus_track_get_bus;
- sd_bus_track_get_userdata;
- sd_bus_track_set_userdata;
- sd_bus_track_add_sender;
- sd_bus_track_remove_sender;
- sd_bus_track_add_name;
- sd_bus_track_remove_name;
- sd_bus_track_count;
- sd_bus_track_contains;
- sd_bus_track_first;
- sd_bus_track_next;
-
- /* sd-event */
- sd_event_default;
- sd_event_new;
- sd_event_ref;
- sd_event_unref;
- sd_event_add_io;
- sd_event_add_time;
- sd_event_add_signal;
- sd_event_add_child;
- sd_event_add_defer;
- sd_event_add_post;
- sd_event_add_exit;
- sd_event_prepare;
- sd_event_wait;
- sd_event_dispatch;
- sd_event_run;
- sd_event_loop;
- sd_event_exit;
- sd_event_now;
- sd_event_get_fd;
- sd_event_get_state;
- sd_event_get_tid;
- sd_event_get_exit_code;
- sd_event_set_watchdog;
- sd_event_get_watchdog;
- sd_event_source_ref;
- sd_event_source_unref;
- sd_event_source_get_event;
- sd_event_source_get_userdata;
- sd_event_source_set_userdata;
- sd_event_source_set_description;
- sd_event_source_get_description;
- sd_event_source_set_prepare;
- sd_event_source_get_pending;
- sd_event_source_get_priority;
- sd_event_source_set_priority;
- sd_event_source_get_enabled;
- sd_event_source_set_enabled;
- sd_event_source_get_io_fd;
- sd_event_source_set_io_fd;
- sd_event_source_get_io_events;
- sd_event_source_set_io_events;
- sd_event_source_get_io_revents;
- sd_event_source_get_time;
- sd_event_source_set_time;
- sd_event_source_set_time_accuracy;
- sd_event_source_get_time_accuracy;
- sd_event_source_get_time_clock;
- sd_event_source_get_signal;
- sd_event_source_get_child_pid;
-} LIBSYSTEMD_220;
-
-m4_ifdef(`ENABLE_KDBUS',
-LIBSYSTEMD_FUTURE {
-global:
- /* sd-utf8 */
- sd_utf8_is_valid;
- sd_ascii_is_valid;
-
- /* sd-resolve */
- sd_resolve_default;
- sd_resolve_new;
- sd_resolve_ref;
- sd_resolve_unref;
- sd_resolve_get_fd;
- sd_resolve_get_events;
- sd_resolve_get_timeout;
- sd_resolve_process;
- sd_resolve_wait;
- sd_resolve_get_tid;
- sd_resolve_attach_event;
- sd_resolve_detach_event;
- sd_resolve_get_event;
- sd_resolve_getaddrinfo;
- sd_resolve_getnameinfo;
- sd_resolve_res_query;
- sd_resolve_res_search;
- sd_resolve_query_ref;
- sd_resolve_query_unref;
- sd_resolve_query_is_done;
- sd_resolve_query_get_userdata;
- sd_resolve_query_set_userdata;
- sd_resolve_query_get_resolve;
-
- /* sd-path */
- sd_path_home;
- sd_path_search;
-} LIBSYSTEMD_220;
-)
+++ /dev/null
-../../Makefile
\ No newline at end of file
/***
This file is part of systemd.
- Copyright 2014 David Herrmann
+ Copyright 2013 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "sd-bus.h"
-#include "bus-xml-policy.h"
-
-typedef struct Proxy Proxy;
-typedef struct ProxyActivation ProxyActivation;
-
-#define PROXY_ACTIVATIONS_MAX (16) /* max parallel activation requests */
-
-struct Proxy {
- sd_bus *local_bus;
- struct ucred local_creds;
- int local_in;
- int local_out;
-
- sd_bus *destination_bus;
-
- Set *owned_names;
- SharedPolicy *policy;
+#include <stdio.h>
- LIST_HEAD(ProxyActivation, activations);
- size_t n_activations;
-
- bool got_hello : 1;
- bool queue_overflow : 1;
- bool message_matched : 1;
- bool synthetic_matched : 1;
-};
+#include "sd-bus.h"
+#include "set.h"
-struct ProxyActivation {
- LIST_FIELDS(ProxyActivation, activations_by_proxy);
- Proxy *proxy;
- sd_bus_message *request;
- sd_bus_slot *slot;
+struct introspect {
+ FILE *f;
+ char *introspection;
+ size_t size;
+ bool trusted;
};
-int proxy_new(Proxy **out, int in_fd, int out_fd, const char *dest);
-Proxy *proxy_free(Proxy *p);
-
-int proxy_set_policy(Proxy *p, SharedPolicy *policy, char **configuration);
-int proxy_hello_policy(Proxy *p, uid_t original_uid);
-int proxy_match(sd_bus_message *m, void *userdata, sd_bus_error *error);
-int proxy_run(Proxy *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Proxy*, proxy_free);
+int introspect_begin(struct introspect *i, bool trusted);
+int introspect_write_default_interfaces(struct introspect *i, bool object_manager);
+int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix);
+int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v);
+int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_bus_message **reply);
+void introspect_free(struct introspect *i);
***/
#include "sd-bus.h"
-#include "bus-xml-policy.h"
-#include "proxy.h"
+#include "bus-internal.h"
-int bus_proxy_process_driver(Proxy *p, sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names);
+sd_bus_slot *bus_slot_allocate(sd_bus *bus, bool floating, BusSlotType type, size_t extra, void *userdata);
+
+void bus_slot_disconnect(sd_bus_slot *slot);
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <getopt.h>
-
-#include "strv.h"
-#include "util.h"
-#include "log.h"
-#include "build.h"
-#include "pager.h"
-#include "path-util.h"
-#include "set.h"
-
-#include "sd-bus.h"
-#include "bus-internal.h"
-#include "bus-util.h"
-#include "bus-dump.h"
-#include "bus-signature.h"
-#include "bus-type.h"
-#include "busctl-introspect.h"
-#include "terminal-util.h"
-
-static bool arg_no_pager = false;
-static bool arg_legend = true;
-static char *arg_address = NULL;
-static bool arg_unique = false;
-static bool arg_acquired = false;
-static bool arg_activatable = false;
-static bool arg_show_machine = false;
-static char **arg_matches = NULL;
-static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
-static char *arg_host = NULL;
-static bool arg_user = false;
-static size_t arg_snaplen = 4096;
-static bool arg_list = false;
-static bool arg_quiet = false;
-static bool arg_verbose = false;
-static bool arg_expect_reply = true;
-static bool arg_auto_start = true;
-static bool arg_allow_interactive_authorization = true;
-static bool arg_augment_creds = true;
-static usec_t arg_timeout = 0;
-
-static void pager_open_if_enabled(void) {
-
- /* Cache result before we open the pager */
- if (arg_no_pager)
- return;
-
- pager_open(false);
-}
-
-#define NAME_IS_ACQUIRED INT_TO_PTR(1)
-#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
-
-static int list_bus_names(sd_bus *bus, char **argv) {
- _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
- _cleanup_free_ char **merged = NULL;
- _cleanup_hashmap_free_ Hashmap *names = NULL;
- char **i;
- int r;
- size_t max_i = 0;
- unsigned n = 0;
- void *v;
- char *k;
- Iterator iterator;
-
- assert(bus);
-
- if (!arg_unique && !arg_acquired && !arg_activatable)
- arg_unique = arg_acquired = arg_activatable = true;
-
- r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to list names: %m");
-
- pager_open_if_enabled();
-
- names = hashmap_new(&string_hash_ops);
- if (!names)
- return log_oom();
-
- STRV_FOREACH(i, acquired) {
- max_i = MAX(max_i, strlen(*i));
-
- r = hashmap_put(names, *i, NAME_IS_ACQUIRED);
- if (r < 0)
- return log_error_errno(r, "Failed to add to hashmap: %m");
- }
-
- STRV_FOREACH(i, activatable) {
- max_i = MAX(max_i, strlen(*i));
-
- r = hashmap_put(names, *i, NAME_IS_ACTIVATABLE);
- if (r < 0 && r != -EEXIST)
- return log_error_errno(r, "Failed to add to hashmap: %m");
- }
-
- merged = new(char*, hashmap_size(names) + 1);
- HASHMAP_FOREACH_KEY(v, k, names, iterator)
- merged[n++] = k;
-
- merged[n] = NULL;
- strv_sort(merged);
-
- if (arg_legend) {
- printf("%-*s %*s %-*s %-*s %-*s %-*s %-*s %-*s",
- (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 13, "CONNECTION", 25, "UNIT", 10, "SESSION", 19, "DESCRIPTION");
-
- if (arg_show_machine)
- puts(" MACHINE");
- else
- putchar('\n');
- }
-
- STRV_FOREACH(i, merged) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- sd_id128_t mid;
-
- if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) {
- /* Activatable */
-
- printf("%-*s", (int) max_i, *i);
- printf(" - - - (activatable) - - ");
- if (arg_show_machine)
- puts(" -");
- else
- putchar('\n');
- continue;
-
- }
-
- if (!arg_unique && (*i)[0] == ':')
- continue;
-
- if (!arg_acquired && (*i)[0] != ':')
- continue;
-
- printf("%-*s", (int) max_i, *i);
-
- r = sd_bus_get_name_creds(
- bus, *i,
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
- SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
- SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
- SD_BUS_CREDS_DESCRIPTION, &creds);
- if (r >= 0) {
- const char *unique, *session, *unit, *cn;
- pid_t pid;
- uid_t uid;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r >= 0) {
- const char *comm = NULL;
-
- sd_bus_creds_get_comm(creds, &comm);
-
- printf(" %10lu %-15s", (unsigned long) pid, strna(comm));
- } else
- fputs(" - - ", stdout);
-
- r = sd_bus_creds_get_euid(creds, &uid);
- if (r >= 0) {
- _cleanup_free_ char *u = NULL;
-
- u = uid_to_name(uid);
- if (!u)
- return log_oom();
-
- if (strlen(u) > 16)
- u[16] = 0;
-
- printf(" %-16s", u);
- } else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_unique_name(creds, &unique);
- if (r >= 0)
- printf(" %-13s", unique);
- else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_unit(creds, &unit);
- if (r >= 0) {
- _cleanup_free_ char *e;
-
- e = ellipsize(unit, 25, 100);
- if (!e)
- return log_oom();
-
- printf(" %-25s", e);
- } else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_session(creds, &session);
- if (r >= 0)
- printf(" %-10s", session);
- else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_description(creds, &cn);
- if (r >= 0)
- printf(" %-19s", cn);
- else
- fputs(" - ", stdout);
-
- } else
- printf(" - - - - - - - ");
-
- if (arg_show_machine) {
- r = sd_bus_get_name_machine_id(bus, *i, &mid);
- if (r >= 0) {
- char m[SD_ID128_STRING_MAX];
- printf(" %s\n", sd_id128_to_string(mid, m));
- } else
- puts(" -");
- } else
- putchar('\n');
- }
-
- return 0;
-}
-
-static void print_subtree(const char *prefix, const char *path, char **l) {
- const char *vertical, *space;
- char **n;
-
- /* We assume the list is sorted. Let's first skip over the
- * entry we are looking at. */
- for (;;) {
- if (!*l)
- return;
-
- if (!streq(*l, path))
- break;
-
- l++;
- }
-
- vertical = strjoina(prefix, draw_special_char(DRAW_TREE_VERTICAL));
- space = strjoina(prefix, draw_special_char(DRAW_TREE_SPACE));
-
- for (;;) {
- bool has_more = false;
-
- if (!*l || !path_startswith(*l, path))
- break;
-
- n = l + 1;
- for (;;) {
- if (!*n || !path_startswith(*n, path))
- break;
-
- if (!path_startswith(*n, *l)) {
- has_more = true;
- break;
- }
-
- n++;
- }
-
- printf("%s%s%s\n", prefix, draw_special_char(has_more ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), *l);
-
- print_subtree(has_more ? vertical : space, *l, l);
- l = n;
- }
-}
-
-static void print_tree(const char *prefix, char **l) {
-
- pager_open_if_enabled();
-
- prefix = strempty(prefix);
-
- if (arg_list) {
- char **i;
-
- STRV_FOREACH(i, l)
- printf("%s%s\n", prefix, *i);
- return;
- }
-
- if (strv_isempty(l)) {
- printf("No objects discovered.\n");
- return;
- }
-
- if (streq(l[0], "/") && !l[1]) {
- printf("Only root object discovered.\n");
- return;
- }
-
- print_subtree(prefix, "/", l);
-}
-
-static int on_path(const char *path, void *userdata) {
- Set *paths = userdata;
- int r;
-
- assert(paths);
-
- r = set_put_strdup(paths, path);
- if (r < 0)
- return log_oom();
-
- return 0;
-}
-
-static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths, bool many) {
- static const XMLIntrospectOps ops = {
- .on_path = on_path,
- };
-
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- const char *xml;
- int r;
-
- r = sd_bus_call_method(bus, service, path, "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- if (r < 0) {
- if (many)
- printf("Failed to introspect object %s of service %s: %s\n", path, service, bus_error_message(&error, r));
- else
- log_error("Failed to introspect object %s of service %s: %s", path, service, bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_read(reply, "s", &xml);
- if (r < 0)
- return bus_log_parse_error(r);
-
- return parse_xml_introspect(path, xml, &ops, paths);
-}
-
-static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool many) {
- _cleanup_set_free_free_ Set *paths = NULL, *done = NULL, *failed = NULL;
- _cleanup_free_ char **l = NULL;
- char *m;
- int r;
-
- paths = set_new(&string_hash_ops);
- if (!paths)
- return log_oom();
-
- done = set_new(&string_hash_ops);
- if (!done)
- return log_oom();
-
- failed = set_new(&string_hash_ops);
- if (!failed)
- return log_oom();
-
- m = strdup("/");
- if (!m)
- return log_oom();
-
- r = set_put(paths, m);
- if (r < 0) {
- free(m);
- return log_oom();
- }
-
- for (;;) {
- _cleanup_free_ char *p = NULL;
- int q;
-
- p = set_steal_first(paths);
- if (!p)
- break;
-
- if (set_contains(done, p) ||
- set_contains(failed, p))
- continue;
-
- q = find_nodes(bus, service, p, paths, many);
- if (q < 0) {
- if (r >= 0)
- r = q;
-
- q = set_put(failed, p);
- } else
- q = set_put(done, p);
-
- if (q < 0)
- return log_oom();
-
- assert(q != 0);
- p = NULL;
- }
-
- pager_open_if_enabled();
-
- l = set_get_strv(done);
- if (!l)
- return log_oom();
-
- strv_sort(l);
- print_tree(prefix, l);
-
- fflush(stdout);
-
- return r;
-}
-
-static int tree(sd_bus *bus, char **argv) {
- char **i;
- int r = 0;
-
- if (!arg_unique && !arg_acquired)
- arg_acquired = true;
-
- if (strv_length(argv) <= 1) {
- _cleanup_strv_free_ char **names = NULL;
- bool not_first = false;
-
- r = sd_bus_list_names(bus, &names, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to get name list: %m");
-
- pager_open_if_enabled();
-
- STRV_FOREACH(i, names) {
- int q;
-
- if (!arg_unique && (*i)[0] == ':')
- continue;
-
- if (!arg_acquired && (*i)[0] == ':')
- continue;
-
- if (not_first)
- printf("\n");
-
- printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
-
- q = tree_one(bus, *i, NULL, true);
- if (q < 0 && r >= 0)
- r = q;
-
- not_first = true;
- }
- } else {
- STRV_FOREACH(i, argv+1) {
- int q;
-
- if (i > argv+1)
- printf("\n");
-
- if (argv[2]) {
- pager_open_if_enabled();
- printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_highlight_off());
- }
-
- q = tree_one(bus, *i, NULL, !!argv[2]);
- if (q < 0 && r >= 0)
- r = q;
- }
- }
-
- return r;
-}
-
-static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
- int r;
-
- for (;;) {
- const char *contents = NULL;
- char type;
- union {
- uint8_t u8;
- uint16_t u16;
- int16_t s16;
- uint32_t u32;
- int32_t s32;
- uint64_t u64;
- int64_t s64;
- double d64;
- const char *string;
- int i;
- } basic;
-
- r = sd_bus_message_peek_type(m, &type, &contents);
- if (r <= 0)
- return r;
-
- if (bus_type_is_container(type) > 0) {
-
- r = sd_bus_message_enter_container(m, type, contents);
- if (r < 0)
- return r;
-
- if (type == SD_BUS_TYPE_ARRAY) {
- unsigned n = 0;
-
- /* count array entries */
- for (;;) {
-
- r = sd_bus_message_skip(m, contents);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- n++;
- }
-
- r = sd_bus_message_rewind(m, false);
- if (r < 0)
- return r;
-
- if (needs_space)
- fputc(' ', f);
-
- fprintf(f, "%u", n);
- } else if (type == SD_BUS_TYPE_VARIANT) {
-
- if (needs_space)
- fputc(' ', f);
-
- fprintf(f, "%s", contents);
- }
-
- r = format_cmdline(m, f, needs_space || IN_SET(type, SD_BUS_TYPE_ARRAY, SD_BUS_TYPE_VARIANT));
- if (r < 0)
- return r;
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return r;
-
- continue;
- }
-
- r = sd_bus_message_read_basic(m, type, &basic);
- if (r < 0)
- return r;
-
- if (needs_space)
- fputc(' ', f);
-
- switch (type) {
- case SD_BUS_TYPE_BYTE:
- fprintf(f, "%u", basic.u8);
- break;
-
- case SD_BUS_TYPE_BOOLEAN:
- fputs(true_false(basic.i), f);
- break;
-
- case SD_BUS_TYPE_INT16:
- fprintf(f, "%i", basic.s16);
- break;
-
- case SD_BUS_TYPE_UINT16:
- fprintf(f, "%u", basic.u16);
- break;
-
- case SD_BUS_TYPE_INT32:
- fprintf(f, "%i", basic.s32);
- break;
-
- case SD_BUS_TYPE_UINT32:
- fprintf(f, "%u", basic.u32);
- break;
-
- case SD_BUS_TYPE_INT64:
- fprintf(f, "%" PRIi64, basic.s64);
- break;
-
- case SD_BUS_TYPE_UINT64:
- fprintf(f, "%" PRIu64, basic.u64);
- break;
-
- case SD_BUS_TYPE_DOUBLE:
- fprintf(f, "%g", basic.d64);
- break;
-
- case SD_BUS_TYPE_STRING:
- case SD_BUS_TYPE_OBJECT_PATH:
- case SD_BUS_TYPE_SIGNATURE: {
- _cleanup_free_ char *b = NULL;
-
- b = cescape(basic.string);
- if (!b)
- return -ENOMEM;
-
- fprintf(f, "\"%s\"", b);
- break;
- }
-
- case SD_BUS_TYPE_UNIX_FD:
- fprintf(f, "%i", basic.i);
- break;
-
- default:
- assert_not_reached("Unknown basic type.");
- }
-
- needs_space = true;
- }
-}
-
-typedef struct Member {
- const char *type;
- char *interface;
- char *name;
- char *signature;
- char *result;
- char *value;
- bool writable;
- uint64_t flags;
-} Member;
-
-static unsigned long member_hash_func(const void *p, const uint8_t hash_key[]) {
- const Member *m = p;
- unsigned long ul;
-
- assert(m);
- assert(m->type);
-
- ul = string_hash_func(m->type, hash_key);
-
- if (m->name)
- ul ^= string_hash_func(m->name, hash_key);
-
- if (m->interface)
- ul ^= string_hash_func(m->interface, hash_key);
-
- return ul;
-}
-
-static int member_compare_func(const void *a, const void *b) {
- const Member *x = a, *y = b;
- int d;
-
- assert(x);
- assert(y);
- assert(x->type);
- assert(y->type);
-
- if (!x->interface && y->interface)
- return -1;
- if (x->interface && !y->interface)
- return 1;
- if (x->interface && y->interface) {
- d = strcmp(x->interface, y->interface);
- if (d != 0)
- return d;
- }
-
- d = strcmp(x->type, y->type);
- if (d != 0)
- return d;
-
- if (!x->name && y->name)
- return -1;
- if (x->name && !y->name)
- return 1;
- if (x->name && y->name)
- return strcmp(x->name, y->name);
-
- return 0;
-}
-
-static int member_compare_funcp(const void *a, const void *b) {
- const Member *const * x = (const Member *const *) a, * const *y = (const Member *const *) b;
-
- return member_compare_func(*x, *y);
-}
-
-static void member_free(Member *m) {
- if (!m)
- return;
-
- free(m->interface);
- free(m->name);
- free(m->signature);
- free(m->result);
- free(m->value);
- free(m);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Member*, member_free);
-
-static void member_set_free(Set *s) {
- Member *m;
-
- while ((m = set_steal_first(s)))
- member_free(m);
-
- set_free(s);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, member_set_free);
-
-static int on_interface(const char *interface, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(members);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "interface";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate interface");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_method(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "method";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->result, result);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate method");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_signal(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "signal";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate signal");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_property(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "property";
- m->flags = flags;
- m->writable = writable;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate property");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static const char *strdash(const char *x) {
- return isempty(x) ? "-" : x;
-}
-
-static int introspect(sd_bus *bus, char **argv) {
- static const struct hash_ops member_hash_ops = {
- .hash = member_hash_func,
- .compare = member_compare_func,
- };
-
- static const XMLIntrospectOps ops = {
- .on_interface = on_interface,
- .on_method = on_method,
- .on_signal = on_signal,
- .on_property = on_property,
- };
-
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(member_set_freep) Set *members = NULL;
- Iterator i;
- Member *m;
- const char *xml;
- int r;
- unsigned name_width, type_width, signature_width, result_width;
- Member **sorted = NULL;
- unsigned k = 0, j, n_args;
-
- n_args = strv_length(argv);
- if (n_args < 3) {
- log_error("Requires service and object path argument.");
- return -EINVAL;
- }
-
- if (n_args > 4) {
- log_error("Too many arguments.");
- return -EINVAL;
- }
-
- members = set_new(&member_hash_ops);
- if (!members)
- return log_oom();
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- if (r < 0) {
- log_error("Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_read(reply, "s", &xml);
- if (r < 0)
- return bus_log_parse_error(r);
-
- /* First, get list of all properties */
- r = parse_xml_introspect(argv[2], xml, &ops, members);
- if (r < 0)
- return r;
-
- /* Second, find the current values for them */
- SET_FOREACH(m, members, i) {
-
- if (!streq(m->type, "property"))
- continue;
-
- if (m->value)
- continue;
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_enter_container(reply, 'a', "{sv}");
- if (r < 0)
- return bus_log_parse_error(r);
-
- for (;;) {
- Member *z;
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *mf = NULL;
- size_t sz = 0;
- const char *name;
-
- r = sd_bus_message_enter_container(reply, 'e', "sv");
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (r == 0)
- break;
-
- r = sd_bus_message_read(reply, "s", &name);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_enter_container(reply, 'v', NULL);
- if (r < 0)
- return bus_log_parse_error(r);
-
- mf = open_memstream(&buf, &sz);
- if (!mf)
- return log_oom();
-
- r = format_cmdline(reply, mf, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fclose(mf);
- mf = NULL;
-
- z = set_get(members, &((Member) {
- .type = "property",
- .interface = m->interface,
- .name = (char*) name }));
- if (z) {
- free(z->value);
- z->value = buf;
- buf = NULL;
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- pager_open_if_enabled();
-
- name_width = strlen("NAME");
- type_width = strlen("TYPE");
- signature_width = strlen("SIGNATURE");
- result_width = strlen("RESULT/VALUE");
-
- sorted = newa(Member*, set_size(members));
-
- SET_FOREACH(m, members, i) {
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- if (m->interface)
- name_width = MAX(name_width, strlen(m->interface));
- if (m->name)
- name_width = MAX(name_width, strlen(m->name) + 1);
- if (m->type)
- type_width = MAX(type_width, strlen(m->type));
- if (m->signature)
- signature_width = MAX(signature_width, strlen(m->signature));
- if (m->result)
- result_width = MAX(result_width, strlen(m->result));
- if (m->value)
- result_width = MAX(result_width, strlen(m->value));
-
- sorted[k++] = m;
- }
-
- if (result_width > 40)
- result_width = 40;
-
- qsort(sorted, k, sizeof(Member*), member_compare_funcp);
-
- if (arg_legend) {
- printf("%-*s %-*s %-*s %-*s %s\n",
- (int) name_width, "NAME",
- (int) type_width, "TYPE",
- (int) signature_width, "SIGNATURE",
- (int) result_width, "RESULT/VALUE",
- "FLAGS");
- }
-
- for (j = 0; j < k; j++) {
- _cleanup_free_ char *ellipsized = NULL;
- const char *rv;
- bool is_interface;
-
- m = sorted[j];
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- is_interface = streq(m->type, "interface");
-
- if (argv[3] && is_interface)
- continue;
-
- if (m->value) {
- ellipsized = ellipsize(m->value, result_width, 100);
- if (!ellipsized)
- return log_oom();
-
- rv = ellipsized;
- } else
- rv = strdash(m->result);
-
- printf("%s%s%-*s%s %-*s %-*s %-*s%s%s%s%s%s%s\n",
- is_interface ? ansi_highlight() : "",
- is_interface ? "" : ".",
- - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
- is_interface ? ansi_highlight_off() : "",
- (int) type_width, strdash(m->type),
- (int) signature_width, strdash(m->signature),
- (int) result_width, rv,
- (m->flags & SD_BUS_VTABLE_DEPRECATED) ? " deprecated" : (m->flags || m->writable ? "" : " -"),
- (m->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ? " no-reply" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_CONST) ? " const" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) ? " emits-change" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) ? " emits-invalidation" : "",
- m->writable ? " writable" : "");
- }
-
- return 0;
-}
-
-static int message_dump(sd_bus_message *m, FILE *f) {
- return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
-}
-
-static int message_pcap(sd_bus_message *m, FILE *f) {
- return bus_message_pcap_frame(m, arg_snaplen, f);
-}
-
-static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
- bool added_something = false;
- char **i;
- int r;
-
- STRV_FOREACH(i, argv+1) {
- _cleanup_free_ char *m = NULL;
-
- if (!service_name_is_valid(*i)) {
- log_error("Invalid service name '%s'", *i);
- return -EINVAL;
- }
-
- m = strjoin("sender='", *i, "'", NULL);
- if (!m)
- return log_oom();
-
- r = sd_bus_add_match(bus, NULL, m, NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
-
- added_something = true;
- }
-
- STRV_FOREACH(i, arg_matches) {
- r = sd_bus_add_match(bus, NULL, *i, NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
-
- added_something = true;
- }
-
- if (!added_something) {
- r = sd_bus_add_match(bus, NULL, "", NULL, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to add match: %m");
- }
-
- log_info("Monitoring bus message stream.");
-
- for (;;) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
-
- r = sd_bus_process(bus, &m);
- if (r < 0)
- return log_error_errno(r, "Failed to process bus: %m");
-
- if (m) {
- dump(m, stdout);
- fflush(stdout);
-
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
- log_info("Connection terminated, exiting.");
- return 0;
- }
-
- continue;
- }
-
- if (r > 0)
- continue;
-
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0)
- return log_error_errno(r, "Failed to wait for bus: %m");
- }
-}
-
-static int capture(sd_bus *bus, char *argv[]) {
- int r;
-
- if (isatty(fileno(stdout)) > 0) {
- log_error("Refusing to write message data to console, please redirect output to a file.");
- return -EINVAL;
- }
-
- bus_pcap_header(arg_snaplen, stdout);
-
- r = monitor(bus, argv, message_pcap);
- if (r < 0)
- return r;
-
- if (ferror(stdout)) {
- log_error("Couldn't write capture file.");
- return -EIO;
- }
-
- return r;
-}
-
-static int status(sd_bus *bus, char *argv[]) {
- _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
- pid_t pid;
- int r;
-
- assert(bus);
-
- if (strv_length(argv) > 2) {
- log_error("Expects no or one argument.");
- return -EINVAL;
- }
-
- if (argv[1]) {
- r = parse_pid(argv[1], &pid);
- if (r < 0)
- r = sd_bus_get_name_creds(
- bus,
- argv[1],
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
- &creds);
- else
- r = sd_bus_creds_new_from_pid(
- &creds,
- pid,
- _SD_BUS_CREDS_ALL);
- } else {
- const char *scope, *address;
- sd_id128_t bus_id;
-
- r = sd_bus_get_address(bus, &address);
- if (r >= 0)
- printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_highlight_off());
-
- r = sd_bus_get_scope(bus, &scope);
- if (r >= 0)
- printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_highlight_off());
-
- r = sd_bus_get_bus_id(bus, &bus_id);
- if (r >= 0)
- printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_highlight_off());
-
- r = sd_bus_get_owner_creds(
- bus,
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
- &creds);
- }
-
- if (r < 0)
- return log_error_errno(r, "Failed to get credentials: %m");
-
- bus_creds_dump(creds, NULL, false);
- return 0;
-}
-
-static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) {
- char **p;
- int r;
-
- assert(m);
- assert(signature);
- assert(x);
-
- p = *x;
-
- for (;;) {
- const char *v;
- char t;
-
- t = *signature;
- v = *p;
-
- if (t == 0)
- break;
- if (!v) {
- log_error("Too few parameters for signature.");
- return -EINVAL;
- }
-
- signature++;
- p++;
-
- switch (t) {
-
- case SD_BUS_TYPE_BOOLEAN:
-
- r = parse_boolean(v);
- if (r < 0) {
- log_error("Failed to parse as boolean: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &r);
- break;
-
- case SD_BUS_TYPE_BYTE: {
- uint8_t z;
-
- r = safe_atou8(v, &z);
- if (r < 0) {
- log_error("Failed to parse as byte (unsigned 8bit integer): %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT16: {
- int16_t z;
-
- r = safe_atoi16(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 16bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT16: {
- uint16_t z;
-
- r = safe_atou16(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 16bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT32: {
- int32_t z;
-
- r = safe_atoi32(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 32bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT32: {
- uint32_t z;
-
- r = safe_atou32(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 32bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT64: {
- int64_t z;
-
- r = safe_atoi64(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 64bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT64: {
- uint64_t z;
-
- r = safe_atou64(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 64bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
-
- case SD_BUS_TYPE_DOUBLE: {
- double z;
-
- r = safe_atod(v, &z);
- if (r < 0) {
- log_error("Failed to parse as double precision floating point: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_STRING:
- case SD_BUS_TYPE_OBJECT_PATH:
- case SD_BUS_TYPE_SIGNATURE:
-
- r = sd_bus_message_append_basic(m, t, v);
- break;
-
- case SD_BUS_TYPE_ARRAY: {
- uint32_t n;
- size_t k;
-
- r = safe_atou32(v, &n);
- if (r < 0) {
- log_error("Failed to parse number of array entries: %s", v);
- return r;
- }
-
- r = signature_element_length(signature, &k);
- if (r < 0) {
- log_error("Invalid array signature.");
- return r;
- }
-
- {
- unsigned i;
- char s[k + 1];
- memcpy(s, signature, k);
- s[k] = 0;
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
- if (r < 0)
- return bus_log_create_error(r);
-
- for (i = 0; i < n; i++) {
- r = message_append_cmdline(m, s, &p);
- if (r < 0)
- return r;
- }
- }
-
- signature += k;
-
- r = sd_bus_message_close_container(m);
- break;
- }
-
- case SD_BUS_TYPE_VARIANT:
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, v);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = message_append_cmdline(m, v, &p);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(m);
- break;
-
- case SD_BUS_TYPE_STRUCT_BEGIN:
- case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
- size_t k;
-
- signature--;
- p--;
-
- r = signature_element_length(signature, &k);
- if (r < 0) {
- log_error("Invalid struct/dict entry signature.");
- return r;
- }
-
- {
- char s[k-1];
- memcpy(s, signature + 1, k - 2);
- s[k - 2] = 0;
-
- r = sd_bus_message_open_container(m, t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = message_append_cmdline(m, s, &p);
- if (r < 0)
- return r;
- }
-
- signature += k;
-
- r = sd_bus_message_close_container(m);
- break;
- }
-
- case SD_BUS_TYPE_UNIX_FD:
- log_error("UNIX file descriptor not supported as type.");
- return -EINVAL;
-
- default:
- log_error("Unknown signature type %c.", t);
- return -EINVAL;
- }
-
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- *x = p;
- return 0;
-}
-
-static int call(sd_bus *bus, char *argv[]) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
- int r;
-
- assert(bus);
-
- if (strv_length(argv) < 5) {
- log_error("Expects at least four arguments.");
- return -EINVAL;
- }
-
- r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], argv[3], argv[4]);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_expect_reply(m, arg_expect_reply);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_auto_start(m, arg_auto_start);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_allow_interactive_authorization(m, arg_allow_interactive_authorization);
- if (r < 0)
- return bus_log_create_error(r);
-
- if (!isempty(argv[5])) {
- char **p;
-
- p = argv+6;
-
- r = message_append_cmdline(m, argv[5], &p);
- if (r < 0)
- return r;
-
- if (*p) {
- log_error("Too many parameters for signature.");
- return -EINVAL;
- }
- }
-
- if (!arg_expect_reply) {
- r = sd_bus_send(bus, m, NULL);
- if (r < 0) {
- log_error("Failed to send message.");
- return r;
- }
-
- return 0;
- }
-
- r = sd_bus_call(bus, m, arg_timeout, &error, &reply);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_is_empty(reply);
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (r == 0 && !arg_quiet) {
-
- if (arg_verbose) {
- pager_open_if_enabled();
-
- r = bus_message_dump(reply, stdout, 0);
- if (r < 0)
- return r;
- } else {
-
- fputs(sd_bus_message_get_signature(reply, true), stdout);
- fputc(' ', stdout);
-
- r = format_cmdline(reply, stdout, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fputc('\n', stdout);
- }
- }
-
- return 0;
-}
-
-static int get_property(sd_bus *bus, char *argv[]) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- unsigned n;
- char **i;
- int r;
-
- assert(bus);
-
- n = strv_length(argv);
- if (n < 5) {
- log_error("Expects at least four arguments.");
- return -EINVAL;
- }
-
- STRV_FOREACH(i, argv + 4) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- const char *contents = NULL;
- char type;
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Get", &error, &reply, "ss", argv[3], *i);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_peek_type(reply, &type, &contents);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_enter_container(reply, 'v', contents);
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (arg_verbose) {
- pager_open_if_enabled();
-
- r = bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
- if (r < 0)
- return r;
- } else {
- fputs(contents, stdout);
- fputc(' ', stdout);
-
- r = format_cmdline(reply, stdout, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fputc('\n', stdout);
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- return 0;
-}
-
-static int set_property(sd_bus *bus, char *argv[]) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- unsigned n;
- char **p;
- int r;
-
- assert(bus);
-
- n = strv_length(argv);
- if (n < 6) {
- log_error("Expects at least five arguments.");
- return -EINVAL;
- }
-
- r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Set");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "ss", argv[3], argv[4]);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'v', argv[5]);
- if (r < 0)
- return bus_log_create_error(r);
-
- p = argv+6;
- r = message_append_cmdline(m, argv[5], &p);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- if (*p) {
- log_error("Too many parameters for signature.");
- return -EINVAL;
- }
-
- r = sd_bus_call(bus, m, arg_timeout, &error, NULL);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- return 0;
-}
-
-static int help(void) {
- printf("%s [OPTIONS...] {COMMAND} ...\n\n"
- "Introspect the bus.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --no-pager Do not pipe output into a pager\n"
- " --no-legend Do not show the headers and footers\n"
- " --system Connect to system bus\n"
- " --user Connect to user bus\n"
- " -H --host=[USER@]HOST Operate on remote host\n"
- " -M --machine=CONTAINER Operate on local container\n"
- " --address=ADDRESS Connect to bus specified by address\n"
- " --show-machine Show machine ID column in list\n"
- " --unique Only show unique names\n"
- " --acquired Only show acquired names\n"
- " --activatable Only show activatable names\n"
- " --match=MATCH Only show matching messages\n"
- " --list Don't show tree, but simple object path list\n"
- " --quiet Don't show method call reply\n"
- " --verbose Show result values in long format\n"
- " --expect-reply=BOOL Expect a method call reply\n"
- " --auto-start=BOOL Auto-start destination service\n"
- " --allow-interactive-authorization=BOOL\n"
- " Allow interactive authorization for operation\n"
- " --timeout=SECS Maximum time to wait for method call completion\n"
- " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n"
- "Commands:\n"
- " list List bus names\n"
- " status [SERVICE] Show bus service, process or bus owner credentials\n"
- " monitor [SERVICE...] Show bus traffic\n"
- " capture [SERVICE...] Capture bus traffic as pcap\n"
- " tree [SERVICE...] Show object tree of service\n"
- " introspect SERVICE OBJECT [INTERFACE]\n"
- " call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n"
- " Call a method\n"
- " get-property SERVICE OBJECT INTERFACE PROPERTY...\n"
- " Get property value\n"
- " set-property SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT...\n"
- " Set property value\n"
- " help Show this help\n"
- , program_invocation_short_name);
-
- return 0;
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
- enum {
- ARG_VERSION = 0x100,
- ARG_NO_PAGER,
- ARG_NO_LEGEND,
- ARG_SYSTEM,
- ARG_USER,
- ARG_ADDRESS,
- ARG_MATCH,
- ARG_SHOW_MACHINE,
- ARG_UNIQUE,
- ARG_ACQUIRED,
- ARG_ACTIVATABLE,
- ARG_SIZE,
- ARG_LIST,
- ARG_VERBOSE,
- ARG_EXPECT_REPLY,
- ARG_AUTO_START,
- ARG_ALLOW_INTERACTIVE_AUTHORIZATION,
- ARG_TIMEOUT,
- ARG_AUGMENT_CREDS,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
- { "system", no_argument, NULL, ARG_SYSTEM },
- { "user", no_argument, NULL, ARG_USER },
- { "address", required_argument, NULL, ARG_ADDRESS },
- { "show-machine", no_argument, NULL, ARG_SHOW_MACHINE },
- { "unique", no_argument, NULL, ARG_UNIQUE },
- { "acquired", no_argument, NULL, ARG_ACQUIRED },
- { "activatable", no_argument, NULL, ARG_ACTIVATABLE },
- { "match", required_argument, NULL, ARG_MATCH },
- { "host", required_argument, NULL, 'H' },
- { "machine", required_argument, NULL, 'M' },
- { "size", required_argument, NULL, ARG_SIZE },
- { "list", no_argument, NULL, ARG_LIST },
- { "quiet", no_argument, NULL, 'q' },
- { "verbose", no_argument, NULL, ARG_VERBOSE },
- { "expect-reply", required_argument, NULL, ARG_EXPECT_REPLY },
- { "auto-start", required_argument, NULL, ARG_AUTO_START },
- { "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION },
- { "timeout", required_argument, NULL, ARG_TIMEOUT },
- { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS},
- {},
- };
-
- int c, r;
-
- assert(argc >= 0);
- assert(argv);
-
- while ((c = getopt_long(argc, argv, "hH:M:q", options, NULL)) >= 0)
-
- switch (c) {
-
- case 'h':
- return help();
-
- case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
-
- case ARG_NO_PAGER:
- arg_no_pager = true;
- break;
-
- case ARG_NO_LEGEND:
- arg_legend = false;
- break;
-
- case ARG_USER:
- arg_user = true;
- break;
-
- case ARG_SYSTEM:
- arg_user = false;
- break;
-
- case ARG_ADDRESS:
- arg_address = optarg;
- break;
-
- case ARG_SHOW_MACHINE:
- arg_show_machine = true;
- break;
-
- case ARG_UNIQUE:
- arg_unique = true;
- break;
-
- case ARG_ACQUIRED:
- arg_acquired = true;
- break;
-
- case ARG_ACTIVATABLE:
- arg_activatable = true;
- break;
-
- case ARG_MATCH:
- if (strv_extend(&arg_matches, optarg) < 0)
- return log_oom();
- break;
-
- case ARG_SIZE: {
- off_t o;
-
- r = parse_size(optarg, 0, &o);
- if (r < 0) {
- log_error("Failed to parse size: %s", optarg);
- return r;
- }
-
- if ((off_t) (size_t) o != o) {
- log_error("Size out of range.");
- return -E2BIG;
- }
-
- arg_snaplen = (size_t) o;
- break;
- }
-
- case ARG_LIST:
- arg_list = true;
- break;
-
- case 'H':
- arg_transport = BUS_TRANSPORT_REMOTE;
- arg_host = optarg;
- break;
-
- case 'M':
- arg_transport = BUS_TRANSPORT_MACHINE;
- arg_host = optarg;
- break;
-
- case 'q':
- arg_quiet = true;
- break;
-
- case ARG_VERBOSE:
- arg_verbose = true;
- break;
-
- case ARG_EXPECT_REPLY:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --expect-reply= parameter.");
- return r;
- }
-
- arg_expect_reply = !!r;
- break;
-
-
- case ARG_AUTO_START:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --auto-start= parameter.");
- return r;
- }
-
- arg_auto_start = !!r;
- break;
-
-
- case ARG_ALLOW_INTERACTIVE_AUTHORIZATION:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --allow-interactive-authorization= parameter.");
- return r;
- }
-
- arg_allow_interactive_authorization = !!r;
- break;
-
- case ARG_TIMEOUT:
- r = parse_sec(optarg, &arg_timeout);
- if (r < 0) {
- log_error("Failed to parse --timeout= parameter.");
- return r;
- }
-
- break;
-
- case ARG_AUGMENT_CREDS:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --augment-creds= parameter.");
- return r;
- }
-
- arg_augment_creds = !!r;
- break;
-
- case '?':
- return -EINVAL;
-
- default:
- assert_not_reached("Unhandled option");
- }
-
- return 1;
-}
-
-static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
- assert(bus);
-
- if (optind >= argc ||
- streq(argv[optind], "list"))
- return list_bus_names(bus, argv + optind);
-
- if (streq(argv[optind], "monitor"))
- return monitor(bus, argv + optind, message_dump);
-
- if (streq(argv[optind], "capture"))
- return capture(bus, argv + optind);
-
- if (streq(argv[optind], "status"))
- return status(bus, argv + optind);
-
- if (streq(argv[optind], "tree"))
- return tree(bus, argv + optind);
-
- if (streq(argv[optind], "introspect"))
- return introspect(bus, argv + optind);
-
- if (streq(argv[optind], "call"))
- return call(bus, argv + optind);
-
- if (streq(argv[optind], "get-property"))
- return get_property(bus, argv + optind);
-
- if (streq(argv[optind], "set-property"))
- return set_property(bus, argv + optind);
-
- if (streq(argv[optind], "help"))
- return help();
-
- log_error("Unknown command '%s'", argv[optind]);
- return -EINVAL;
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- int r;
-
- log_parse_environment();
- log_open();
-
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
-
- r = sd_bus_new(&bus);
- if (r < 0) {
- log_error_errno(r, "Failed to allocate bus: %m");
- goto finish;
- }
-
- if (streq_ptr(argv[optind], "monitor") ||
- streq_ptr(argv[optind], "capture")) {
-
- r = sd_bus_set_monitor(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to set monitor mode: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_creds(bus, true, _SD_BUS_CREDS_ALL);
- if (r < 0) {
- log_error_errno(r, "Failed to enable credentials: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_timestamp(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to enable timestamps: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_fds(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to enable fds: %m");
- goto finish;
- }
- }
-
- if (arg_address)
- r = sd_bus_set_address(bus, arg_address);
- else {
- r = sd_bus_set_bus_client(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to set bus client: %m");
- goto finish;
- }
-
- switch (arg_transport) {
-
- case BUS_TRANSPORT_LOCAL:
- if (arg_user) {
- bus->is_user = true;
- r = bus_set_address_user(bus);
- } else {
- bus->is_system = true;
- r = bus_set_address_system(bus);
- }
- break;
-
- case BUS_TRANSPORT_REMOTE:
- r = bus_set_address_system_remote(bus, arg_host);
- break;
-
- case BUS_TRANSPORT_MACHINE:
- r = bus_set_address_system_machine(bus, arg_host);
- break;
-
- default:
- assert_not_reached("Hmm, unknown transport type.");
- }
- }
- if (r < 0) {
- log_error_errno(r, "Failed to set address: %m");
- goto finish;
- }
-
- r = sd_bus_start(bus);
- if (r < 0) {
- log_error_errno(r, "Failed to connect to bus: %m");
- goto finish;
- }
-
- r = busctl_main(bus, argc, argv);
-
-finish:
- pager_close();
-
- strv_free(arg_matches);
-
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "log.h"
-#include "util.h"
-#include "macro.h"
-#include "formats-util.h"
-
-#include "sd-bus.h"
-#include "bus-error.h"
-#include "bus-match.h"
-#include "bus-internal.h"
-#include "bus-util.h"
-
-static int match_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
- return 0;
-}
-
-static int object_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- int r;
-
- if (sd_bus_message_is_method_error(m, NULL))
- return 0;
-
- if (sd_bus_message_is_method_call(m, "org.object.test", "Foobar")) {
- log_info("Invoked Foobar() on %s", sd_bus_message_get_path(m));
-
- r = sd_bus_reply_method_return(m, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to send reply: %m");
-
- return 1;
- }
-
- return 0;
-}
-
-static int server_init(sd_bus **_bus) {
- sd_bus *bus = NULL;
- sd_id128_t id;
- int r;
- const char *unique;
-
- assert_se(_bus);
-
- r = sd_bus_open_user(&bus);
- if (r < 0) {
- log_error_errno(r, "Failed to connect to user bus: %m");
- goto fail;
- }
-
- r = sd_bus_get_bus_id(bus, &id);
- if (r < 0) {
- log_error_errno(r, "Failed to get server ID: %m");
- goto fail;
- }
-
- r = sd_bus_get_unique_name(bus, &unique);
- if (r < 0) {
- log_error_errno(r, "Failed to get unique name: %m");
- goto fail;
- }
-
- log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
- log_info("Unique ID: %s", unique);
- log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
-
- r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
- if (r < 0) {
- log_error_errno(r, "Failed to acquire name: %m");
- goto fail;
- }
-
- r = sd_bus_add_fallback(bus, NULL, "/foo/bar", object_callback, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to add object: %m");
- goto fail;
- }
-
- r = sd_bus_add_match(bus, NULL, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to add match: %m");
- goto fail;
- }
-
- r = sd_bus_add_match(bus, NULL, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to add match: %m");
- goto fail;
- }
-
- bus_match_dump(&bus->match_callbacks, 0);
-
- *_bus = bus;
- return 0;
-
-fail:
- if (bus)
- sd_bus_unref(bus);
-
- return r;
-}
-
-static int server(sd_bus *bus) {
- int r;
- bool client1_gone = false, client2_gone = false;
-
- while (!client1_gone || !client2_gone) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- pid_t pid = 0;
- const char *label = NULL;
-
- r = sd_bus_process(bus, &m);
- if (r < 0) {
- log_error_errno(r, "Failed to process requests: %m");
- goto fail;
- }
-
- if (r == 0) {
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0) {
- log_error_errno(r, "Failed to wait: %m");
- goto fail;
- }
-
- continue;
- }
-
- if (!m)
- continue;
-
- sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid);
- sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label);
- log_info("Got message! member=%s pid="PID_FMT" label=%s",
- strna(sd_bus_message_get_member(m)),
- pid,
- strna(label));
- /* bus_message_dump(m); */
- /* sd_bus_message_rewind(m, true); */
-
- if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
- const char *hello;
- _cleanup_free_ char *lowercase = NULL;
-
- r = sd_bus_message_read(m, "s", &hello);
- if (r < 0) {
- log_error_errno(r, "Failed to get parameter: %m");
- goto fail;
- }
-
- lowercase = strdup(hello);
- if (!lowercase) {
- r = log_oom();
- goto fail;
- }
-
- ascii_strlower(lowercase);
-
- r = sd_bus_reply_method_return(m, "s", lowercase);
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
-
- r = sd_bus_reply_method_return(m, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
-
- client1_gone = true;
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
-
- r = sd_bus_reply_method_return(m, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
-
- client2_gone = true;
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
-
- sleep(1);
-
- r = sd_bus_reply_method_return(m, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
-
- } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) {
- int fd;
- static const char x = 'X';
-
- r = sd_bus_message_read(m, "h", &fd);
- if (r < 0) {
- log_error_errno(r, "Failed to get parameter: %m");
- goto fail;
- }
-
- log_info("Received fd=%d", fd);
-
- if (write(fd, &x, 1) < 0) {
- log_error_errno(errno, "Failed to write to fd: %m");
- safe_close(fd);
- goto fail;
- }
-
- r = sd_bus_reply_method_return(m, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
-
- } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
-
- r = sd_bus_reply_method_error(
- m,
- &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
- if (r < 0) {
- log_error_errno(r, "Failed to send reply: %m");
- goto fail;
- }
- }
- }
-
- r = 0;
-
-fail:
- if (bus) {
- sd_bus_flush(bus);
- sd_bus_unref(bus);
- }
-
- return r;
-}
-
-static void* client1(void*p) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- const char *hello;
- int r;
- _cleanup_close_pair_ int pp[2] = { -1, -1 };
- char x;
-
- r = sd_bus_open_user(&bus);
- if (r < 0) {
- log_error_errno(r, "Failed to connect to user bus: %m");
- goto finish;
- }
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "LowerCase",
- &error,
- &reply,
- "s",
- "HELLO");
- if (r < 0) {
- log_error_errno(r, "Failed to issue method call: %m");
- goto finish;
- }
-
- r = sd_bus_message_read(reply, "s", &hello);
- if (r < 0) {
- log_error_errno(r, "Failed to get string: %m");
- goto finish;
- }
-
- assert_se(streq(hello, "hello"));
-
- if (pipe2(pp, O_CLOEXEC|O_NONBLOCK) < 0) {
- log_error_errno(errno, "Failed to allocate pipe: %m");
- r = -errno;
- goto finish;
- }
-
- log_info("Sending fd=%d", pp[1]);
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "FileDescriptor",
- &error,
- NULL,
- "h",
- pp[1]);
- if (r < 0) {
- log_error_errno(r, "Failed to issue method call: %m");
- goto finish;
- }
-
- errno = 0;
- if (read(pp[0], &x, 1) <= 0) {
- log_error("Failed to read from pipe: %s", errno ? strerror(errno) : "early read");
- goto finish;
- }
-
- r = 0;
-
-finish:
- if (bus) {
- _cleanup_bus_message_unref_ sd_bus_message *q;
-
- r = sd_bus_message_new_method_call(
- bus,
- &q,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "ExitClient1");
- if (r < 0)
- log_error_errno(r, "Failed to allocate method call: %m");
- else
- sd_bus_send(bus, q, NULL);
-
- }
-
- return INT_TO_PTR(r);
-}
-
-static int quit_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- bool *x = userdata;
-
- log_error("Quit callback: %s", strerror(sd_bus_message_get_errno(m)));
-
- *x = 1;
- return 1;
-}
-
-static void* client2(void*p) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- bool quit = false;
- const char *mid;
- int r;
-
- r = sd_bus_open_user(&bus);
- if (r < 0) {
- log_error_errno(r, "Failed to connect to user bus: %m");
- goto finish;
- }
-
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.systemd.test",
- "/foo/bar/waldo/piep",
- "org.object.test",
- "Foobar");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate method call: %m");
- goto finish;
- }
-
- r = sd_bus_send(bus, m, NULL);
- if (r < 0) {
- log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
- goto finish;
- }
-
- m = sd_bus_message_unref(m);
-
- r = sd_bus_message_new_signal(
- bus,
- &m,
- "/foobar",
- "foo.bar",
- "Notify");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate signal: %m");
- goto finish;
- }
-
- r = sd_bus_send(bus, m, NULL);
- if (r < 0) {
- log_error("Failed to issue signal: %s", bus_error_message(&error, -r));
- goto finish;
- }
-
- m = sd_bus_message_unref(m);
-
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.DBus.Peer",
- "GetMachineId");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate method call: %m");
- goto finish;
- }
-
- r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0) {
- log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
- goto finish;
- }
-
- r = sd_bus_message_read(reply, "s", &mid);
- if (r < 0) {
- log_error_errno(r, "Failed to parse machine ID: %m");
- goto finish;
- }
-
- log_info("Machine ID is %s.", mid);
-
- m = sd_bus_message_unref(m);
-
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "Slow");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate method call: %m");
- goto finish;
- }
-
- reply = sd_bus_message_unref(reply);
-
- r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
- if (r < 0)
- log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
- else
- log_info("Slow call succeed.");
-
- m = sd_bus_message_unref(m);
-
- r = sd_bus_message_new_method_call(
- bus,
- &m,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "Slow");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate method call: %m");
- goto finish;
- }
-
- r = sd_bus_call_async(bus, NULL, m, quit_callback, &quit, 200 * USEC_PER_MSEC);
- if (r < 0) {
- log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
- goto finish;
- }
-
- while (!quit) {
- r = sd_bus_process(bus, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to process requests: %m");
- goto finish;
- }
- if (r == 0) {
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0) {
- log_error_errno(r, "Failed to wait: %m");
- goto finish;
- }
- }
- }
-
- r = 0;
-
-finish:
- if (bus) {
- _cleanup_bus_message_unref_ sd_bus_message *q;
-
- r = sd_bus_message_new_method_call(
- bus,
- &q,
- "org.freedesktop.systemd.test",
- "/",
- "org.freedesktop.systemd.test",
- "ExitClient2");
- if (r < 0) {
- log_error_errno(r, "Failed to allocate method call: %m");
- goto finish;
- }
-
- (void) sd_bus_send(bus, q, NULL);
- }
-
- return INT_TO_PTR(r);
-}
-
-int main(int argc, char *argv[]) {
- pthread_t c1, c2;
- sd_bus *bus;
- void *p;
- int q, r;
-
- r = server_init(&bus);
- if (r < 0) {
- log_info("Failed to connect to bus, skipping tests.");
- return EXIT_TEST_SKIP;
- }
-
- log_info("Initialized...");
-
- r = pthread_create(&c1, NULL, client1, bus);
- if (r != 0)
- return EXIT_FAILURE;
-
- r = pthread_create(&c2, NULL, client2, bus);
- if (r != 0)
- return EXIT_FAILURE;
-
- r = server(bus);
-
- q = pthread_join(c1, &p);
- if (q != 0)
- return EXIT_FAILURE;
- if (PTR_TO_INT(p) < 0)
- return EXIT_FAILURE;
-
- q = pthread_join(c2, &p);
- if (q != 0)
- return EXIT_FAILURE;
- if (PTR_TO_INT(p) < 0)
- return EXIT_FAILURE;
-
- if (r < 0)
- return EXIT_FAILURE;
-
- return EXIT_SUCCESS;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#ifdef HAVE_GLIB
-#include <glib.h>
-#endif
-
-#include "util.h"
-#include "macro.h"
-#include "sd-bus.h"
-#include "bus-gvariant.h"
-#include "bus-util.h"
-#include "bus-internal.h"
-#include "bus-message.h"
-#include "bus-dump.h"
-
-static void test_bus_gvariant_is_fixed_size(void) {
- assert_se(bus_gvariant_is_fixed_size("") > 0);
- assert_se(bus_gvariant_is_fixed_size("()") > 0);
- assert_se(bus_gvariant_is_fixed_size("y") > 0);
- assert_se(bus_gvariant_is_fixed_size("u") > 0);
- assert_se(bus_gvariant_is_fixed_size("b") > 0);
- assert_se(bus_gvariant_is_fixed_size("n") > 0);
- assert_se(bus_gvariant_is_fixed_size("q") > 0);
- assert_se(bus_gvariant_is_fixed_size("i") > 0);
- assert_se(bus_gvariant_is_fixed_size("t") > 0);
- assert_se(bus_gvariant_is_fixed_size("d") > 0);
- assert_se(bus_gvariant_is_fixed_size("s") == 0);
- assert_se(bus_gvariant_is_fixed_size("o") == 0);
- assert_se(bus_gvariant_is_fixed_size("g") == 0);
- assert_se(bus_gvariant_is_fixed_size("h") > 0);
- assert_se(bus_gvariant_is_fixed_size("ay") == 0);
- assert_se(bus_gvariant_is_fixed_size("v") == 0);
- assert_se(bus_gvariant_is_fixed_size("(u)") > 0);
- assert_se(bus_gvariant_is_fixed_size("(uuuuy)") > 0);
- assert_se(bus_gvariant_is_fixed_size("(uusuuy)") == 0);
- assert_se(bus_gvariant_is_fixed_size("a{ss}") == 0);
- assert_se(bus_gvariant_is_fixed_size("((u)yyy(b(iiii)))") > 0);
- assert_se(bus_gvariant_is_fixed_size("((u)yyy(b(iiivi)))") == 0);
-}
-
-static void test_bus_gvariant_get_size(void) {
- assert_se(bus_gvariant_get_size("") == 0);
- assert_se(bus_gvariant_get_size("()") == 1);
- assert_se(bus_gvariant_get_size("y") == 1);
- assert_se(bus_gvariant_get_size("u") == 4);
- assert_se(bus_gvariant_get_size("b") == 1);
- assert_se(bus_gvariant_get_size("n") == 2);
- assert_se(bus_gvariant_get_size("q") == 2);
- assert_se(bus_gvariant_get_size("i") == 4);
- assert_se(bus_gvariant_get_size("t") == 8);
- assert_se(bus_gvariant_get_size("d") == 8);
- assert_se(bus_gvariant_get_size("s") < 0);
- assert_se(bus_gvariant_get_size("o") < 0);
- assert_se(bus_gvariant_get_size("g") < 0);
- assert_se(bus_gvariant_get_size("h") == 4);
- assert_se(bus_gvariant_get_size("ay") < 0);
- assert_se(bus_gvariant_get_size("v") < 0);
- assert_se(bus_gvariant_get_size("(u)") == 4);
- assert_se(bus_gvariant_get_size("(uuuuy)") == 20);
- assert_se(bus_gvariant_get_size("(uusuuy)") < 0);
- assert_se(bus_gvariant_get_size("a{ss}") < 0);
- assert_se(bus_gvariant_get_size("((u)yyy(b(iiii)))") == 28);
- assert_se(bus_gvariant_get_size("((u)yyy(b(iiivi)))") < 0);
- assert_se(bus_gvariant_get_size("((b)(t))") == 16);
- assert_se(bus_gvariant_get_size("((b)(b)(t))") == 16);
- assert_se(bus_gvariant_get_size("(bt)") == 16);
- assert_se(bus_gvariant_get_size("((t)(b))") == 16);
- assert_se(bus_gvariant_get_size("(tb)") == 16);
- assert_se(bus_gvariant_get_size("((b)(b))") == 2);
- assert_se(bus_gvariant_get_size("((t)(t))") == 16);
-}
-
-static void test_bus_gvariant_get_alignment(void) {
- assert_se(bus_gvariant_get_alignment("") == 1);
- assert_se(bus_gvariant_get_alignment("()") == 1);
- assert_se(bus_gvariant_get_alignment("y") == 1);
- assert_se(bus_gvariant_get_alignment("b") == 1);
- assert_se(bus_gvariant_get_alignment("u") == 4);
- assert_se(bus_gvariant_get_alignment("s") == 1);
- assert_se(bus_gvariant_get_alignment("o") == 1);
- assert_se(bus_gvariant_get_alignment("g") == 1);
- assert_se(bus_gvariant_get_alignment("v") == 8);
- assert_se(bus_gvariant_get_alignment("h") == 4);
- assert_se(bus_gvariant_get_alignment("i") == 4);
- assert_se(bus_gvariant_get_alignment("t") == 8);
- assert_se(bus_gvariant_get_alignment("x") == 8);
- assert_se(bus_gvariant_get_alignment("q") == 2);
- assert_se(bus_gvariant_get_alignment("n") == 2);
- assert_se(bus_gvariant_get_alignment("d") == 8);
- assert_se(bus_gvariant_get_alignment("ay") == 1);
- assert_se(bus_gvariant_get_alignment("as") == 1);
- assert_se(bus_gvariant_get_alignment("au") == 4);
- assert_se(bus_gvariant_get_alignment("an") == 2);
- assert_se(bus_gvariant_get_alignment("ans") == 2);
- assert_se(bus_gvariant_get_alignment("ant") == 8);
- assert_se(bus_gvariant_get_alignment("(ss)") == 1);
- assert_se(bus_gvariant_get_alignment("(ssu)") == 4);
- assert_se(bus_gvariant_get_alignment("a(ssu)") == 4);
- assert_se(bus_gvariant_get_alignment("(u)") == 4);
- assert_se(bus_gvariant_get_alignment("(uuuuy)") == 4);
- assert_se(bus_gvariant_get_alignment("(uusuuy)") == 4);
- assert_se(bus_gvariant_get_alignment("a{ss}") == 1);
- assert_se(bus_gvariant_get_alignment("((u)yyy(b(iiii)))") == 4);
- assert_se(bus_gvariant_get_alignment("((u)yyy(b(iiivi)))") == 8);
- assert_se(bus_gvariant_get_alignment("((b)(t))") == 8);
- assert_se(bus_gvariant_get_alignment("((b)(b)(t))") == 8);
- assert_se(bus_gvariant_get_alignment("(bt)") == 8);
- assert_se(bus_gvariant_get_alignment("((t)(b))") == 8);
- assert_se(bus_gvariant_get_alignment("(tb)") == 8);
- assert_se(bus_gvariant_get_alignment("((b)(b))") == 1);
- assert_se(bus_gvariant_get_alignment("((t)(t))") == 8);
-}
-
-static void test_marshal(void) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *n = NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- _cleanup_free_ void *blob;
- size_t sz;
- int r;
-
- r = sd_bus_open_system(&bus);
- if (r < 0)
- exit(EXIT_TEST_SKIP);
-
- bus->message_version = 2; /* dirty hack to enable gvariant */
-
- assert_se(sd_bus_message_new_method_call(bus, &m, "a.service.name", "/an/object/path/which/is/really/really/long/so/that/we/hit/the/eight/bit/boundary/by/quite/some/margin/to/test/this/stuff/that/it/really/works", "an.interface.name", "AMethodName") >= 0);
-
- assert_cc(sizeof(struct bus_header) == 16);
-
- assert_se(sd_bus_message_append(m,
- "a(usv)", 3,
- 4711, "first-string-parameter", "(st)", "X", (uint64_t) 1111,
- 4712, "second-string-parameter", "(a(si))", 2, "Y", 5, "Z", 6,
- 4713, "third-string-parameter", "(uu)", 1, 2) >= 0);
-
- assert_se(bus_message_seal(m, 4711, 0) >= 0);
-
-#ifdef HAVE_GLIB
- {
- GVariant *v;
- char *t;
-
-#if !defined(GLIB_VERSION_2_36)
- g_type_init();
-#endif
-
- v = g_variant_new_from_data(G_VARIANT_TYPE("(yyyyuta{tv})"), m->header, sizeof(struct bus_header) + m->fields_size, false, NULL, NULL);
- assert_se(g_variant_is_normal_form(v));
- t = g_variant_print(v, TRUE);
- printf("%s\n", t);
- g_free(t);
- g_variant_unref(v);
-
- v = g_variant_new_from_data(G_VARIANT_TYPE("(a(usv))"), m->body.data, m->user_body_size, false, NULL, NULL);
- assert_se(g_variant_is_normal_form(v));
- t = g_variant_print(v, TRUE);
- printf("%s\n", t);
- g_free(t);
- g_variant_unref(v);
- }
-#endif
-
- assert_se(bus_message_dump(m, NULL, BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
-
- assert_se(bus_message_get_blob(m, &blob, &sz) >= 0);
-
-#ifdef HAVE_GLIB
- {
- GVariant *v;
- char *t;
-
- v = g_variant_new_from_data(G_VARIANT_TYPE("(yyyyuta{tv}v)"), blob, sz, false, NULL, NULL);
- assert_se(g_variant_is_normal_form(v));
- t = g_variant_print(v, TRUE);
- printf("%s\n", t);
- g_free(t);
- g_variant_unref(v);
- }
-#endif
-
- assert_se(bus_message_from_malloc(bus, blob, sz, NULL, 0, NULL, &n) >= 0);
- blob = NULL;
-
- assert_se(bus_message_dump(n, NULL, BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
-
- m = sd_bus_message_unref(m);
-
- assert_se(sd_bus_message_new_method_call(bus, &m, "a.x", "/a/x", "a.x", "Ax") >= 0);
-
- assert_se(sd_bus_message_append(m, "as", 0) >= 0);
-
- assert_se(bus_message_seal(m, 4712, 0) >= 0);
- assert_se(bus_message_dump(m, NULL, BUS_MESSAGE_DUMP_WITH_HEADER) >= 0);
-}
-
-int main(int argc, char *argv[]) {
-
- test_bus_gvariant_is_fixed_size();
- test_bus_gvariant_get_size();
- test_bus_gvariant_get_alignment();
- test_marshal();
-
- return 0;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "util.h"
-#include "log.h"
-
-#include "sd-bus.h"
-#include "bus-kernel.h"
-#include "bus-util.h"
-
-static int test_match(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- int *found = userdata;
-
- *found = 1;
-
- return 0;
-}
-
-static void test_one(
- const char *path,
- const char *interface,
- const char *member,
- bool as_list,
- const char *arg0,
- const char *match,
- bool good) {
-
- _cleanup_close_ int bus_ref = -1;
- _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL;
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- sd_bus *a, *b;
- int r, found = 0;
-
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
-
- bus_ref = bus_kernel_create_bus(name, false, &bus_name);
- if (bus_ref == -ENOENT)
- exit(EXIT_TEST_SKIP);
-
- assert_se(bus_ref >= 0);
-
- address = strappend("kernel:path=", bus_name);
- assert_se(address);
-
- r = sd_bus_new(&a);
- assert_se(r >= 0);
-
- r = sd_bus_new(&b);
- assert_se(r >= 0);
-
- r = sd_bus_set_address(a, address);
- assert_se(r >= 0);
-
- r = sd_bus_set_address(b, address);
- assert_se(r >= 0);
-
- r = sd_bus_start(a);
- assert_se(r >= 0);
-
- r = sd_bus_start(b);
- assert_se(r >= 0);
-
- log_debug("match");
- r = sd_bus_add_match(b, NULL, match, test_match, &found);
- assert_se(r >= 0);
-
- log_debug("signal");
-
- if (as_list)
- r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0);
- else
- r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
- assert_se(r >= 0);
-
- r = sd_bus_process(b, &m);
- assert_se(r >= 0 && good == !!found);
-
- sd_bus_unref(a);
- sd_bus_unref(b);
-}
-
-int main(int argc, char *argv[]) {
- log_set_max_level(LOG_DEBUG);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/tuut'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "interface='waldo.com'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Piep'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Pi_ep'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foo_bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/quux'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/quux'", false);
- test_one("/", "waldo.com", "Piep", false, "foobar", "path_namespace='/'", true);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/bar/waldo/'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path_namespace='/foo/'", true);
-
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/bar/waldo", "arg0path='/foo/'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo'", true);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo", "arg0path='/foo/bar/waldo'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "/foo/", "arg0path='/foo/bar/waldo'", true);
-
- return 0;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <fcntl.h>
-
-#include "util.h"
-#include "log.h"
-
-#include "sd-bus.h"
-#include "bus-kernel.h"
-#include "bus-util.h"
-#include "bus-dump.h"
-
-int main(int argc, char *argv[]) {
- _cleanup_close_ int bus_ref = -1;
- _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL, *bname = NULL;
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- const char *ua = NULL, *ub = NULL, *the_string = NULL;
- sd_bus *a, *b;
- int r, pipe_fds[2];
- const char *nn;
-
- log_set_max_level(LOG_DEBUG);
-
- assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);
-
- bus_ref = bus_kernel_create_bus(name, false, &bus_name);
- if (bus_ref == -ENOENT)
- return EXIT_TEST_SKIP;
-
- assert_se(bus_ref >= 0);
-
- address = strappend("kernel:path=", bus_name);
- assert_se(address);
-
- r = sd_bus_new(&a);
- assert_se(r >= 0);
-
- r = sd_bus_new(&b);
- assert_se(r >= 0);
-
- r = sd_bus_set_description(a, "a");
- assert_se(r >= 0);
-
- r = sd_bus_set_address(a, address);
- assert_se(r >= 0);
-
- r = sd_bus_set_address(b, address);
- assert_se(r >= 0);
-
- assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0);
- assert_se(sd_bus_negotiate_creds(a, true, _SD_BUS_CREDS_ALL) >= 0);
-
- assert_se(sd_bus_negotiate_timestamp(b, 0) >= 0);
- assert_se(sd_bus_negotiate_creds(b, true, 0) >= 0);
-
- r = sd_bus_start(a);
- assert_se(r >= 0);
-
- r = sd_bus_start(b);
- assert_se(r >= 0);
-
- assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0);
- assert_se(sd_bus_negotiate_creds(b, true, _SD_BUS_CREDS_ALL) >= 0);
-
- r = sd_bus_get_unique_name(a, &ua);
- assert_se(r >= 0);
- printf("unique a: %s\n", ua);
-
- r = sd_bus_get_description(a, &nn);
- assert_se(r >= 0);
- printf("name of a: %s\n", nn);
-
- r = sd_bus_get_unique_name(b, &ub);
- assert_se(r >= 0);
- printf("unique b: %s\n", ub);
-
- r = sd_bus_get_description(b, &nn);
- assert_se(r >= 0);
- printf("name of b: %s\n", nn);
-
- assert_se(bus_kernel_get_bus_name(b, &bname) >= 0);
- assert_se(endswith(bname, name));
-
- r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay");
- assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN));
- assert_se(r == -EHOSTUNREACH);
-
- r = sd_bus_add_match(b, NULL, "interface='waldo.com',member='Piep'", NULL, NULL);
- assert_se(r >= 0);
-
- r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name");
- assert_se(r >= 0);
-
- r = sd_bus_try_close(b);
- assert_se(r == -EBUSY);
-
- r = sd_bus_process_priority(b, -10, &m);
- assert_se(r == 0);
-
- r = sd_bus_process(b, &m);
- assert_se(r > 0);
- assert_se(m);
-
- bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
- assert_se(sd_bus_message_rewind(m, true) >= 0);
-
- r = sd_bus_message_read(m, "s", &the_string);
- assert_se(r >= 0);
- assert_se(streq(the_string, "I am a string"));
-
- sd_bus_message_unref(m);
- m = NULL;
-
- r = sd_bus_request_name(a, "net.x0pointer.foobar", 0);
- assert_se(r >= 0);
-
- r = sd_bus_message_new_method_call(b, &m, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod");
- assert_se(r >= 0);
-
- assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0);
-
- assert_se(write(pipe_fds[1], "x", 1) == 1);
-
- pipe_fds[1] = safe_close(pipe_fds[1]);
-
- r = sd_bus_message_append(m, "h", pipe_fds[0]);
- assert_se(r >= 0);
-
- pipe_fds[0] = safe_close(pipe_fds[0]);
-
- r = sd_bus_send(b, m, NULL);
- assert_se(r >= 0);
-
- for (;;) {
- sd_bus_message_unref(m);
- m = NULL;
- r = sd_bus_process(a, &m);
- assert_se(r > 0);
- assert_se(m);
-
- bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
- assert_se(sd_bus_message_rewind(m, true) >= 0);
-
- if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) {
- int fd;
- char x;
-
- r = sd_bus_message_read(m, "h", &fd);
- assert_se(r >= 0);
-
- assert_se(read(fd, &x, 1) == 1);
- assert_se(x == 'x');
- break;
- }
- }
-
- r = sd_bus_release_name(a, "net.x0pointer.foobar");
- assert_se(r >= 0);
-
- r = sd_bus_release_name(a, "net.x0pointer.foobar");
- assert_se(r == -ESRCH);
-
- r = sd_bus_try_close(a);
- assert_se(r >= 0);
-
- sd_bus_unref(a);
- sd_bus_unref(b);
-
- return 0;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <math.h>
-
-#ifdef HAVE_GLIB
-#include <gio/gio.h>
-#endif
-
-#ifdef HAVE_DBUS
-#include <dbus/dbus.h>
-#endif
-
-#include "log.h"
-#include "util.h"
-
-#include "sd-bus.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "bus-dump.h"
-#include "bus-label.h"
-
-static void test_bus_path_encode_unique(void) {
- _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
-
- assert_se(bus_path_encode_unique(NULL, "/foo/bar", "some.sender", "a.suffix", &a) >= 0 && streq_ptr(a, "/foo/bar/some_2esender/a_2esuffix"));
- assert_se(bus_path_decode_unique(a, "/foo/bar", &b, &c) > 0 && streq_ptr(b, "some.sender") && streq_ptr(c, "a.suffix"));
- assert_se(bus_path_decode_unique(a, "/bar/foo", &d, &d) == 0 && !d);
- assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d, &d) == 0 && !d);
- assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d, &e) > 0 && streq_ptr(d, "") && streq_ptr(e, ""));
-}
-
-static void test_bus_path_encode(void) {
- _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
-
- assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a) >= 0 && streq(a, "/foo/bar/waldo"));
- assert_se(sd_bus_path_decode(a, "/waldo", &b) == 0 && b == NULL);
- assert_se(sd_bus_path_decode(a, "/foo/bar", &b) > 0 && streq(b, "waldo"));
-
- assert_se(sd_bus_path_encode("xxxx", "waldo", &c) < 0);
- assert_se(sd_bus_path_encode("/foo/", "waldo", &c) < 0);
-
- assert_se(sd_bus_path_encode("/foo/bar", "", &c) >= 0 && streq(c, "/foo/bar/_"));
- assert_se(sd_bus_path_decode(c, "/foo/bar", &d) > 0 && streq(d, ""));
-
- assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e) >= 0 && streq(e, "/foo/bar/foo_2ebar"));
- assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
-}
-
-static void test_bus_label_escape_one(const char *a, const char *b) {
- _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
-
- assert_se(t = bus_label_escape(a));
- assert_se(streq(t, b));
-
- assert_se(x = bus_label_unescape(t));
- assert_se(streq(a, x));
-
- assert_se(y = bus_label_unescape(b));
- assert_se(streq(a, y));
-}
-
-static void test_bus_label_escape(void) {
- test_bus_label_escape_one("foo123bar", "foo123bar");
- test_bus_label_escape_one("foo.bar", "foo_2ebar");
- test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
- test_bus_label_escape_one("", "_");
- test_bus_label_escape_one("_", "_5f");
- test_bus_label_escape_one("1", "_31");
- test_bus_label_escape_one(":1", "_3a1");
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
- int r, boolean;
- const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
- uint8_t u, v;
- void *buffer = NULL;
- size_t sz;
- char *h;
- const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
- char *s;
- _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
- _cleanup_fclose_ FILE *ms = NULL;
- size_t first_size = 0, second_size = 0, third_size = 0;
- _cleanup_bus_unref_ sd_bus *bus = NULL;
- double dbl;
- uint64_t u64;
-
- r = sd_bus_default_system(&bus);
- if (r < 0)
- return EXIT_TEST_SKIP;
-
- r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "s", "a string");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "s", NULL);
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "()");
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
- assert_se(r >= 0);
-
- r = sd_bus_message_open_container(m, 'a', "s");
- assert_se(r >= 0);
-
- r = sd_bus_message_append_basic(m, 's', "foobar");
- assert_se(r >= 0);
-
- r = sd_bus_message_append_basic(m, 's', "waldo");
- assert_se(r >= 0);
-
- r = sd_bus_message_close_container(m);
- assert_se(r >= 0);
-
- r = sd_bus_message_append_string_space(m, 5, &s);
- assert_se(r >= 0);
- strcpy(s, "hallo");
-
- r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
- assert_se(r >= 0);
-
- r = sd_bus_message_append_array(m, 'u', NULL, 0);
- assert_se(r >= 0);
-
- r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
- assert_se(r >= 0);
-
- r = bus_message_seal(m, 4711, 0);
- assert_se(r >= 0);
-
- bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- ms = open_memstream(&first, &first_size);
- bus_message_dump(m, ms, 0);
- fflush(ms);
- assert_se(!ferror(ms));
-
- r = bus_message_get_blob(m, &buffer, &sz);
- assert_se(r >= 0);
-
- h = hexmem(buffer, sz);
- assert_se(h);
-
- log_info("message size = %zu, contents =\n%s", sz, h);
- free(h);
-
-#ifdef HAVE_GLIB
- {
- GDBusMessage *g;
- char *p;
-
-#if !defined(GLIB_VERSION_2_36)
- g_type_init();
-#endif
-
- g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
- p = g_dbus_message_print(g, 0);
- log_info("%s", p);
- g_free(p);
- g_object_unref(g);
- }
-#endif
-
-#ifdef HAVE_DBUS
- {
- DBusMessage *w;
- DBusError error;
-
- dbus_error_init(&error);
-
- w = dbus_message_demarshal(buffer, sz, &error);
- if (!w)
- log_error("%s", error.message);
- else
- dbus_message_unref(w);
- }
-#endif
-
- m = sd_bus_message_unref(m);
-
- r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
- assert_se(r >= 0);
-
- bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- fclose(ms);
- ms = open_memstream(&second, &second_size);
- bus_message_dump(m, ms, 0);
- fflush(ms);
- assert_se(!ferror(ms));
- assert_se(first_size == second_size);
- assert_se(memcmp(first, second, first_size) == 0);
-
- assert_se(sd_bus_message_rewind(m, true) >= 0);
-
- r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
- assert_se(r > 0);
- assert_se(streq(x, "a string"));
- assert_se(streq(x2, ""));
- assert_se(streq(y, "string #1"));
- assert_se(streq(z, "string #2"));
- assert_se(streq(a_signature, "sba(tt)ss"));
-
- r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
- assert_se(r > 0);
- assert_se(streq(x, "foobar"));
- assert_se(streq(y, "foo"));
- assert_se(streq(z, "bar"));
- assert_se(streq(a, "waldo"));
- assert_se(streq(b, "piep"));
- assert_se(streq(c, "pap"));
- assert_se(streq(d, "after"));
-
- r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
- assert_se(r > 0);
- assert_se(u == 3);
- assert_se(streq(x, "foo"));
- assert_se(v == 5);
- assert_se(streq(y, "waldo"));
-
- r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
- assert_se(r > 0);
- assert_se(v == 8);
- assert_se(u64 == 777);
- assert_se(u == 7);
-
- r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
- assert_se(r > 0);
- assert_se(v == 9);
- assert_se(u == 77);
- assert_se(u64 == 7777);
-
- r = sd_bus_message_read(m, "y", &v);
- assert_se(r > 0);
- assert_se(v == 10);
-
- r = sd_bus_message_read(m, "()");
- assert_se(r > 0);
-
- r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
- assert_se(r > 0);
- assert_se(boolean);
- assert_se(streq(x, "aaa"));
- assert_se(streq(y, "1"));
- assert_se(streq(a, "bbb"));
- assert_se(streq(b, "2"));
- assert_se(streq(c, "ccc"));
- assert_se(streq(d, "3"));
-
- assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
-
- r = sd_bus_message_read(m, "as", 2, &x, &y);
- assert_se(r > 0);
- assert_se(streq(x, "foobar"));
- assert_se(streq(y, "waldo"));
-
- r = sd_bus_message_read_basic(m, 's', &s);
- assert_se(r > 0);
- assert_se(streq(s, "hallo"));
-
- r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
- assert_se(r > 0);
- assert_se(sz == sizeof(integer_array));
- assert_se(memcmp(integer_array, return_array, sz) == 0);
-
- r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
- assert_se(r > 0);
- assert_se(sz == 0);
-
- r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
- assert_se(r > 0);
- assert_se(streq(x, "foo"));
- assert_se(u64 == 815ULL);
- assert_se(fabs(dbl - 47.0) < 0.1);
- assert_se(streq(y, "/"));
-
- r = sd_bus_message_peek_type(m, NULL, NULL);
- assert_se(r == 0);
-
- r = sd_bus_message_new_method_call(bus, ©, "foobar.waldo", "/", "foobar.waldo", "Piep");
- assert_se(r >= 0);
-
- r = sd_bus_message_rewind(m, true);
- assert_se(r >= 0);
-
- r = sd_bus_message_copy(copy, m, true);
- assert_se(r >= 0);
-
- r = bus_message_seal(copy, 4712, 0);
- assert_se(r >= 0);
-
- fclose(ms);
- ms = open_memstream(&third, &third_size);
- bus_message_dump(copy, ms, 0);
- fflush(ms);
- assert_se(!ferror(ms));
-
- printf("<%.*s>\n", (int) first_size, first);
- printf("<%.*s>\n", (int) third_size, third);
-
- assert_se(first_size == third_size);
- assert_se(memcmp(first, third, third_size) == 0);
-
- r = sd_bus_message_rewind(m, true);
- assert_se(r >= 0);
-
- assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
-
- r = sd_bus_message_skip(m, "ssasg");
- assert_se(r > 0);
-
- assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
-
- r = sd_bus_message_skip(m, "sass");
- assert_se(r >= 0);
-
- assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
-
- r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
- assert_se(r >= 0);
-
- assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
-
- r = sd_bus_message_read(m, "b", &boolean);
- assert_se(r > 0);
- assert_se(boolean);
-
- r = sd_bus_message_enter_container(m, 0, NULL);
- assert_se(r > 0);
-
- r = sd_bus_message_read(m, "(ss)", &x, &y);
- assert_se(r > 0);
-
- r = sd_bus_message_read(m, "(ss)", &a, &b);
- assert_se(r > 0);
-
- r = sd_bus_message_read(m, "(ss)", &c, &d);
- assert_se(r > 0);
-
- r = sd_bus_message_read(m, "(ss)", &x, &y);
- assert_se(r == 0);
-
- r = sd_bus_message_exit_container(m);
- assert_se(r >= 0);
-
- assert_se(streq(x, "aaa"));
- assert_se(streq(y, "1"));
- assert_se(streq(a, "bbb"));
- assert_se(streq(b, "2"));
- assert_se(streq(c, "ccc"));
- assert_se(streq(d, "3"));
-
- test_bus_label_escape();
- test_bus_path_encode();
- test_bus_path_encode_unique();
-
- return 0;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "log.h"
-#include "macro.h"
-
-#include "bus-match.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "bus-slot.h"
-
-static bool mask[32];
-
-static int filter(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
- log_info("Ran %u", PTR_TO_UINT(userdata));
- assert_se(PTR_TO_UINT(userdata) < ELEMENTSOF(mask));
- mask[PTR_TO_UINT(userdata)] = true;
- return 0;
-}
-
-static bool mask_contains(unsigned a[], unsigned n) {
- unsigned i, j;
-
- for (i = 0; i < ELEMENTSOF(mask); i++) {
- bool found = false;
-
- for (j = 0; j < n; j++)
- if (a[j] == i) {
- found = true;
- break;
- }
-
- if (found != mask[i])
- return false;
- }
-
- return true;
-}
-
-static int match_add(sd_bus_slot *slots, struct bus_match_node *root, const char *match, int value) {
- struct bus_match_component *components = NULL;
- unsigned n_components = 0;
- sd_bus_slot *s;
- int r;
-
- s = slots + value;
- zero(*s);
-
- r = bus_match_parse(match, &components, &n_components);
- if (r < 0)
- return r;
-
- s->userdata = INT_TO_PTR(value);
- s->match_callback.callback = filter;
-
- r = bus_match_add(root, components, n_components, &s->match_callback);
- bus_match_parse_free(components, n_components);
-
- return r;
-}
-
-static void test_match_scope(const char *match, enum bus_match_scope scope) {
- struct bus_match_component *components = NULL;
- unsigned n_components = 0;
-
- assert_se(bus_match_parse(match, &components, &n_components) >= 0);
- assert_se(bus_match_get_scope(components, n_components) == scope);
- bus_match_parse_free(components, n_components);
-}
-
-int main(int argc, char *argv[]) {
- struct bus_match_node root = {
- .type = BUS_MATCH_ROOT,
- };
-
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- enum bus_match_node_type i;
- sd_bus_slot slots[19];
- int r;
-
- r = sd_bus_open_system(&bus);
- if (r < 0)
- return EXIT_TEST_SKIP;
-
- assert_se(match_add(slots, &root, "arg2='wal\\'do',sender='foo',type='signal',interface='bar.x',", 1) >= 0);
- assert_se(match_add(slots, &root, "arg2='wal\\'do2',sender='foo',type='signal',interface='bar.x',", 2) >= 0);
- assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='signal',interface='bar.x',", 3) >= 0);
- assert_se(match_add(slots, &root, "arg3='test',sender='foo',type='method_call',interface='bar.x',", 4) >= 0);
- assert_se(match_add(slots, &root, "", 5) >= 0);
- assert_se(match_add(slots, &root, "interface='quux.x'", 6) >= 0);
- assert_se(match_add(slots, &root, "interface='bar.x'", 7) >= 0);
- assert_se(match_add(slots, &root, "member='waldo',path='/foo/bar'", 8) >= 0);
- assert_se(match_add(slots, &root, "path='/foo/bar'", 9) >= 0);
- assert_se(match_add(slots, &root, "path_namespace='/foo'", 10) >= 0);
- assert_se(match_add(slots, &root, "path_namespace='/foo/quux'", 11) >= 0);
- assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0);
- assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0);
- assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0);
- assert_se(match_add(slots, &root, "arg4='pi'", 15) >= 0);
- assert_se(match_add(slots, &root, "arg4='pa'", 16) >= 0);
- assert_se(match_add(slots, &root, "arg4='po'", 17) >= 0);
- assert_se(match_add(slots, &root, "arg4='pu'", 18) >= 0);
-
- bus_match_dump(&root, 0);
-
- assert_se(sd_bus_message_new_signal(bus, &m, "/foo/bar", "bar.x", "waldo") >= 0);
- assert_se(sd_bus_message_append(m, "ssssas", "one", "two", "/prefix/three", "prefix.four", 3, "pi", "pa", "po") >= 0);
- assert_se(bus_message_seal(m, 1, 0) >= 0);
-
- zero(mask);
- assert_se(bus_match_run(NULL, &root, m) == 0);
- assert_se(mask_contains((unsigned[]) { 9, 8, 7, 5, 10, 12, 13, 14, 15, 16, 17 }, 11));
-
- assert_se(bus_match_remove(&root, &slots[8].match_callback) >= 0);
- assert_se(bus_match_remove(&root, &slots[13].match_callback) >= 0);
-
- bus_match_dump(&root, 0);
-
- zero(mask);
- assert_se(bus_match_run(NULL, &root, m) == 0);
- assert_se(mask_contains((unsigned[]) { 9, 5, 10, 12, 14, 7, 15, 16, 17 }, 9));
-
- for (i = 0; i < _BUS_MATCH_NODE_TYPE_MAX; i++) {
- char buf[32];
- const char *x;
-
- assert_se(x = bus_match_node_type_to_string(i, buf, sizeof(buf)));
-
- if (i >= BUS_MATCH_MESSAGE_TYPE)
- assert_se(bus_match_node_type_from_string(x, strlen(x)) == i);
- }
-
- bus_match_free(&root);
-
- test_match_scope("interface='foobar'", BUS_MATCH_GENERIC);
- test_match_scope("", BUS_MATCH_GENERIC);
- test_match_scope("interface='org.freedesktop.DBus.Local'", BUS_MATCH_LOCAL);
- test_match_scope("sender='org.freedesktop.DBus.Local'", BUS_MATCH_LOCAL);
- test_match_scope("member='gurke',path='/org/freedesktop/DBus/Local'", BUS_MATCH_LOCAL);
- test_match_scope("arg2='piep',sender='org.freedesktop.DBus',member='waldo'", BUS_MATCH_DRIVER);
-
- return 0;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <pthread.h>
-
-#include "log.h"
-#include "util.h"
-#include "macro.h"
-#include "strv.h"
-
-#include "sd-bus.h"
-#include "bus-internal.h"
-#include "bus-message.h"
-#include "bus-util.h"
-#include "bus-dump.h"
-
-struct context {
- int fds[2];
- bool quit;
- char *something;
- char *automatic_string_property;
- uint32_t automatic_integer_property;
-};
-
-static int something_handler(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- struct context *c = userdata;
- const char *s;
- char *n = NULL;
- int r;
-
- r = sd_bus_message_read(m, "s", &s);
- assert_se(r > 0);
-
- n = strjoin("<<<", s, ">>>", NULL);
- assert_se(n);
-
- free(c->something);
- c->something = n;
-
- log_info("AlterSomething() called, got %s, returning %s", s, n);
-
- /* This should fail, since the return type doesn't match */
- assert_se(sd_bus_reply_method_return(m, "u", 4711) == -ENOMSG);
-
- r = sd_bus_reply_method_return(m, "s", n);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int exit_handler(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- struct context *c = userdata;
- int r;
-
- c->quit = true;
-
- log_info("Exit called");
-
- r = sd_bus_reply_method_return(m, "");
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
- struct context *c = userdata;
- int r;
-
- log_info("property get for %s called, returning \"%s\".", property, c->something);
-
- r = sd_bus_message_append(reply, "s", c->something);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error) {
- struct context *c = userdata;
- const char *s;
- char *n;
- int r;
-
- log_info("property set for %s called", property);
-
- r = sd_bus_message_read(value, "s", &s);
- assert_se(r >= 0);
-
- n = strdup(s);
- assert_se(n);
-
- free(c->something);
- c->something = n;
-
- return 1;
-}
-
-static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
- _cleanup_free_ char *s = NULL;
- int r;
-
- assert_se(asprintf(&s, "object %p, path %s", userdata, path) >= 0);
- r = sd_bus_message_append(reply, "s", s);
- assert_se(r >= 0);
-
- assert_se(startswith(path, "/value/") != NULL || strcmp(path, "/value") == 0);
-
- assert_se(PTR_TO_UINT(userdata) == 30);
-
- return 1;
-}
-
-static int notify_test(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", "Value", NULL) >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int notify_test2(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_properties_changed_strv(sd_bus_message_get_bus(m), m->path, "org.freedesktop.systemd.ValueTest", NULL) >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int emit_interfaces_added(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_interfaces_added(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int emit_interfaces_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_interfaces_removed(sd_bus_message_get_bus(m), "/value/a/x", "org.freedesktop.systemd.ValueTest", NULL) >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int emit_object_added(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_object_added(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static int emit_object_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
- int r;
-
- assert_se(sd_bus_emit_object_removed(sd_bus_message_get_bus(m), "/value/a/x") >= 0);
-
- r = sd_bus_reply_method_return(m, NULL);
- assert_se(r >= 0);
-
- return 1;
-}
-
-static const sd_bus_vtable vtable[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0),
- SD_BUS_METHOD("Exit", "", "", exit_handler, 0),
- SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
- SD_BUS_WRITABLE_PROPERTY("AutomaticStringProperty", "s", NULL, NULL, offsetof(struct context, automatic_string_property), 0),
- SD_BUS_WRITABLE_PROPERTY("AutomaticIntegerProperty", "u", NULL, NULL, offsetof(struct context, automatic_integer_property), 0),
- SD_BUS_METHOD("NoOperation", NULL, NULL, NULL, 0),
- SD_BUS_METHOD("EmitInterfacesAdded", NULL, NULL, emit_interfaces_added, 0),
- SD_BUS_METHOD("EmitInterfacesRemoved", NULL, NULL, emit_interfaces_removed, 0),
- SD_BUS_METHOD("EmitObjectAdded", NULL, NULL, emit_object_added, 0),
- SD_BUS_METHOD("EmitObjectRemoved", NULL, NULL, emit_object_removed, 0),
- SD_BUS_VTABLE_END
-};
-
-static const sd_bus_vtable vtable2[] = {
- SD_BUS_VTABLE_START(0),
- SD_BUS_METHOD("NotifyTest", "", "", notify_test, 0),
- SD_BUS_METHOD("NotifyTest2", "", "", notify_test2, 0),
- SD_BUS_PROPERTY("Value", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
- SD_BUS_PROPERTY("Value2", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_PROPERTY("Value3", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Value4", "s", value_handler, 10, 0),
- SD_BUS_VTABLE_END
-};
-
-static int enumerator_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
-
- if (object_path_startswith("/value", path))
- assert_se(*nodes = strv_new("/value/a", "/value/b", "/value/c", NULL));
-
- return 1;
-}
-
-static int enumerator2_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
-
- if (object_path_startswith("/value/a", path))
- assert_se(*nodes = strv_new("/value/a/x", "/value/a/y", "/value/a/z", NULL));
-
- return 1;
-}
-
-static void *server(void *p) {
- struct context *c = p;
- sd_bus *bus = NULL;
- sd_id128_t id;
- int r;
-
- c->quit = false;
-
- assert_se(sd_id128_randomize(&id) >= 0);
-
- assert_se(sd_bus_new(&bus) >= 0);
- assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
- assert_se(sd_bus_set_server(bus, 1, id) >= 0);
-
- assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test", vtable, c) >= 0);
- assert_se(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.test2", vtable, c) >= 0);
- assert_se(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
- assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL) >= 0);
- assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/a", enumerator2_callback, NULL) >= 0);
- assert_se(sd_bus_add_object_manager(bus, NULL, "/value") >= 0);
- assert_se(sd_bus_add_object_manager(bus, NULL, "/value/a") >= 0);
-
- assert_se(sd_bus_start(bus) >= 0);
-
- log_error("Entering event loop on server");
-
- while (!c->quit) {
- log_error("Loop!");
-
- r = sd_bus_process(bus, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to process requests: %m");
- goto fail;
- }
-
- if (r == 0) {
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0) {
- log_error_errno(r, "Failed to wait: %m");
- goto fail;
- }
-
- continue;
- }
- }
-
- r = 0;
-
-fail:
- if (bus) {
- sd_bus_flush(bus);
- sd_bus_unref(bus);
- }
-
- return INT_TO_PTR(r);
-}
-
-static int client(struct context *c) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_unref_ sd_bus *bus = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- const char *s;
- int r;
-
- assert_se(sd_bus_new(&bus) >= 0);
- assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
- assert_se(sd_bus_start(bus) >= 0);
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "NoOperation", &error, NULL, NULL);
- assert_se(r >= 0);
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "s", "hallo");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- assert_se(streq(s, "<<<hallo>>>"));
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Doesntexist", &error, &reply, "");
- assert_se(r < 0);
- assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
-
- sd_bus_error_free(&error);
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AlterSomething", &error, &reply, "as", 1, "hallo");
- assert_se(r < 0);
- assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS));
-
- sd_bus_error_free(&error);
-
- r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- assert_se(streq(s, "<<<hallo>>>"));
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, "s", "test");
- assert_se(r >= 0);
-
- r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Something", &error, &reply, "s");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- assert_se(streq(s, "test"));
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticIntegerProperty", &error, "u", 815);
- assert_se(r >= 0);
-
- assert_se(c->automatic_integer_property == 815);
-
- r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticStringProperty", &error, "s", "Du Dödel, Du!");
- assert_se(r >= 0);
-
- assert_se(streq(c->automatic_string_property, "Du Dödel, Du!"));
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- fputs(s, stdout);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_get_property(bus, "org.freedesktop.systemd.test", "/value/xuzz", "org.freedesktop.systemd.ValueTest", "Value", &error, &reply, "s");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- log_info("read %s", s);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- fputs(s, stdout);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- fputs(s, stdout);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- assert_se(r >= 0);
-
- r = sd_bus_message_read(reply, "s", &s);
- assert_se(r >= 0);
- fputs(s, stdout);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "");
- assert_se(r >= 0);
-
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", "org.freedesktop.systemd.ValueTest2");
- assert_se(r < 0);
- assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_INTERFACE));
- sd_bus_error_free(&error);
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, "");
- assert_se(r < 0);
- assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD));
- sd_bus_error_free(&error);
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", &error, &reply, "");
- assert_se(r >= 0);
-
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/a", "org.freedesktop.systemd.ValueTest", "NotifyTest2", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.Properties", "PropertiesChanged"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesAdded", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitInterfacesRemoved", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectAdded", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectRemoved", &error, NULL, "");
- assert_se(r >= 0);
-
- r = sd_bus_process(bus, &reply);
- assert_se(r > 0);
-
- assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved"));
- bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
-
- sd_bus_message_unref(reply);
- reply = NULL;
-
- r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Exit", &error, NULL, "");
- assert_se(r >= 0);
-
- sd_bus_flush(bus);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- struct context c = {};
- pthread_t s;
- void *p;
- int r, q;
-
- zero(c);
-
- c.automatic_integer_property = 4711;
- assert_se(c.automatic_string_property = strdup("dudeldu"));
-
- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
-
- r = pthread_create(&s, NULL, server, &c);
- if (r != 0)
- return -r;
-
- r = client(&c);
-
- q = pthread_join(s, &p);
- if (q != 0)
- return -q;
-
- if (r < 0)
- return r;
-
- if (PTR_TO_INT(p) < 0)
- return PTR_TO_INT(p);
-
- free(c.something);
- free(c.automatic_string_property);
-
- return EXIT_SUCCESS;
-}
+++ /dev/null
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-#include "log.h"
-#include "bus-signature.h"
-#include "bus-internal.h"
-
-int main(int argc, char *argv[]) {
- char prefix[256];
- int r;
-
- assert_se(signature_is_single("y", false));
- assert_se(signature_is_single("u", false));
- assert_se(signature_is_single("v", false));
- assert_se(signature_is_single("as", false));
- assert_se(signature_is_single("(ss)", false));
- assert_se(signature_is_single("()", false));
- assert_se(signature_is_single("(()()()()())", false));
- assert_se(signature_is_single("(((())))", false));
- assert_se(signature_is_single("((((s))))", false));
- assert_se(signature_is_single("{ss}", true));
- assert_se(signature_is_single("a{ss}", false));
- assert_se(!signature_is_single("uu", false));
- assert_se(!signature_is_single("", false));
- assert_se(!signature_is_single("(", false));
- assert_se(!signature_is_single(")", false));
- assert_se(!signature_is_single("())", false));
- assert_se(!signature_is_single("((())", false));
- assert_se(!signature_is_single("{)", false));
- assert_se(!signature_is_single("{}", true));
- assert_se(!signature_is_single("{sss}", true));
- assert_se(!signature_is_single("{s}", true));
- assert_se(!signature_is_single("{ss}", false));
- assert_se(!signature_is_single("{ass}", true));
- assert_se(!signature_is_single("a}", true));
-
- assert_se(signature_is_pair("yy"));
- assert_se(signature_is_pair("ss"));
- assert_se(signature_is_pair("sas"));
- assert_se(signature_is_pair("sv"));
- assert_se(signature_is_pair("sa(vs)"));
- assert_se(!signature_is_pair(""));
- assert_se(!signature_is_pair("va"));
- assert_se(!signature_is_pair("sss"));
- assert_se(!signature_is_pair("{s}ss"));
-
- assert_se(signature_is_valid("ssa{ss}sssub", true));
- assert_se(signature_is_valid("ssa{ss}sssub", false));
- assert_se(signature_is_valid("{ss}", true));
- assert_se(!signature_is_valid("{ss}", false));
- assert_se(signature_is_valid("", true));
- assert_se(signature_is_valid("", false));
-
- assert_se(signature_is_valid("sssusa(uuubbba(uu)uuuu)a{u(uuuvas)}", false));
-
- assert_se(!signature_is_valid("a", false));
- assert_se(signature_is_valid("as", false));
- assert_se(signature_is_valid("aas", false));
- assert_se(signature_is_valid("aaas", false));
- assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad", false));
- assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
- assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
-
- assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
- assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
-
- assert_se(namespace_complex_pattern("", ""));
- assert_se(namespace_complex_pattern("foobar", "foobar"));
- assert_se(namespace_complex_pattern("foobar.waldo", "foobar.waldo"));
- assert_se(namespace_complex_pattern("foobar.", "foobar.waldo"));
- assert_se(namespace_complex_pattern("foobar.waldo", "foobar."));
- assert_se(!namespace_complex_pattern("foobar.waldo", "foobar"));
- assert_se(!namespace_complex_pattern("foobar", "foobar.waldo"));
- assert_se(!namespace_complex_pattern("", "foo"));
- assert_se(!namespace_complex_pattern("foo", ""));
- assert_se(!namespace_complex_pattern("foo.", ""));
-
- assert_se(path_complex_pattern("", ""));
- assert_se(!path_complex_pattern("", "/"));
- assert_se(!path_complex_pattern("/", ""));
- assert_se(path_complex_pattern("/", "/"));
- assert_se(path_complex_pattern("/foobar/", "/"));
- assert_se(!path_complex_pattern("/foobar/", "/foobar"));
- assert_se(path_complex_pattern("/foobar", "/foobar"));
- assert_se(!path_complex_pattern("/foobar", "/foobar/"));
- assert_se(!path_complex_pattern("/foobar", "/foobar/waldo"));
- assert_se(path_complex_pattern("/foobar/", "/foobar/waldo"));
- assert_se(path_complex_pattern("/foobar/waldo", "/foobar/"));
-
- assert_se(path_simple_pattern("/foo/", "/foo/bar/waldo"));
-
- assert_se(namespace_simple_pattern("", ""));
- assert_se(namespace_simple_pattern("", ".foobar"));
- assert_se(namespace_simple_pattern("foobar", "foobar"));
- assert_se(namespace_simple_pattern("foobar.waldo", "foobar.waldo"));
- assert_se(namespace_simple_pattern("foobar", "foobar.waldo"));
- assert_se(!namespace_simple_pattern("foobar.waldo", "foobar"));
- assert_se(!namespace_simple_pattern("", "foo"));
- assert_se(!namespace_simple_pattern("foo", ""));
- assert_se(namespace_simple_pattern("foo.", "foo.bar.waldo"));
-
- assert_se(streq(object_path_startswith("/foo/bar", "/foo"), "bar"));
- assert_se(streq(object_path_startswith("/foo", "/foo"), ""));
- assert_se(streq(object_path_startswith("/foo", "/"), "foo"));
- assert_se(streq(object_path_startswith("/", "/"), ""));
- assert_se(!object_path_startswith("/foo", "/bar"));
- assert_se(!object_path_startswith("/", "/bar"));
- assert_se(!object_path_startswith("/foo", ""));
-
- assert_se(object_path_is_valid("/foo/bar"));
- assert_se(object_path_is_valid("/foo"));
- assert_se(object_path_is_valid("/"));
- assert_se(object_path_is_valid("/foo5"));
- assert_se(object_path_is_valid("/foo_5"));
- assert_se(!object_path_is_valid(""));
- assert_se(!object_path_is_valid("/foo/"));
- assert_se(!object_path_is_valid("//"));
- assert_se(!object_path_is_valid("//foo"));
- assert_se(!object_path_is_valid("/foo//bar"));
- assert_se(!object_path_is_valid("/foo/aaaäöä"));
-
- OBJECT_PATH_FOREACH_PREFIX(prefix, "/") {
- log_info("<%s>", prefix);
- assert_not_reached("???");
- }
-
- r = 0;
- OBJECT_PATH_FOREACH_PREFIX(prefix, "/xxx") {
- log_info("<%s>", prefix);
- assert_se(streq(prefix, "/"));
- assert_se(r == 0);
- r++;
- }
- assert_se(r == 1);
-
- r = 0;
- OBJECT_PATH_FOREACH_PREFIX(prefix, "/xxx/yyy/zzz") {
- log_info("<%s>", prefix);
- assert_se(r != 0 || streq(prefix, "/xxx/yyy"));
- assert_se(r != 1 || streq(prefix, "/xxx"));
- assert_se(r != 2 || streq(prefix, "/"));
- r++;
- }
- assert_se(r == 3);
-
- return 0;
-}
-../Makefile
\ No newline at end of file
+../../Makefile
\ No newline at end of file
+++ /dev/null
-/***
- This file is part of systemd.
-
- Copyright 2008-2012 Kay Sievers <kay@vrfy.org>
- Copyright 2014 Tom Gundersen <teg@jklm.no>
-
- systemd 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.1 of the License, or
- (at your option) any later version.
-
- systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <ctype.h>
-#include <sys/types.h>
-#include <net/if.h>
-
-#include "util.h"
-#include "macro.h"
-#include "path-util.h"
-#include "strxcpyx.h"
-#include "fileio.h"
-#include "hashmap.h"
-#include "set.h"
-#include "strv.h"
-
-#include "sd-device.h"
-
-#include "device-util.h"
-#include "device-private.h"
-#include "device-internal.h"
-
-int device_new_aux(sd_device **ret) {
- _cleanup_device_unref_ sd_device *device = NULL;
-
- assert(ret);
-
- device = new0(sd_device, 1);
- if (!device)
- return -ENOMEM;
-
- device->n_ref = 1;
- device->watch_handle = -1;
-
- *ret = device;
- device = NULL;
-
- return 0;
-}
-
-_public_ sd_device *sd_device_ref(sd_device *device) {
- if (device)
- assert_se(++ device->n_ref >= 2);
-
- return device;
-}
-
-_public_ sd_device *sd_device_unref(sd_device *device) {
- if (device && -- device->n_ref == 0) {
- sd_device_unref(device->parent);
- free(device->syspath);
- free(device->sysname);
- free(device->devtype);
- free(device->devname);
- free(device->subsystem);
- free(device->driver);
- free(device->id_filename);
- free(device->properties_strv);
- free(device->properties_nulstr);
-
- ordered_hashmap_free_free_free(device->properties);
- ordered_hashmap_free_free_free(device->properties_db);
- hashmap_free_free_free(device->sysattr_values);
- set_free_free(device->sysattrs);
- set_free_free(device->tags);
- set_free_free(device->devlinks);
-
- free(device);
- }
-
- return NULL;
-}
-
-int device_add_property_aux(sd_device *device, const char *_key, const char *_value, bool db) {
- OrderedHashmap **properties;
-
- assert(device);
- assert(_key);
-
- if (db)
- properties = &device->properties_db;
- else
- properties = &device->properties;
-
- if (_value) {
- _cleanup_free_ char *key = NULL, *value = NULL, *old_key = NULL, *old_value = NULL;
- int r;
-
- r = ordered_hashmap_ensure_allocated(properties, &string_hash_ops);
- if (r < 0)
- return r;
-
- key = strdup(_key);
- if (!key)
- return -ENOMEM;
-
- value = strdup(_value);
- if (!value)
- return -ENOMEM;
-
- old_value = ordered_hashmap_get2(*properties, key, (void**) &old_key);
-
- r = ordered_hashmap_replace(*properties, key, value);
- if (r < 0)
- return r;
-
- key = NULL;
- value = NULL;
- } else {
- _cleanup_free_ char *key = NULL;
- _cleanup_free_ char *value = NULL;
-
- value = ordered_hashmap_remove2(*properties, _key, (void**) &key);
- }
-
- if (!db) {
- device->properties_generation ++;
- device->properties_buf_outdated = true;
- }
-
- return 0;
-}
-
-int device_add_property_internal(sd_device *device, const char *key, const char *value) {
- return device_add_property_aux(device, key, value, false);
-}
-
-int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
- _cleanup_free_ char *syspath = NULL;
- const char *devpath;
- int r;
-
- assert(device);
- assert(_syspath);
-
- /* must be a subdirectory of /sys */
- if (!path_startswith(_syspath, "/sys/")) {
- log_debug("sd-device: syspath '%s' is not a subdirectory of /sys", _syspath);
- return -EINVAL;
- }
-
- if (verify) {
- r = readlink_and_canonicalize(_syspath, &syspath);
- if (r == -ENOENT)
- /* the device does not exist (any more?) */
- return -ENODEV;
- else if (r == -EINVAL) {
- /* not a symlink */
- syspath = canonicalize_file_name(_syspath);
- if (!syspath) {
- if (errno == ENOENT)
- /* the device does not exist (any more?) */
- return -ENODEV;
-
- log_debug("sd-device: could not canonicalize '%s': %m", _syspath);
- return -errno;
- }
- } else if (r < 0) {
- log_debug("sd-device: could not get target of '%s': %s", _syspath, strerror(-r));
- return r;
- }
-
- if (path_startswith(syspath, "/sys/devices/")) {
- char *path;
-
- /* all 'devices' require an 'uevent' file */
- path = strjoina(syspath, "/uevent");
- r = access(path, F_OK);
- if (r < 0) {
- if (errno == ENOENT)
- /* this is not a valid device */
- return -ENODEV;
-
- log_debug("sd-device: %s does not have an uevent file: %m", syspath);
- return -errno;
- }
- } else {
- /* everything else just just needs to be a directory */
- if (!is_dir(syspath, false))
- return -ENODEV;
- }
- } else {
- syspath = strdup(_syspath);
- if (!syspath)
- return -ENOMEM;
- }
-
- devpath = syspath + strlen("/sys");
-
- r = device_add_property_internal(device, "DEVPATH", devpath);
- if (r < 0)
- return r;
-
- free(device->syspath);
- device->syspath = syspath;
- syspath = NULL;
-
- device->devpath = devpath;
-
- return 0;
-}
-
-_public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) {
- _cleanup_device_unref_ sd_device *device = NULL;
- int r;
-
- assert_return(ret, -EINVAL);
- assert_return(syspath, -EINVAL);
-
- r = device_new_aux(&device);
- if (r < 0)
- return r;
-
- r = device_set_syspath(device, syspath, true);
- if (r < 0)
- return r;
-
- *ret = device;
- device = NULL;
-
- return 0;
-}
-
-_public_ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum) {
- char *syspath;
- char id[DECIMAL_STR_MAX(unsigned) * 2 + 1];
-
- assert_return(ret, -EINVAL);
- assert_return(type == 'b' || type == 'c', -EINVAL);
-
- /* use /sys/dev/{block,char}/<maj>:<min> link */
- snprintf(id, sizeof(id), "%u:%u", major(devnum), minor(devnum));
-
- syspath = strjoina("/sys/dev/", (type == 'b' ? "block" : "char"), "/", id);
-
- return sd_device_new_from_syspath(ret, syspath);
-}
-
-_public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname) {
- char *syspath;
-
- assert_return(ret, -EINVAL);
- assert_return(subsystem, -EINVAL);
- assert_return(sysname, -EINVAL);
-
- if (streq(subsystem, "subsystem")) {
- syspath = strjoina("/sys/subsystem/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
-
- syspath = strjoina("/sys/bus/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
-
- syspath = strjoina("/sys/class/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
- } else if (streq(subsystem, "module")) {
- syspath = strjoina("/sys/module/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
- } else if (streq(subsystem, "drivers")) {
- char subsys[PATH_MAX];
- char *driver;
-
- strscpy(subsys, sizeof(subsys), sysname);
- driver = strchr(subsys, ':');
- if (driver) {
- driver[0] = '\0';
- driver++;
-
- syspath = strjoina("/sys/subsystem/", subsys, "/drivers/", driver);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
-
- syspath = strjoina("/sys/bus/", subsys, "/drivers/", driver);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
- } else
- return -EINVAL;
- } else {
- syspath = strjoina("/sys/subsystem/", subsystem, "/devices/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
-
- syspath = strjoina("/sys/bus/", subsystem, "/devices/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
-
- syspath = strjoina("/sys/class/", subsystem, "/", sysname);
- if (access(syspath, F_OK) >= 0)
- return sd_device_new_from_syspath(ret, syspath);
- }
-
- return -ENODEV;
-}
-
-int device_set_devtype(sd_device *device, const char *_devtype) {
- _cleanup_free_ char *devtype = NULL;
- int r;
-
- assert(device);
- assert(_devtype);
-
- devtype = strdup(_devtype);
- if (!devtype)
- return -ENOMEM;
-
- r = device_add_property_internal(device, "DEVTYPE", devtype);
- if (r < 0)
- return r;
-
- free(device->devtype);
- device->devtype = devtype;
- devtype = NULL;
-
- return 0;
-}
-
-int device_set_ifindex(sd_device *device, const char *_ifindex) {
- int ifindex, r;
-
- assert(device);
- assert(_ifindex);
-
- r = safe_atoi(_ifindex, &ifindex);
- if (r < 0)
- return r;
-
- if (ifindex <= 0)
- return -EINVAL;
-
- r = device_add_property_internal(device, "IFINDEX", _ifindex);
- if (r < 0)
- return r;
-
- device->ifindex = ifindex;
-
- return 0;
-}
-
-int device_set_devname(sd_device *device, const char *_devname) {
- _cleanup_free_ char *devname = NULL;
- int r;
-
- assert(device);
- assert(_devname);
-
- if (_devname[0] != '/') {
- r = asprintf(&devname, "/dev/%s", _devname);
- if (r < 0)
- return -ENOMEM;
- } else {
- devname = strdup(_devname);
- if (!devname)
- return -ENOMEM;
- }
-
- r = device_add_property_internal(device, "DEVNAME", devname);
- if (r < 0)
- return r;
-
- free(device->devname);
- device->devname = devname;
- devname = NULL;
-
- return 0;
-}
-
-int device_set_devmode(sd_device *device, const char *_devmode) {
- unsigned devmode;
- int r;
-
- assert(device);
- assert(_devmode);
-
- r = safe_atou(_devmode, &devmode);
- if (r < 0)
- return r;
-
- if (devmode > 07777)
- return -EINVAL;
-
- r = device_add_property_internal(device, "DEVMODE", _devmode);
- if (r < 0)
- return r;
-
- device->devmode = devmode;
-
- return 0;
-}
-
-int device_set_devnum(sd_device *device, const char *major, const char *minor) {
- unsigned maj = 0, min = 0;
- int r;
-
- assert(device);
- assert(major);
-
- r = safe_atou(major, &maj);
- if (r < 0)
- return r;
- if (!maj)
- return 0;
-
- if (minor) {
- r = safe_atou(minor, &min);
- if (r < 0)
- return r;
- }
-
- r = device_add_property_internal(device, "MAJOR", major);
- if (r < 0)
- return r;
-
- if (minor) {
- r = device_add_property_internal(device, "MINOR", minor);
- if (r < 0)
- return r;
- }
-
- device->devnum = makedev(maj, min);
-
- return 0;
-}
-
-static int handle_uevent_line(sd_device *device, const char *key, const char *value, const char **major, const char **minor) {
- int r;
-
- assert(device);
- assert(key);
- assert(value);
- assert(major);
- assert(minor);
-
- if (streq(key, "DEVTYPE")) {
- r = device_set_devtype(device, value);
- if (r < 0)
- return r;
- } else if (streq(key, "IFINDEX")) {
- r = device_set_ifindex(device, value);
- if (r < 0)
- return r;
- } else if (streq(key, "DEVNAME")) {
- r = device_set_devname(device, value);
- if (r < 0)
- return r;
- } else if (streq(key, "DEVMODE")) {
- r = device_set_devmode(device, value);
- if (r < 0)
- return r;
- } else if (streq(key, "MAJOR"))
- *major = value;
- else if (streq(key, "MINOR"))
- *minor = value;
- else {
- r = device_add_property_internal(device, key, value);
- if (r < 0)
- return r;
- }
-
- return 0;
-}
-
-int device_read_uevent_file(sd_device *device) {
- _cleanup_free_ char *uevent = NULL;
- const char *syspath, *key, *value, *major = NULL, *minor = NULL;
- char *path;
- size_t uevent_len;
- unsigned i;
- int r;
-
- enum {
- PRE_KEY,
- KEY,
- PRE_VALUE,
- VALUE,
- INVALID_LINE,
- } state = PRE_KEY;
-
- assert(device);
-
- if (device->uevent_loaded || device->sealed)
- return 0;
-
- device->uevent_loaded = true;
-
- r = sd_device_get_syspath(device, &syspath);
- if (r < 0)
- return r;
-
- path = strjoina(syspath, "/uevent");
-
- r = read_full_file(path, &uevent, &uevent_len);
- if (r == -EACCES)
- /* empty uevent files may be write-only */
- return 0;
- else if (r == -ENOENT)
- /* some devices may not have uevent files, see set_syspath() */
- return 0;
- else if (r < 0) {
- log_debug("sd-device: failed to read uevent file '%s': %s", path, strerror(-r));
- return r;
- }
-
- for (i = 0; i < uevent_len; i++) {
- switch (state) {
- case PRE_KEY:
- if (!strchr(NEWLINE, uevent[i])) {
- key = &uevent[i];
-
- state = KEY;
- }
-
- break;
- case KEY:
- if (uevent[i] == '=') {
- uevent[i] = '\0';
-
- state = PRE_VALUE;
- } else if (strchr(NEWLINE, uevent[i])) {
- uevent[i] = '\0';
- log_debug("sd-device: ignoring invalid uevent line '%s'", key);
-
- state = PRE_KEY;
- }
-
- break;
- case PRE_VALUE:
- value = &uevent[i];
-
- state = VALUE;
-
- break;
- case VALUE:
- if (strchr(NEWLINE, uevent[i])) {
- uevent[i] = '\0';
-
- r = handle_uevent_line(device, key, value, &major, &minor);
- if (r < 0)
- log_debug("sd-device: failed to handle uevent entry '%s=%s': %s", key, value, strerror(-r));
-
- state = PRE_KEY;
- }
-
- break;
- default:
- assert_not_reached("invalid state when parsing uevent file");
- }
- }
-
- if (major) {
- r = device_set_devnum(device, major, minor);
- if (r < 0)
- log_debug("sd-device: could not set 'MAJOR=%s' or 'MINOR=%s' from '%s': %s", major, minor, path, strerror(-r));
- }
-
- return 0;
-}
-
-_public_ int sd_device_get_ifindex(sd_device *device, int *ifindex) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(ifindex, -EINVAL);
-
- r = device_read_uevent_file(device);
- if (r < 0)
- return r;
-
- *ifindex = device->ifindex;
-
- return 0;
-}
-
-_public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
- int r;
-
- assert_return(ret, -EINVAL);
- assert_return(id, -EINVAL);
-
- switch (id[0]) {
- case 'b':
- case 'c':
- {
- char type;
- int maj, min;
-
- r = sscanf(id, "%c%i:%i", &type, &maj, &min);
- if (r != 3)
- return -EINVAL;
-
- return sd_device_new_from_devnum(ret, type, makedev(maj, min));
- }
- case 'n':
- {
- _cleanup_device_unref_ sd_device *device = NULL;
- _cleanup_close_ int sk = -1;
- struct ifreq ifr = {};
- int ifindex;
-
- r = safe_atoi(&id[1], &ifr.ifr_ifindex);
- if (r < 0)
- return r;
- else if (ifr.ifr_ifindex <= 0)
- return -EINVAL;
-
- sk = socket(PF_INET, SOCK_DGRAM, 0);
- if (sk < 0)
- return -errno;
-
- r = ioctl(sk, SIOCGIFNAME, &ifr);
- if (r < 0)
- return -errno;
-
- r = sd_device_new_from_subsystem_sysname(&device, "net", ifr.ifr_name);
- if (r < 0)
- return r;
-
- r = sd_device_get_ifindex(device, &ifindex);
- if (r < 0)
- return r;
-
- /* this is racey, so we might end up with the wrong device */
- if (ifr.ifr_ifindex != ifindex)
- return -ENODEV;
-
- *ret = device;
- device = NULL;
-
- return 0;
- }
- case '+':
- {
- char subsys[PATH_MAX];
- char *sysname;
-
- (void)strscpy(subsys, sizeof(subsys), id + 1);
- sysname = strchr(subsys, ':');
- if (!sysname)
- return -EINVAL;
-
- sysname[0] = '\0';
- sysname ++;
-
- return sd_device_new_from_subsystem_sysname(ret, subsys, sysname);
- }
- default:
- return -EINVAL;
- }
-}
-
-_public_ int sd_device_get_syspath(sd_device *device, const char **ret) {
- assert_return(device, -EINVAL);
- assert_return(ret, -EINVAL);
-
- assert(path_startswith(device->syspath, "/sys/"));
-
- *ret = device->syspath;
-
- return 0;
-}
-
-static int device_new_from_child(sd_device **ret, sd_device *child) {
- _cleanup_free_ char *path = NULL;
- const char *subdir, *syspath;
- int r;
-
- assert(ret);
- assert(child);
-
- r = sd_device_get_syspath(child, &syspath);
- if (r < 0)
- return r;
-
- path = strdup(syspath);
- if (!path)
- return -ENOMEM;
- subdir = path + strlen("/sys");
-
- for (;;) {
- char *pos;
-
- pos = strrchr(subdir, '/');
- if (!pos || pos < subdir + 2)
- break;
-
- *pos = '\0';
-
- r = sd_device_new_from_syspath(ret, path);
- if (r < 0)
- continue;
-
- return 0;
- }
-
- return -ENODEV;
-}
-
-_public_ int sd_device_get_parent(sd_device *child, sd_device **ret) {
-
- assert_return(ret, -EINVAL);
- assert_return(child, -EINVAL);
-
- if (!child->parent_set) {
- child->parent_set = true;
-
- (void)device_new_from_child(&child->parent, child);
- }
-
- if (!child->parent)
- return -ENOENT;
-
- *ret = child->parent;
-
- return 0;
-}
-
-int device_set_subsystem(sd_device *device, const char *_subsystem) {
- _cleanup_free_ char *subsystem = NULL;
- int r;
-
- assert(device);
- assert(_subsystem);
-
- subsystem = strdup(_subsystem);
- if (!subsystem)
- return -ENOMEM;
-
- r = device_add_property_internal(device, "SUBSYSTEM", subsystem);
- if (r < 0)
- return r;
-
- free(device->subsystem);
- device->subsystem = subsystem;
- subsystem = NULL;
-
- device->subsystem_set = true;
-
- return 0;
-}
-
-_public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
- assert_return(ret, -EINVAL);
- assert_return(device, -EINVAL);
-
- if (!device->subsystem_set) {
- _cleanup_free_ char *subsystem = NULL;
- const char *syspath;
- char *path;
- int r;
-
- /* read 'subsystem' link */
- r = sd_device_get_syspath(device, &syspath);
- if (r < 0)
- return r;
-
- path = strjoina(syspath, "/subsystem");
- r = readlink_value(path, &subsystem);
- if (r >= 0)
- r = device_set_subsystem(device, subsystem);
- /* use implicit names */
- else if (path_startswith(device->devpath, "/module/"))
- r = device_set_subsystem(device, "module");
- else if (strstr(device->devpath, "/drivers/"))
- r = device_set_subsystem(device, "drivers");
- else if (path_startswith(device->devpath, "/subsystem/") ||
- path_startswith(device->devpath, "/class/") ||
- path_startswith(device->devpath, "/bus/"))
- r = device_set_subsystem(device, "subsystem");
- if (r < 0 && r != -ENOENT)
- return log_debug_errno(r, "sd-device: could not set subsystem for %s: %m", device->devpath);
-
- device->subsystem_set = true;
- }
-
- if (!device->subsystem)
- return -ENOENT;
-
- *ret = device->subsystem;
-
- return 0;
-}
-
-_public_ int sd_device_get_devtype(sd_device *device, const char **devtype) {
- int r;
-
- assert(devtype);
- assert(device);
-
- r = device_read_uevent_file(device);
- if (r < 0)
- return r;
-
- *devtype = device->devtype;
-
- return 0;
-}
-
-_public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *subsystem, const char *devtype, sd_device **ret) {
- sd_device *parent = NULL;
- int r;
-
- assert_return(child, -EINVAL);
- assert_return(subsystem, -EINVAL);
-
- r = sd_device_get_parent(child, &parent);
- while (r >= 0) {
- const char *parent_subsystem = NULL;
- const char *parent_devtype = NULL;
-
- (void)sd_device_get_subsystem(parent, &parent_subsystem);
- if (streq_ptr(parent_subsystem, subsystem)) {
- if (!devtype)
- break;
-
- (void)sd_device_get_devtype(parent, &parent_devtype);
- if (streq_ptr(parent_devtype, devtype))
- break;
- }
- r = sd_device_get_parent(parent, &parent);
- }
-
- if (r < 0)
- return r;
-
- *ret = parent;
-
- return 0;
-}
-
-_public_ int sd_device_get_devnum(sd_device *device, dev_t *devnum) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(devnum, -EINVAL);
-
- r = device_read_uevent_file(device);
- if (r < 0)
- return r;
-
- *devnum = device->devnum;
-
- return 0;
-}
-
-int device_set_driver(sd_device *device, const char *_driver) {
- _cleanup_free_ char *driver = NULL;
- int r;
-
- assert(device);
- assert(_driver);
-
- driver = strdup(_driver);
- if (!driver)
- return -ENOMEM;
-
- r = device_add_property_internal(device, "DRIVER", driver);
- if (r < 0)
- return r;
-
- free(device->driver);
- device->driver = driver;
- driver = NULL;
-
- device->driver_set = true;
-
- return 0;
-}
-
-_public_ int sd_device_get_driver(sd_device *device, const char **ret) {
- assert_return(device, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!device->driver_set) {
- _cleanup_free_ char *driver = NULL;
- const char *syspath;
- char *path;
- int r;
-
- r = sd_device_get_syspath(device, &syspath);
- if (r < 0)
- return r;
-
- path = strjoina(syspath, "/driver");
- r = readlink_value(path, &driver);
- if (r >= 0) {
- r = device_set_driver(device, driver);
- if (r < 0)
- return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
- } else if (r == -ENOENT)
- device->driver_set = true;
- else
- return log_debug_errno(r, "sd-device: could not set driver for %s: %m", device->devpath);
- }
-
- if (!device->driver)
- return -ENOENT;
-
- *ret = device->driver;
-
- return 0;
-}
-
-_public_ int sd_device_get_devpath(sd_device *device, const char **devpath) {
- assert_return(device, -EINVAL);
- assert_return(devpath, -EINVAL);
-
- assert(device->devpath);
- assert(device->devpath[0] == '/');
-
- *devpath = device->devpath;
-
- return 0;
-}
-
-_public_ int sd_device_get_devname(sd_device *device, const char **devname) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(devname, -EINVAL);
-
- r = device_read_uevent_file(device);
- if (r < 0)
- return r;
-
- if (!device->devname)
- return -ENOENT;
-
- assert(path_startswith(device->devname, "/dev/"));
-
- *devname = device->devname;
-
- return 0;
-}
-
-static int device_set_sysname(sd_device *device) {
- _cleanup_free_ char *sysname = NULL;
- const char *sysnum = NULL;
- const char *pos;
- size_t len = 0;
-
- pos = strrchr(device->devpath, '/');
- if (!pos)
- return -EINVAL;
- pos ++;
-
- /* devpath is not a root directory */
- if (*pos == '\0' || pos <= device->devpath)
- return -EINVAL;
-
- sysname = strdup(pos);
- if (!sysname)
- return -ENOMEM;
-
- /* some devices have '!' in their name, change that to '/' */
- while (sysname[len] != '\0') {
- if (sysname[len] == '!')
- sysname[len] = '/';
-
- len ++;
- }
-
- /* trailing number */
- while (len > 0 && isdigit(sysname[--len]))
- sysnum = &sysname[len];
-
- if (len == 0)
- sysnum = NULL;
-
- free(device->sysname);
- device->sysname = sysname;
- sysname = NULL;
-
- device->sysnum = sysnum;
-
- device->sysname_set = true;
-
- return 0;
-}
-
-_public_ int sd_device_get_sysname(sd_device *device, const char **ret) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!device->sysname_set) {
- r = device_set_sysname(device);
- if (r < 0)
- return r;
- }
-
- assert_return(device->sysname, -ENOENT);
-
- *ret = device->sysname;
-
- return 0;
-}
-
-_public_ int sd_device_get_sysnum(sd_device *device, const char **ret) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!device->sysname_set) {
- r = device_set_sysname(device);
- if (r < 0)
- return r;
- }
-
- *ret = device->sysnum;
-
- return 0;
-}
-
-static bool is_valid_tag(const char *tag) {
- assert(tag);
-
- return !strchr(tag, ':') && !strchr(tag, ' ');
-}
-
-int device_add_tag(sd_device *device, const char *tag) {
- int r;
-
- assert(device);
- assert(tag);
-
- if (!is_valid_tag(tag))
- return -EINVAL;
-
- r = set_ensure_allocated(&device->tags, &string_hash_ops);
- if (r < 0)
- return r;
-
- r = set_put_strdup(device->tags, tag);
- if (r < 0)
- return r;
-
- device->tags_generation ++;
- device->property_tags_outdated = true;
-
- return 0;
-}
-
-int device_add_devlink(sd_device *device, const char *devlink) {
- int r;
-
- assert(device);
- assert(devlink);
-
- r = set_ensure_allocated(&device->devlinks, &string_hash_ops);
- if (r < 0)
- return r;
-
- r = set_put_strdup(device->devlinks, devlink);
- if (r < 0)
- return r;
-
- device->devlinks_generation ++;
- device->property_devlinks_outdated = true;
-
- return 0;
-}
-
-static int device_add_property_internal_from_string(sd_device *device, const char *str) {
- _cleanup_free_ char *key = NULL;
- char *value;
-
- assert(device);
- assert(str);
-
- key = strdup(str);
- if (!key)
- return -ENOMEM;
-
- value = strchr(key, '=');
- if (!value)
- return -EINVAL;
-
- *value = '\0';
-
- if (isempty(++value))
- value = NULL;
-
- return device_add_property_internal(device, key, value);
-}
-
-int device_set_usec_initialized(sd_device *device, const char *initialized) {
- uint64_t usec_initialized;
- int r;
-
- assert(device);
- assert(initialized);
-
- r = safe_atou64(initialized, &usec_initialized);
- if (r < 0)
- return r;
-
- r = device_add_property_internal(device, "USEC_INITIALIZED", initialized);
- if (r < 0)
- return r;
-
- device->usec_initialized = usec_initialized;
-
- return 0;
-}
-
-static int handle_db_line(sd_device *device, char key, const char *value) {
- char *path;
- int r;
-
- assert(device);
- assert(value);
-
- switch (key) {
- case 'G':
- r = device_add_tag(device, value);
- if (r < 0)
- return r;
-
- break;
- case 'S':
- path = strjoina("/dev/", value);
- r = device_add_devlink(device, path);
- if (r < 0)
- return r;
-
- break;
- case 'E':
- r = device_add_property_internal_from_string(device, value);
- if (r < 0)
- return r;
-
- break;
- case 'I':
- r = device_set_usec_initialized(device, value);
- if (r < 0)
- return r;
-
- break;
- case 'L':
- r = safe_atoi(value, &device->devlink_priority);
- if (r < 0)
- return r;
-
- break;
- case 'W':
- r = safe_atoi(value, &device->watch_handle);
- if (r < 0)
- return r;
-
- break;
- default:
- log_debug("device db: unknown key '%c'", key);
- }
-
- return 0;
-}
-
-int device_get_id_filename(sd_device *device, const char **ret) {
- assert(device);
- assert(ret);
-
- if (!device->id_filename) {
- _cleanup_free_ char *id = NULL;
- const char *subsystem;
- dev_t devnum;
- int ifindex, r;
-
- r = sd_device_get_subsystem(device, &subsystem);
- if (r < 0)
- return r;
-
- r = sd_device_get_devnum(device, &devnum);
- if (r < 0)
- return r;
-
- r = sd_device_get_ifindex(device, &ifindex);
- if (r < 0)
- return r;
-
- if (major(devnum) > 0) {
- assert(subsystem);
-
- /* use dev_t -- b259:131072, c254:0 */
- r = asprintf(&id, "%c%u:%u",
- streq(subsystem, "block") ? 'b' : 'c',
- major(devnum), minor(devnum));
- if (r < 0)
- return -ENOMEM;
- } else if (ifindex > 0) {
- /* use netdev ifindex -- n3 */
- r = asprintf(&id, "n%u", ifindex);
- if (r < 0)
- return -ENOMEM;
- } else {
- /* use $subsys:$sysname -- pci:0000:00:1f.2
- * sysname() has '!' translated, get it from devpath
- */
- const char *sysname;
-
- sysname = basename(device->devpath);
- if (!sysname)
- return -EINVAL;
-
- if (!subsystem)
- return -EINVAL;
-
- r = asprintf(&id, "+%s:%s", subsystem, sysname);
- if (r < 0)
- return -ENOMEM;
- }
-
- device->id_filename = id;
- id = NULL;
- }
-
- *ret = device->id_filename;
-
- return 0;
-}
-
-int device_read_db_aux(sd_device *device, bool force) {
- _cleanup_free_ char *db = NULL;
- char *path;
- const char *id, *value;
- char key;
- size_t db_len;
- unsigned i;
- int r;
-
- enum {
- PRE_KEY,
- KEY,
- PRE_VALUE,
- VALUE,
- INVALID_LINE,
- } state = PRE_KEY;
-
- if (device->db_loaded || (!force && device->sealed))
- return 0;
-
- device->db_loaded = true;
-
- r = device_get_id_filename(device, &id);
- if (r < 0)
- return r;
-
- path = strjoina("/run/udev/data/", id);
-
- r = read_full_file(path, &db, &db_len);
- if (r < 0) {
- if (r == -ENOENT)
- return 0;
- else {
- log_debug("sd-device: failed to read db '%s': %s", path, strerror(-r));
- return r;
- }
- }
-
- /* devices with a database entry are initialized */
- device->is_initialized = true;
-
- for (i = 0; i < db_len; i++) {
- switch (state) {
- case PRE_KEY:
- if (!strchr(NEWLINE, db[i])) {
- key = db[i];
-
- state = KEY;
- }
-
- break;
- case KEY:
- if (db[i] != ':') {
- log_debug("sd-device: ignoring invalid db entry with key '%c'", key);
-
- state = INVALID_LINE;
- } else {
- db[i] = '\0';
-
- state = PRE_VALUE;
- }
-
- break;
- case PRE_VALUE:
- value = &db[i];
-
- state = VALUE;
-
- break;
- case INVALID_LINE:
- if (strchr(NEWLINE, db[i]))
- state = PRE_KEY;
-
- break;
- case VALUE:
- if (strchr(NEWLINE, db[i])) {
- db[i] = '\0';
- r = handle_db_line(device, key, value);
- if (r < 0)
- log_debug("sd-device: failed to handle db entry '%c:%s': %s", key, value, strerror(-r));
-
- state = PRE_KEY;
- }
-
- break;
- default:
- assert_not_reached("invalid state when parsing db");
- }
- }
-
- return 0;
-}
-
-static int device_read_db(sd_device *device) {
- return device_read_db_aux(device, false);
-}
-
-_public_ int sd_device_get_is_initialized(sd_device *device, int *initialized) {
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(initialized, -EINVAL);
-
- r = device_read_db(device);
- if (r < 0)
- return r;
-
- *initialized = device->is_initialized;
-
- return 0;
-}
-
-_public_ int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *usec) {
- usec_t now_ts;
- int r;
-
- assert_return(device, -EINVAL);
- assert_return(usec, -EINVAL);
-
- r = device_read_db(device);
- if (r < 0)
- return r;
-
- if (!device->is_initialized)
- return -EBUSY;
-
- if (!device->usec_initialized)
- return -ENODATA;
-
- now_ts = now(clock_boottime_or_monotonic());
-
- if (now_ts < device->usec_initialized)
- return -EIO;
-
- *usec = now_ts - device->usec_initialized;
-
- return 0;
-}
-
-_public_ const char *sd_device_get_tag_first(sd_device *device) {
- void *v;
-
- assert_return(device, NULL);
-
- (void) device_read_db(device);
-
- device->tags_iterator_generation = device->tags_generation;
- device->tags_iterator = ITERATOR_FIRST;
-
- set_iterate(device->tags, &device->tags_iterator, &v);
- return v;
-}
-
-_public_ const char *sd_device_get_tag_next(sd_device *device) {
- void *v;
-
- assert_return(device, NULL);
-
- (void) device_read_db(device);
-
- if (device->tags_iterator_generation != device->tags_generation)
- return NULL;
-
- set_iterate(device->tags, &device->tags_iterator, &v);
- return v;
-}
-
-_public_ const char *sd_device_get_devlink_first(sd_device *device) {
- void *v;
-
- assert_return(device, NULL);
-
- (void) device_read_db(device);
-
- device->devlinks_iterator_generation = device->devlinks_generation;
- device->devlinks_iterator = ITERATOR_FIRST;
-
- set_iterate(device->devlinks, &device->devlinks_iterator, &v);
- return v;
-}
-
-_public_ const char *sd_device_get_devlink_next(sd_device *device) {
- void *v;
-
- assert_return(device, NULL);
-
- (void) device_read_db(device);
-
- if (device->devlinks_iterator_generation != device->devlinks_generation)
- return NULL;
-
- set_iterate(device->devlinks, &device->devlinks_iterator, &v);
- return v;
-}
-
-static int device_properties_prepare(sd_device *device) {
- int r;
-
- assert(device);
-
- r = device_read_uevent_file(device);
- if (r < 0)
- return r;
-
- r = device_read_db(device);
- if (r < 0)
- return r;
-
- if (device->property_devlinks_outdated) {
- char *devlinks = NULL;
- const char *devlink;
-
- devlink = sd_device_get_devlink_first(device);
- if (devlink)
- devlinks = strdupa(devlink);
-
- while ((devlink = sd_device_get_devlink_next(device)))
- devlinks = strjoina(devlinks, " ", devlink);
-
- r = device_add_property_internal(device, "DEVLINKS", devlinks);
- if (r < 0)
- return r;
-
- device->property_devlinks_outdated = false;
- }
-
- if (device->property_tags_outdated) {
- char *tags = NULL;
- const char *tag;
-
- tag = sd_device_get_tag_first(device);
- if (tag)
- tags = strjoina(":", tag);
-
- while ((tag = sd_device_get_tag_next(device)))
- tags = strjoina(tags, ":", tag);
-
- tags = strjoina(tags, ":");
-