]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #977 from richardmaw-codethink/machinectl-userns-login-v2
authorLennart Poettering <lennart@poettering.net>
Mon, 17 Aug 2015 13:12:15 +0000 (15:12 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 17 Aug 2015 13:12:15 +0000 (15:12 +0200)
Fix machinectl login with containers in user namespaces (v2)

85 files changed:
NEWS
README
TODO
hwdb/70-mouse.hwdb
man/systemd-nspawn.xml
man/systemd-timesyncd.service.xml
man/systemd.service.xml
man/timedatectl.xml
rules/60-persistent-storage.rules
shell-completion/bash/machinectl
shell-completion/bash/systemctl.in
shell-completion/zsh/_busctl
src/basic/def.h
src/basic/env-util.c
src/basic/strv.c
src/basic/strv.h
src/basic/util.c
src/basic/util.h
src/boot/bootctl.c
src/bus-proxyd/bus-proxyd.c
src/bus-proxyd/stdio-bridge.c
src/core/automount.c
src/core/dbus-timer.c
src/core/load-fragment.c
src/core/service.c
src/core/socket.c
src/core/timer.c
src/dbus1-generator/dbus1-generator.c
src/gpt-auto-generator/gpt-auto-generator.c
src/journal-remote/journal-gatewayd.c
src/journal-remote/journal-remote.c
src/journal/journal-file.c
src/journal/journalctl.c
src/journal/journald-server.c
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-convenience.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/bus-internal.c
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-track.c
src/libsystemd/sd-bus/busctl.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/test-bus-benchmark.c
src/libsystemd/sd-bus/test-bus-chat.c
src/libsystemd/sd-bus/test-bus-cleanup.c
src/libsystemd/sd-bus/test-bus-error.c
src/libsystemd/sd-bus/test-bus-gvariant.c
src/libsystemd/sd-bus/test-bus-kernel.c
src/libsystemd/sd-bus/test-bus-match.c
src/libsystemd/sd-bus/test-bus-objects.c
src/libsystemd/sd-bus/test-bus-server.c
src/libsystemd/sd-daemon/sd-daemon.c
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-login/sd-login.c
src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/sd-netlink.c
src/locale/localed.c
src/login/logind-inhibit.c
src/login/logind.c
src/machine/machined.c
src/nspawn/nspawn.c
src/nss-myhostname/nss-myhostname.c
src/resolve-host/resolve-host.c
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-manager.c
src/shared/bus-util.c
src/shared/bus-util.h
src/shared/condition.c
src/systemctl/systemctl.c
src/sysusers/sysusers.c
src/test/test-strv.c
src/test/test-util.c
src/tmpfiles/tmpfiles.c
src/udev/udev-builtin-blkid.c
src/udev/udev-builtin-path_id.c
src/udev/udev-ctrl.c
src/update-utmp/update-utmp.c

diff --git a/NEWS b/NEWS
index 97dd000d4e86015af2398bcd8c3c6f5ab15ee9f7..fe5eb316722b068e26beaefb6f10f003822ac922 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -756,7 +756,7 @@ CHANGES WITH 218:
         * When querying unit file enablement status (for example via
           "systemctl is-enabled"), a new state "indirect" is now known
           which indicates that a unit might not be enabled itself, but
-          another unit listed in its Alias= setting might be.
+          another unit listed in its Also= setting might be.
 
         * Similar to the various existing ConditionXYZ= settings for
           units there are now matching AssertXYZ= settings. While
diff --git a/README b/README
index 75959497650b63ae59bff341121abbb9c31c3a55..d84bf8ea69e05ef3d115656c2eb815ef541449e9 100644 (file)
--- a/README
+++ b/README
@@ -274,8 +274,3 @@ WARNINGS:
         servers if not specified otherwise at configure time. You
         really should not ship an OS or device with this default
         setting. See DISTRO_PORTING for details.
-
-ENGINEERING AND CONSULTING SERVICES:
-        ENDOCODE <https://endocode.com/> offers professional
-        engineering and consulting services for systemd. Please
-        contact Chris Kühl <chris@endocode.com> for more information.
diff --git a/TODO b/TODO
index 628d5ba3154966f8a9ef7fb0b3a216119c1bda91..fdb073aa2cc4ccecb3a7ca463e574a6c4ef8774a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,7 +6,7 @@ Bugfixes:
   automount points even when the original .automount file did not exist
   anymore. Only the .mount unit was still around.
 
-* ExecStart with unicode characters fails in strv_split_quoted:
+* ExecStart with unicode characters fails in strv_split_extract:
 
           [Service]
           Environment=ONE='one' "TWO='two two' too" THREE=
@@ -26,6 +26,12 @@ External:
 
 Features:
 
+* PID 1 should send out sd_notify("WATCHDOG=1") messages (for usage in the --user mode, and when run via nspawn)
+
+* nspawn should send out sd_notify("WATCHDOG=1") messages
+
+* nspawn should optionally support receiving WATCHDOG=1 messages from its payload PID 1...
+
 * introduce "machinectl shell" that is like systemd-run -M foo /bin/bash -t but also adds PAMName=login
 
 * allow loging into host with "machinectl login".
@@ -267,7 +273,7 @@ Features:
 
 * maybe add support for specifier expansion in user.conf, specifically DefaultEnvironment=
 
-* code cleanup: retire FOREACH_WORD_QUOTED, port to unquote_first_word() loops instead
+* code cleanup: retire FOREACH_WORD_QUOTED, port to extract_first_word() loops instead
 
 * introduce systemd-timesync-wait.service or so to sync on an NTP fix?
 
@@ -303,7 +309,7 @@ Features:
 
 * exponential backoff in timesyncd and resolved when we cannot reach a server
 
-* unquote_many_words() should probably be used by a lot of code that
+* extract_many_words() should probably be used by a lot of code that
   currently uses FOREACH_WORD and friends. For example, most conf
   parsing callbacks should use it.
 
@@ -348,7 +354,9 @@ Features:
         - avahi compat
   - DNS-SD service registration from socket units
   - edns0
-  - dname
+  - dname: Not necessary for plain DNS as synthesized cname is handed out instead if we do not
+           announce dname support. However, for DNSSEC it is necessary as the synthesized cname
+           will not be signed.
   - cname on PTR (?)
 
 * Allow multiple ExecStart= for all Type= settings, so that we can cover rescue.service nicely
@@ -464,6 +472,7 @@ Features:
   ReadOnlyDirectories=... for whitelisting files for a service.
 
 * sd-bus:
+  - change argv list matching logic
   - GetAllProperties() on a non-existing object does not result in a failure currently
   - kdbus: process fd=-1 for incoming msgs
   - port to sd-resolve for connecting to TCP dbus servers
index 7373be4778bf5a0ff71dec5f623496289c3d5196..1451fc02cc2abeacdba8d12b738e64134d2632de 100644 (file)
@@ -171,6 +171,8 @@ mouse:usb:v17efp6044:name:ThinkPad USB Laser Mouse:
 
 # Logitech M-BJ58 Optical Mouse
 mouse:usb:v046dpc00e:name:Logitech USB-PS/2 Optical Mouse:
+# Logitech Mini Optical Mouse
+mouse:usb:v046dpc016:name:Logitech Optical USB Mouse:
 # Logitech MX310 Optical Mouse
 mouse:usb:v046dpc01b:name:Logitech USB-PS/2 Optical Mouse:
 # Logitech USB-PS/2 M-BT58
@@ -219,6 +221,8 @@ mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:4008:
 # Logitech M705 (marathon mouse)
 mouse:usb:v046dp101b:name:Logitech M705:
 mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101b:
+# Logitech Performance MX
+mouse:usb:v046dp101a:name:Logitech Performance MX:
  MOUSE_DPI=800@166
 
 # Logitech MX Revolution
@@ -300,6 +304,10 @@ mouse:usb:v046dpc068:name:Logitech G500:
 mouse:bluetooth:v046dpb00d:name:Ultrathin Touch Mouse:
  MOUSE_DPI=1000@1000
 
+# ImPS/2 Logitech Wheel Mouse
+mouse:ps2:*:name:ImPS/2 Logitech Wheel Mouse:
+ MOUSE_DPI=400@100
+
 # ImExPS/2 Logitech Wheel Mouse
 mouse:ps2:*:name:ImExPS/2 Logitech Wheel Mouse:
  MOUSE_DPI=400@250
@@ -314,6 +322,10 @@ mouse:usb:v045ep0040:name:Microsoft Microsoft 3-Button Mouse with IntelliEye(TM)
 # Note: unsure that these work, it's likely that all devices on these
 # receivers show up with the same vid/pid/name
 
+# Microsoft Wireless Mouse 5000
+mouse:usb:v045ep0745:name:Microsoft Microsoft® 2.4GHz Transceiver v6.0:
+ MOUSE_DPI=800@142
+
 # Microsoft Sculpt Ergonomic Mouse
 mouse:usb:v045ep07a5:name:Microsoft Microsoft® 2.4GHz Transceiver v9.0:
  MOUSE_DPI=1000@142
index d1e050cb897d4dfea4840d197ebce0f675dcc1ca..496674925973d77bbff73dcd9ff147de88d00f10 100644 (file)
         same path in the container --, or a colon-separated pair of
         paths -- in which case the first specified path is the source
         in the host, and the second path is the destination in the
-        container. This option may be specified multiple times for
+        container. Backslash escapes are interpreted so
+        <literal>\:</literal> may be used to embed colons in either path.
+        This option may be specified multiple times for
         creating multiple independent bind mount points. The
         <option>--bind-ro=</option> option creates read-only bind
         mounts.</para></listitem>
         otherwise specified). This option is particularly useful for
         mounting directories such as <filename>/var</filename> as
         tmpfs, to allow state-less systems, in particular when
-        combined with <option>--read-only</option>.</para></listitem>
+        combined with <option>--read-only</option>.
+        Backslash escapes are interpreted in the path so
+        <literal>\:</literal> may be used to embed colons in the path.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
         list of colon-separated paths to the directory trees to
         combine and the destination mount point.</para>
 
+        <para>Backslash escapes are interpreted in the paths, so
+        <literal>\:</literal> may be used to embed colons in the paths.
+        </para>
+
         <para>If three or more paths are specified, then the last
         specified path is the destination mount point in the
         container, all paths specified before refer to directory trees
index ac1af2d136a032b5c56368c65d041fa17ad99ca0..01ed0b814928a37cc64809d5ccd1d7e980fd2e6a 100644 (file)
     files, and the per-link dynamic settings received over DHCP. See
     <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
     for more details.</para>
+
+    <para><citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+    <command>set-ntp</command> command may be used to enable and
+    start, or disable and stop this service.</para>
   </refsect1>
 
   <refsect1>
index 7e96989583475f2439b9676ce2d29756905d851c..4c113a34790416c6e6ff3b75ac68a9becb749eed 100644 (file)
         <literal>-</literal>) fail, the rest are not executed and the
         unit is considered failed.</para>
 
+        <para><varname>ExecStart=</varname> commands are only run after
+        all <varname>ExecStartPre=</varname> commands that were not prefixed
+        with a <literal>-</literal> exit successfully.</para>
+
+        <para><varname>ExecStartPost=</varname> commands are only run after
+        the service has started, as determined by <varname>Type=</varname>
+        (i.e. The process has been started for <varname>Type=simple</varname>
+        or <varname>Type=idle</varname>, the process exits successfully for
+        <varname>Type=oneshot</varname>, the initial process exits successfully
+        for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent
+        for <varname>Type=notify</varname>, or the <varname>BusName=</varname>
+        has been taken for <varname>Type=dbus</varname>).</para>
+
         <para>Note that <varname>ExecStartPre=</varname> may not be
         used to start long-running processes. All processes forked
         off by processes invoked via <varname>ExecStartPre=</varname> will
index 2d42b41d5e9c1df455fbe80b8cb4604950ee7c88..9a86c4126a932d3b2276121ffbbf7fcb2ccc7a42 100644 (file)
         <term><command>set-ntp [BOOL]</command></term>
 
         <listitem><para>Takes a boolean argument. Controls whether
-        network time synchronization is enabled (if available). This
-        enables or disables the
-        <filename>systemd-timesyncd.service</filename> unit. Note that
-        even if this command turns time synchronization off a
-        different system service might still synchronize the clock
-        with the network.</para></listitem>
+        network time synchronization is active and enabled (if
+        available). This enables and starts, or disables and stops the
+        <filename>systemd-timesyncd.service</filename> unit. It does
+        not affect the state of any other, unrelated network time
+        synchronization services that might be installed on the
+        system. This command is hence mostly equivalent to:
+        <command>systemctl enable --now
+        systemd-timesyncd.service</command> and <command>systemctl
+        disable --now systemd-timesyncd.service</command>, but is
+        protected by a different access policy.</para>
+
+        <para>Note that even if time synchronization is turned off
+        with this command another, unrelated system service might
+        still synchronize the clock with the network. Also note that
+        strictly speaking
+        <filename>systemd-timesyncd.service</filename> does more than
+        just network time synchronization as it ensures a monotonic
+        clock on systems without RTC even if no network is
+        available. See
+        <citerefentry><refentrytitle>systemd-timesyncd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+        for details about this.</para></listitem>
       </varlistentry>
 
     </variablelist>
index 5ab03fc278b37c7aa209f1736fa156ab7954aa89..0b14bb4a112c4286cef1feeba26bd78b6b29321b 100644 (file)
@@ -6,7 +6,7 @@
 ACTION=="remove", GOTO="persistent_storage_end"
 
 SUBSYSTEM!="block", GOTO="persistent_storage_end"
-KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*", GOTO="persistent_storage_end"
+KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*", GOTO="persistent_storage_end"
 
 # ignore partitions that span the entire disk
 TEST=="whole_disk", GOTO="persistent_storage_end"
index 3789492d723189ae314f8176f34f2dcb45d778cc..0d09258a0b9cceec6b476d5caf88475df7aadfc3 100644 (file)
@@ -26,7 +26,8 @@ __contains_word() {
 
 __get_machines() {
         local a b
-        machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+        (machinectl list-images --no-legend --no-pager; machinectl list --no-legend --no-pager) | \
+               { while read a b; do echo " $a"; done; } | sort -u;
 }
 
 _machinectl() {
@@ -39,8 +40,8 @@ _machinectl() {
         )
 
         local -A VERBS=(
-               [STANDALONE]='list'
-                 [MACHINES]='status show terminate kill reboot login'
+               [STANDALONE]='list list-images'
+                 [MACHINES]='status show start login enable disable poweroff reboot terminate kill copy-to copy-from image-status show-image clone rename read-only remove set-limit list-transfers cancel-transfer'
         )
 
         _init_completion || return
index c2707ba3a6ab42f3139ed222be42bbf49db3cdae..0bcd49f923620d7422e8c91a0beb68ea0f970f2d 100644 (file)
@@ -108,7 +108,7 @@ _systemctl () {
                                 comps=$(compgen -A signal)
                         ;;
                         --type|-t)
-                                comps='automount busname device mount path service snapshot socket swap target timer'
+                                comps=$(__systemctl $mode -t help)
                         ;;
                         --state)
                                 comps='loaded not-found stub
index fb1841341ea0ccf2eab59fcc2701ede32fef3533..ef790e558fbc063ec5014cd178497403a7dd7b71 100644 (file)
     local -a _busctl_cmds
     _busctl_cmds=(
         "list:List bus names"
+        "status:Show bus service, process or bus owner credentials"
         "monitor:Show bus traffic"
+        "capture:Capture bus traffix as pcap"
+        "tree:Show object tree of service"
+        "introspect:Introspect object"
+        "call:Call a method"
+        "get-property:Get property value"
+        "set-property:Set property value"
     )
     if (( CURRENT == 1 )); then
         _describe -t commands 'busctl command' _busctl_cmds || compadd "$@"
@@ -54,4 +61,12 @@ _arguments \
     '--acquired[Only show acquired names]' \
     '--activatable[Only show activatable names]' \
     '--match=[Only show matching messages]:match' \
+    '--list[Do not show tree, but simple object path list]' \
+    '--quiet[Do not show method call reply]'\
+    '--verbose[Show result values in long format]' \
+    '--expect-reply=[Expect a method call reply]:boolean:(1 0)' \
+    '--auto-start=[Auto-start destination service]:boolean:(1 0)' \
+    '--allow-interactive-authorization=[Allow interactive authorization for operation]:boolean:(1 0)' \
+    '--timeout=[Maximum time to wait for method call completion]:timeout (seconds)' \
+    '--augment-creds=[Extend credential data with data read from /proc/$PID]:boolean:(1 0)' \
     '*::busctl command:_busctl_command'
index 5aaba1fe87264d06b2ca6448eafae0e167a9f07b..e0d6822f38f6c67771a517435d63011caf300593 100644 (file)
@@ -63,7 +63,6 @@
 
 #define UNIX_SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
 #define KERNEL_SYSTEM_BUS_ADDRESS "kernel:path=/sys/fs/kdbus/0-system/bus"
-#define DEFAULT_SYSTEM_BUS_ADDRESS KERNEL_SYSTEM_BUS_ADDRESS ";" UNIX_SYSTEM_BUS_ADDRESS
 #define UNIX_USER_BUS_ADDRESS_FMT "unix:path=%s/bus"
 #define KERNEL_USER_BUS_ADDRESS_FMT "kernel:path=/sys/fs/kdbus/"UID_FMT"-user/bus"
 
index ac7bbdc7110c3f85d5149392c1058fb2894f1478..4804a67f914e5f19a0ebbedda296df30d9ca20c5 100644 (file)
@@ -550,7 +550,7 @@ char **replace_env_argv(char **argv, char **env) {
                         if (e) {
                                 int r;
 
-                                r = strv_split_quoted(&m, e, UNQUOTE_RELAX);
+                                r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES);
                                 if (r < 0) {
                                         ret[k] = NULL;
                                         strv_free(ret);
index d44a72fc484d09966ac745066499a71cedd05c65..eaf440a4b2bc7c168775bd48b3dfeb1c48613e01 100644 (file)
@@ -278,7 +278,7 @@ char **strv_split_newlines(const char *s) {
         return l;
 }
 
-int strv_split_quoted(char ***t, const char *s, UnquoteFlags flags) {
+int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
         size_t n = 0, allocated = 0;
         _cleanup_strv_free_ char **l = NULL;
         int r;
@@ -289,11 +289,12 @@ int strv_split_quoted(char ***t, const char *s, UnquoteFlags flags) {
         for (;;) {
                 _cleanup_free_ char *word = NULL;
 
-                r = unquote_first_word(&s, &word, flags);
+                r = extract_first_word(&s, &word, separators, flags);
                 if (r < 0)
                         return r;
-                if (r == 0)
+                if (r == 0) {
                         break;
+                }
 
                 if (!GREEDY_REALLOC(l, allocated, n + 2))
                         return -ENOMEM;
@@ -693,6 +694,26 @@ char **strv_reverse(char **l) {
         return l;
 }
 
+char **strv_shell_escape(char **l, const char *bad) {
+        char **s;
+
+        /* Escapes every character in every string in l that is in bad,
+         * edits in-place, does not roll-back on error. */
+
+        STRV_FOREACH(s, l) {
+                char *v;
+
+                v = shell_escape(*s, bad);
+                if (!v)
+                        return NULL;
+
+                free(*s);
+                *s = v;
+        }
+
+        return l;
+}
+
 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
         char* const* p;
 
index 22f8f98fdad09fc672ded27dba2eea1e732b7b60..f07da8cdf3b7965251ef851278cd4e68ba1c5058 100644 (file)
@@ -73,7 +73,7 @@ static inline bool strv_isempty(char * const *l) {
 char **strv_split(const char *s, const char *separator);
 char **strv_split_newlines(const char *s);
 
-int strv_split_quoted(char ***t, const char *s, UnquoteFlags flags);
+int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags);
 
 char *strv_join(char **l, const char *separator);
 char *strv_join_quoted(char **l);
@@ -145,6 +145,7 @@ void strv_print(char **l);
         }))
 
 char **strv_reverse(char **l);
+char **strv_shell_escape(char **l, const char *bad);
 
 bool strv_fnmatch(char* const* patterns, const char *s, int flags);
 
index 381146089506124d3925b6fc2584bd8cbc07232a..9571f0ab122b1c62977997fa2d7400b8b0b6224a 100644 (file)
@@ -4843,7 +4843,7 @@ int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
                 _cleanup_free_ char *word = NULL;
                 char *value = NULL;
 
-                r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -4883,7 +4883,7 @@ int get_proc_cmdline_key(const char *key, char **value) {
                 _cleanup_free_ char *word = NULL;
                 const char *e;
 
-                r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
                 if (r < 0)
                         return r;
                 if (r == 0)
@@ -5729,7 +5729,7 @@ int is_device_node(const char *path) {
         return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
 }
 
-int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
+int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
         _cleanup_free_ char *s = NULL;
         size_t allocated = 0, sz = 0;
         int r;
@@ -5742,13 +5742,19 @@ int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
                 SINGLE_QUOTE_ESCAPE,
                 DOUBLE_QUOTE,
                 DOUBLE_QUOTE_ESCAPE,
-                SPACE,
+                SEPARATOR,
         } state = START;
 
         assert(p);
-        assert(*p);
         assert(ret);
 
+        if (!separators)
+                separators = WHITESPACE;
+
+        /* Bail early if called after last value or with no input */
+        if (!*p)
+                goto finish_force_terminate;
+
         /* Parses the first word of a string, and returns it in
          * *ret. Removes all quotes in the process. When parsing fails
          * (because of an uneven number of quotes or similar), leaves
@@ -5760,32 +5766,46 @@ int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
                 switch (state) {
 
                 case START:
-                        if (c == 0)
-                                goto finish;
-                        else if (strchr(WHITESPACE, c))
+                        if (c == 0) {
+                                if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+                                        if (!GREEDY_REALLOC(s, allocated, sz+1))
+                                                return -ENOMEM;
+                                goto finish_force_terminate;
+                        } else if (strchr(separators, c)) {
+                                if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+                                        if (!GREEDY_REALLOC(s, allocated, sz+1))
+                                                return -ENOMEM;
+                                        (*p) ++;
+                                        goto finish_force_next;
+                                }
                                 break;
+                        }
 
                         state = VALUE;
                         /* fallthrough */
 
                 case VALUE:
                         if (c == 0)
-                                goto finish;
-                        else if (c == '\'') {
+                                goto finish_force_terminate;
+                        else if (c == '\'' && (flags & EXTRACT_QUOTES)) {
                                 if (!GREEDY_REALLOC(s, allocated, sz+1))
                                         return -ENOMEM;
 
                                 state = SINGLE_QUOTE;
                         } else if (c == '\\')
                                 state = VALUE_ESCAPE;
-                        else if (c == '\"') {
+                        else if (c == '\"' && (flags & EXTRACT_QUOTES)) {
                                 if (!GREEDY_REALLOC(s, allocated, sz+1))
                                         return -ENOMEM;
 
                                 state = DOUBLE_QUOTE;
-                        } else if (strchr(WHITESPACE, c))
-                                state = SPACE;
-                        else {
+                        } else if (strchr(separators, c)) {
+                                if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
+                                        (*p) ++;
+                                        goto finish_force_next;
+                                }
+                                state = SEPARATOR;
+                        } else {
                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
                                         return -ENOMEM;
 
@@ -5796,8 +5816,8 @@ int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
 
                 case SINGLE_QUOTE:
                         if (c == 0) {
-                                if (flags & UNQUOTE_RELAX)
-                                        goto finish;
+                                if (flags & EXTRACT_RELAX)
+                                        goto finish_force_terminate;
                                 return -EINVAL;
                         } else if (c == '\'')
                                 state = VALUE;
@@ -5835,29 +5855,29 @@ int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
                                 return -ENOMEM;
 
                         if (c == 0) {
-                                if ((flags & UNQUOTE_CUNESCAPE_RELAX) &&
-                                    (state == VALUE_ESCAPE || flags & UNQUOTE_RELAX)) {
+                                if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
+                                    (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
                                         /* If we find an unquoted trailing backslash and we're in
-                                         * UNQUOTE_CUNESCAPE_RELAX mode, keep it verbatim in the
+                                         * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
                                          * output.
                                          *
-                                         * Unbalanced quotes will only be allowed in UNQUOTE_RELAX
-                                         * mode, UNQUOTE_CUNESCAP_RELAX mode does not allow them.
+                                         * Unbalanced quotes will only be allowed in EXTRACT_RELAX
+                                         * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
                                          */
                                         s[sz++] = '\\';
-                                        goto finish;
+                                        goto finish_force_terminate;
                                 }
-                                if (flags & UNQUOTE_RELAX)
-                                        goto finish;
+                                if (flags & EXTRACT_RELAX)
+                                        goto finish_force_terminate;
                                 return -EINVAL;
                         }
 
-                        if (flags & UNQUOTE_CUNESCAPE) {
+                        if (flags & EXTRACT_CUNESCAPE) {
                                 uint32_t u;
 
                                 r = cunescape_one(*p, (size_t) -1, &c, &u);
                                 if (r < 0) {
-                                        if (flags & UNQUOTE_CUNESCAPE_RELAX) {
+                                        if (flags & EXTRACT_CUNESCAPE_RELAX) {
                                                 s[sz++] = '\\';
                                                 s[sz++] = c;
                                                 goto end_escape;
@@ -5880,24 +5900,29 @@ end_escape:
                                 VALUE;
                         break;
 
-                case SPACE:
+                case SEPARATOR:
                         if (c == 0)
+                                goto finish_force_terminate;
+                        if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
+                                goto finish_force_next;
+                        if (!strchr(separators, c))
                                 goto finish;
-                        if (!strchr(WHITESPACE, c))
-                                goto finish;
-
                         break;
                 }
 
                 (*p) ++;
         }
 
+finish_force_terminate:
+        *p = NULL;
 finish:
         if (!s) {
+                *p = NULL;
                 *ret = NULL;
                 return 0;
         }
 
+finish_force_next:
         s[sz] = 0;
         *ret = s;
         s = NULL;
@@ -5905,26 +5930,27 @@ finish:
         return 1;
 }
 
-int unquote_first_word_and_warn(
+int extract_first_word_and_warn(
                 const char **p,
                 char **ret,
-                UnquoteFlags flags,
+                const char *separators,
+                ExtractFlags flags,
                 const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *rvalue) {
         /* Try to unquote it, if it fails, warn about it and try again but this
-         * time using UNQUOTE_CUNESCAPE_RELAX to keep the backslashes verbatim
+         * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
          * in invalid escape sequences. */
         const char *save;
         int r;
 
         save = *p;
-        r = unquote_first_word(p, ret, flags);
-        if (r < 0 && !(flags&UNQUOTE_CUNESCAPE_RELAX)) {
-                /* Retry it with UNQUOTE_CUNESCAPE_RELAX. */
+        r = extract_first_word(p, ret, separators, flags);
+        if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
+                /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
                 *p = save;
-                r = unquote_first_word(p, ret, flags|UNQUOTE_CUNESCAPE_RELAX);
+                r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
                 if (r < 0)
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                                    "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
@@ -5935,7 +5961,7 @@ int unquote_first_word_and_warn(
         return r;
 }
 
-int unquote_many_words(const char **p, UnquoteFlags flags, ...) {
+int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
         va_list ap;
         char **l;
         int n = 0, i, c, r;
@@ -5961,7 +5987,7 @@ int unquote_many_words(const char **p, UnquoteFlags flags, ...) {
         l = newa0(char*, n);
         for (c = 0; c < n; c++) {
 
-                r = unquote_first_word(p, &l[c], flags);
+                r = extract_first_word(p, &l[c], separators, flags);
                 if (r < 0) {
                         int j;
 
@@ -6542,6 +6568,32 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
         return 0;
 }
 
+static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
+        assert(bad);
+
+        for (; *s; s++) {
+                if (*s == '\\' || strchr(bad, *s))
+                        *(t++) = '\\';
+
+                *(t++) = *s;
+        }
+
+        return t;
+}
+
+char *shell_escape(const char *s, const char *bad) {
+        char *r, *t;
+
+        r = new(char, strlen(s)*2+1);
+        if (!r)
+                return NULL;
+
+        t = strcpy_backslash_escaped(r, s, bad);
+        *t = 0;
+
+        return r;
+}
+
 char *shell_maybe_quote(const char *s) {
         const char *p;
         char *r, *t;
@@ -6568,13 +6620,7 @@ char *shell_maybe_quote(const char *s) {
         *(t++) = '"';
         t = mempcpy(t, s, p - s);
 
-        for (; *p; p++) {
-
-                if (strchr(SHELL_NEED_ESCAPE, *p))
-                        *(t++) = '\\';
-
-                *(t++) = *p;
-        }
+        t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
 
         *(t++)= '"';
         *t = 0;
index 1667b35f0049cfc2efac625a526ee3b6c699faf7..8f21d56ed8ebc494bcd0b2e0bb1efe44f9baa63d 100644 (file)
@@ -854,15 +854,17 @@ int is_symlink(const char *path);
 int is_dir(const char *path, bool follow);
 int is_device_node(const char *path);
 
-typedef enum UnquoteFlags {
-        UNQUOTE_RELAX           = 1,
-        UNQUOTE_CUNESCAPE       = 2,
-        UNQUOTE_CUNESCAPE_RELAX = 4,
-} UnquoteFlags;
-
-int unquote_first_word(const char **p, char **ret, UnquoteFlags flags);
-int unquote_first_word_and_warn(const char **p, char **ret, UnquoteFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
-int unquote_many_words(const char **p, UnquoteFlags flags, ...) _sentinel_;
+typedef enum ExtractFlags {
+        EXTRACT_RELAX           = 1,
+        EXTRACT_CUNESCAPE       = 2,
+        EXTRACT_CUNESCAPE_RELAX = 4,
+        EXTRACT_QUOTES          = 8,
+        EXTRACT_DONT_COALESCE_SEPARATORS = 16,
+} ExtractFlags;
+
+int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
+int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
+int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
 
 static inline void free_and_replace(char **s, char *v) {
         free(*s);
@@ -917,6 +919,7 @@ void cmsg_close_all(struct msghdr *mh);
 
 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
 
+char *shell_escape(const char *s, const char *bad);
 char *shell_maybe_quote(const char *s);
 
 int parse_mode(const char *s, mode_t *ret);
index 359fde999874d0288a70d3c689f3a2c2210b1784..ac1711b31836cc23017e405832d2361833078d3d 100644 (file)
@@ -818,7 +818,7 @@ static int remove_boot_efi(const char *esp_path) {
                         if (r < 0)
                                 return log_error_errno(errno, "Failed to remove \"%s/%s\": %m", p, de->d_name);
 
-                        log_info("Removed \"%s/\%s\".", p, de->d_name);
+                        log_info("Removed \"%s/%s\".", p, de->d_name);
                 }
 
                 c++;
index 3cc3b33ae70a7322c71afc478bd15fed940c61c3..6e07aea94e2c0128f12b76d413493cf0996dee68 100644 (file)
@@ -177,8 +177,9 @@ static int help(void) {
                "     --configuration=PATH Configuration file or directory\n"
                "     --machine=MACHINE    Connect to specified machine\n"
                "     --address=ADDRESS    Connect to the bus specified by ADDRESS\n"
-               "                          (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
-               program_invocation_short_name);
+               "                          (default: %s)\n",
+               program_invocation_short_name,
+               is_kdbus_available() ? KERNEL_SYSTEM_BUS_ADDRESS : UNIX_SYSTEM_BUS_ADDRESS);
 
         return 0;
 }
@@ -262,7 +263,7 @@ static int parse_argv(int argc, char *argv[]) {
         }
 
         if (!arg_address) {
-                arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
+                arg_address = strdup(is_kdbus_available() ? KERNEL_SYSTEM_BUS_ADDRESS : UNIX_SYSTEM_BUS_ADDRESS);
                 if (!arg_address)
                         return log_oom();
         }
index f275f6705fb6bc5c0eff6045f532a7cd8548da62..c5dac396d3259e4b6b03616f6d38e5f2ef9907b3 100644 (file)
@@ -50,8 +50,9 @@ static int help(void) {
                "     --version            Show package version\n"
                "     --machine=MACHINE    Connect to specified machine\n"
                "     --address=ADDRESS    Connect to the bus specified by ADDRESS\n"
-               "                          (default: " DEFAULT_SYSTEM_BUS_ADDRESS ")\n",
-               program_invocation_short_name);
+               "                          (default: %s)\n",
+               program_invocation_short_name,
+               is_kdbus_available() ? KERNEL_SYSTEM_BUS_ADDRESS : UNIX_SYSTEM_BUS_ADDRESS);
 
         return 0;
 }
@@ -137,7 +138,7 @@ static int parse_argv(int argc, char *argv[]) {
         }
 
         if (!arg_address) {
-                arg_address = strdup(DEFAULT_SYSTEM_BUS_ADDRESS);
+                arg_address = strdup(is_kdbus_available() ? KERNEL_SYSTEM_BUS_ADDRESS : UNIX_SYSTEM_BUS_ADDRESS);
                 if (!arg_address)
                         return log_oom();
         }
index 4af381b4b62510be609754378f8187156a16d834..2b84c441b2b9cc9e3848754a6639b25841425920 100644 (file)
@@ -39,7 +39,6 @@
 #include "path-util.h"
 #include "dbus-automount.h"
 #include "bus-util.h"
-#include "bus-error.h"
 #include "formats-util.h"
 #include "process-util.h"
 #include "async.h"
index 74a9914358e8e2974437316dcb01d2021ba74ea3..8ea2cf84a493906b932f2461e3c03acc1da4633a 100644 (file)
@@ -252,8 +252,7 @@ static int bus_timer_set_transient_property(
 
                         v = new0(TimerValue, 1);
                         if (!v) {
-                                if (c)
-                                        calendar_spec_free(c);
+                                calendar_spec_free(c);
                                 return -ENOMEM;
                         }
 
index 299172123e4b081b9896e73cd3d5aa308562e2a7..e1e3a5ffb72903f666980976ff240065302c07bb 100644 (file)
@@ -552,7 +552,7 @@ int config_parse_exec(
 
                 semicolon = false;
 
-                r = unquote_first_word_and_warn(&p, &firstword, UNQUOTE_CUNESCAPE, unit, filename, line, rvalue);
+                r = extract_first_word_and_warn(&p, &firstword, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
                 if (r <= 0)
                         return 0;
 
@@ -614,7 +614,7 @@ int config_parse_exec(
 
                 path_kill_slashes(path);
 
-                for (;;) {
+                while (!isempty(p)) {
                         _cleanup_free_ char *word = NULL;
 
                         /* Check explicitly for an unquoted semicolon as
@@ -627,7 +627,7 @@ int config_parse_exec(
                         }
 
                         /* Check for \; explicitly, to not confuse it with \\;
-                         * or "\;" or "\\;" etc.  unquote_first_word would
+                         * or "\;" or "\\;" etc.  extract_first_word would
                          * return the same for all of those.  */
                         if (p[0] == '\\' && p[1] == ';' && (!p[2] || strchr(WHITESPACE, p[2]))) {
                                 p += 2;
@@ -642,7 +642,7 @@ int config_parse_exec(
                                 continue;
                         }
 
-                        r = unquote_first_word_and_warn(&p, &word, UNQUOTE_CUNESCAPE, unit, filename, line, rvalue);
+                        r = extract_first_word_and_warn(&p, &word, WHITESPACE, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, unit, filename, line, rvalue);
                         if (r == 0)
                                 break;
                         else if (r < 0)
index b790ec98befa71ca438ed10f99c2a03bad4866ad..7bd8cb8b91929eb6c9552144e3797b1846b08103 100644 (file)
@@ -42,7 +42,6 @@
 #include "utf8.h"
 #include "env-util.h"
 #include "fileio.h"
-#include "bus-error.h"
 #include "bus-util.h"
 #include "bus-kernel.h"
 #include "formats-util.h"
index a3870574732edbace69b1d8b12cd111a7bcc9fdd..c78e8ad01b8eab6fcfff1e561427b3f09cf70458 100644 (file)
@@ -43,7 +43,6 @@
 #include "def.h"
 #include "smack-util.h"
 #include "bus-util.h"
-#include "bus-error.h"
 #include "selinux-util.h"
 #include "dbus-socket.h"
 #include "unit.h"
index 7f4a2eb716276e371d27f297eb806e72edb25346..7027f83dfd600abbc8deae4c48e9782c5914296b 100644 (file)
@@ -27,7 +27,6 @@
 #include "dbus-timer.h"
 #include "special.h"
 #include "bus-util.h"
-#include "bus-error.h"
 
 static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
         [TIMER_DEAD] = UNIT_INACTIVE,
@@ -57,10 +56,7 @@ void timer_free_values(Timer *t) {
 
         while ((v = t->values)) {
                 LIST_REMOVE(value, t->values, v);
-
-                if (v->calendar_spec)
-                        calendar_spec_free(v->calendar_spec);
-
+                calendar_spec_free(v->calendar_spec);
                 free(v);
         }
 }
index 4980fccc31b6a4c3f8e07291b63a18438b6c8770..25c8e209fd7b3fc607be5776ce1b7b81413d9bcf 100644 (file)
@@ -84,7 +84,8 @@ static int create_dbus_files(
                         fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type);
 
                         if (streq(type, "system"))
-                                fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_ADDRESS "\n");
+                                fprintf(f, "Environment=DBUS_STARTER_ADDRESS=%s\n",
+                                        is_kdbus_available() ? KERNEL_SYSTEM_BUS_ADDRESS : UNIX_SYSTEM_BUS_ADDRESS);
                         else if (streq(type, "session")) {
                                 char *run;
 
@@ -94,8 +95,10 @@ static int create_dbus_files(
                                         return -EINVAL;
                                 }
 
-                                fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT "\n",
-                                        getuid(), run);
+                                if (is_kdbus_available())
+                                        fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT "\n", getuid());
+                                else
+                                        fprintf(f, "Environment=DBUS_STARTER_ADDRESS="UNIX_USER_BUS_ADDRESS_FMT "\n", run);
                         }
                 }
 
index 9d889c17d8df71d7c3be842ce7ffd9cb9a97eb17..0a34f86be7cde2c44021b8b14575073f2fedcf2b 100644 (file)
@@ -240,82 +240,6 @@ static int add_mount(
         return 0;
 }
 
-static int add_automount(
-                const char *id,
-                const char *what,
-                const char *where,
-                const char *fstype,
-                bool rw,
-                const char *options,
-                const char *description,
-                usec_t timeout) {
-
-        _cleanup_free_ char *unit = NULL, *lnk = NULL;
-        _cleanup_free_ char *opt, *p = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
-        assert(id);
-        assert(where);
-        assert(description);
-
-        if (options)
-                opt = strjoin(options, ",noauto", NULL);
-        else
-                opt = strdup("noauto");
-        if (!opt)
-                return log_oom();
-
-        r = add_mount(id,
-                      what,
-                      where,
-                      fstype,
-                      rw,
-                      opt,
-                      description,
-                      NULL);
-        if (r < 0)
-                return r;
-
-        r = unit_name_from_path(where, ".automount", &unit);
-        if (r < 0)
-                return log_error_errno(r, "Failed to generate unit name: %m");
-
-        p = strjoin(arg_dest, "/", unit, NULL);
-        if (!p)
-                return log_oom();
-
-        f = fopen(p, "wxe");
-        if (!f)
-                return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
-
-        fprintf(f,
-                "# Automatically generated by systemd-gpt-auto-generator\n\n"
-                "[Unit]\n"
-                "Description=%s\n"
-                "Documentation=man:systemd-gpt-auto-generator(8)\n"
-                "[Automount]\n"
-                "Where=%s\n"
-                "TimeoutIdleSec=%lld\n",
-                description,
-                where,
-                (unsigned long long)timeout / USEC_PER_SEC);
-
-        r = fflush_and_check(f);
-        if (r < 0)
-                return log_error_errno(r, "Failed to write unit file %s: %m", p);
-
-        lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
-        if (!lnk)
-                return log_oom();
-        mkdir_parents_label(lnk, 0755);
-
-        if (symlink(p, lnk) < 0)
-                return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
-
-        return 0;
-}
-
 static bool path_is_busy(const char *where) {
         int r;
 
@@ -441,8 +365,84 @@ static int add_swap(const char *path) {
         return 0;
 }
 
-static int add_boot(const char *what) {
 #ifdef ENABLE_EFI
+static int add_automount(
+                const char *id,
+                const char *what,
+                const char *where,
+                const char *fstype,
+                bool rw,
+                const char *options,
+                const char *description,
+                usec_t timeout) {
+
+        _cleanup_free_ char *unit = NULL, *lnk = NULL;
+        _cleanup_free_ char *opt, *p = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        assert(id);
+        assert(where);
+        assert(description);
+
+        if (options)
+                opt = strjoin(options, ",noauto", NULL);
+        else
+                opt = strdup("noauto");
+        if (!opt)
+                return log_oom();
+
+        r = add_mount(id,
+                      what,
+                      where,
+                      fstype,
+                      rw,
+                      opt,
+                      description,
+                      NULL);
+        if (r < 0)
+                return r;
+
+        r = unit_name_from_path(where, ".automount", &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate unit name: %m");
+
+        p = strjoin(arg_dest, "/", unit, NULL);
+        if (!p)
+                return log_oom();
+
+        f = fopen(p, "wxe");
+        if (!f)
+                return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
+
+        fprintf(f,
+                "# Automatically generated by systemd-gpt-auto-generator\n\n"
+                "[Unit]\n"
+                "Description=%s\n"
+                "Documentation=man:systemd-gpt-auto-generator(8)\n"
+                "[Automount]\n"
+                "Where=%s\n"
+                "TimeoutIdleSec=%lld\n",
+                description,
+                where,
+                (unsigned long long)timeout / USEC_PER_SEC);
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write unit file %s: %m", p);
+
+        lnk = strjoin(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/", unit, NULL);
+        if (!lnk)
+                return log_oom();
+        mkdir_parents_label(lnk, 0755);
+
+        if (symlink(p, lnk) < 0)
+                return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
+
+        return 0;
+}
+
+static int add_boot(const char *what) {
         _cleanup_blkid_free_probe_ blkid_probe b = NULL;
         const char *fstype = NULL, *uuid = NULL;
         sd_id128_t id, type_id;
@@ -532,10 +532,12 @@ static int add_boot(const char *what) {
                        120 * USEC_PER_SEC);
 
         return r;
+}
 #else
+static int add_boot(const char *what) {
         return 0;
-#endif
 }
+#endif
 
 static int enumerate_partitions(dev_t devnum) {
 
@@ -616,9 +618,12 @@ static int enumerate_partitions(dev_t devnum) {
 
         errno = 0;
         r = blkid_do_safeprobe(b);
-        if (r == -2 || r == 1) /* no result or uncertain */
+        if (r == 1)
+                return 0; /* no results */
+        else if (r == -2) {
+                log_warning("%s: probe gave ambiguous results, ignoring", node);
                 return 0;
-        else if (r != 0)
+        else if (r != 0)
                 return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);
 
         errno = 0;
@@ -666,7 +671,6 @@ static int enumerate_partitions(dev_t devnum) {
                 blkid_partition pp;
                 dev_t qn;
                 int nr;
-                unsigned long long flags;
 
                 q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                 if (!q)
@@ -690,13 +694,6 @@ static int enumerate_partitions(dev_t devnum) {
                 if (!pp)
                         continue;
 
-                flags = blkid_partition_get_flags(pp);
-
-                /* Ignore partitions that are not marked for automatic
-                 * mounting on discovery */
-                if (flags & GPT_FLAG_NO_AUTO)
-                        continue;
-
                 nr = blkid_partition_get_partno(pp);
                 if (nr < 0)
                         continue;
@@ -709,6 +706,11 @@ static int enumerate_partitions(dev_t devnum) {
                         continue;
 
                 if (sd_id128_equal(type_id, GPT_SWAP)) {
+                        unsigned long long flags;
+
+                        flags = blkid_partition_get_flags(pp);
+                        if (flags & GPT_FLAG_NO_AUTO)
+                                continue;
 
                         if (flags & GPT_FLAG_READ_ONLY) {
                                 log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
@@ -732,6 +734,11 @@ static int enumerate_partitions(dev_t devnum) {
                                 return log_oom();
 
                 } else if (sd_id128_equal(type_id, GPT_HOME)) {
+                        unsigned long long flags;
+
+                        flags = blkid_partition_get_flags(pp);
+                        if (flags & GPT_FLAG_NO_AUTO)
+                                continue;
 
                         /* We only care for the first /home partition */
                         if (home && nr >= home_nr)
@@ -745,6 +752,11 @@ static int enumerate_partitions(dev_t devnum) {
                                 return log_oom();
 
                 } else if (sd_id128_equal(type_id, GPT_SRV)) {
+                        unsigned long long flags;
+
+                        flags = blkid_partition_get_flags(pp);
+                        if (flags & GPT_FLAG_NO_AUTO)
+                                continue;
 
                         /* We only care for the first /srv partition */
                         if (srv && nr >= srv_nr)
index 1eb07a16810c2463de596abca0fa7091488b8660..ebdd9edfc3c393eba002c8cd84cbce12ba3b13ea 100644 (file)
@@ -103,8 +103,7 @@ static void request_meta_free(
         if (!m)
                 return;
 
-        if (m->journal)
-                sd_journal_close(m->journal);
+        sd_journal_close(m->journal);
 
         if (m->tmp)
                 fclose(m->tmp);
index e3bd76051b7004dac3280e15da4f9e7435895c02..cdcda1cb52a17b1155d9928fb4f067db07be4424 100644 (file)
@@ -148,7 +148,7 @@ static int spawn_getter(const char *getter, const char *url) {
         _cleanup_strv_free_ char **words = NULL;
 
         assert(getter);
-        r = strv_split_quoted(&words, getter, 0);
+        r = strv_split_extract(&words, getter, WHITESPACE, EXTRACT_QUOTES);
         if (r < 0)
                 return log_error_errno(r, "Failed to split getter option: %m");
 
index f7815b27961c251cff428ee5e3d9cd391b4a50d8..4f94799ce74708dbbb6b7536f19336043f1154f4 100644 (file)
@@ -169,7 +169,7 @@ void journal_file_close(JournalFile *f) {
 #ifdef HAVE_GCRYPT
         if (f->fss_file)
                 munmap(f->fss_file, PAGE_ALIGN(f->fss_file_size));
-        else if (f->fsprg_state)
+        else
                 free(f->fsprg_state);
 
         free(f->fsprg_seed);
index fe83edd2b3da96e3c45c16f6474eaae968e350ca..ce2dd9da26cabd233333387b677c6b2e990788d1 100644 (file)
@@ -2066,8 +2066,12 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
         if (r == 0) {
-                printf("-- No entries --\n");
-                goto finish;
+                if (arg_follow)
+                        need_seek = true;
+                else {
+                        printf("-- No entries --\n");
+                        goto finish;
+                }
         }
 
         if (!arg_follow)
index 28b1472ac80e497d1e143f5fbb3f17c349ce9379..fa2e9b9825e3b43b126617289916f8da058a6f6c 100644 (file)
@@ -1689,6 +1689,5 @@ void server_done(Server *s) {
         if (s->mmap)
                 mmap_cache_unref(s->mmap);
 
-        if (s->udev)
-                udev_unref(s->udev);
+        udev_unref(s->udev);
 }
index 773c264cf05ba13b757e08041ffb793c3cc88d61..92b12f2ae83638924f982f3a6027ff64c64157ed 100644 (file)
@@ -32,7 +32,6 @@
 #include "bus-message.h"
 #include "bus-control.h"
 #include "bus-bloom.h"
-#include "bus-util.h"
 #include "capability.h"
 
 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
index dfd82e746d678722f82347236e181b800800bbb8..79747e058b0552b82f7d26a1cfef9a35a8308829 100644 (file)
@@ -22,7 +22,6 @@
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-signature.h"
-#include "bus-util.h"
 #include "bus-type.h"
 
 _public_ int sd_bus_emit_signal(
@@ -108,15 +107,17 @@ _public_ int sd_bus_call_method(
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member);
         if (r < 0)
-                return r;
+                goto fail;
 
         if (!isempty(types)) {
                 va_list ap;
@@ -125,10 +126,13 @@ _public_ int sd_bus_call_method(
                 r = bus_message_append_ap(m, types, ap);
                 va_end(ap);
                 if (r < 0)
-                        return r;
+                        goto fail;
         }
 
         return sd_bus_call(bus, m, 0, error, reply);
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_reply_method_return(
@@ -290,15 +294,17 @@ _public_ int sd_bus_get_property(
         sd_bus_message *rep = NULL;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
-        assert_return(member_name_is_valid(member), -EINVAL);
-        assert_return(reply, -EINVAL);
-        assert_return(signature_is_single(type, false), -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error);
+        bus_assert_return(member_name_is_valid(member), -EINVAL, error);
+        bus_assert_return(reply, -EINVAL, error);
+        bus_assert_return(signature_is_single(type, false), -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
         if (r < 0)
@@ -307,11 +313,14 @@ _public_ int sd_bus_get_property(
         r = sd_bus_message_enter_container(rep, 'v', type);
         if (r < 0) {
                 sd_bus_message_unref(rep);
-                return r;
+                goto fail;
         }
 
         *reply = rep;
         return 0;
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_get_property_trivial(
@@ -326,15 +335,17 @@ _public_ int sd_bus_get_property_trivial(
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
-        assert_return(member_name_is_valid(member), -EINVAL);
-        assert_return(bus_type_is_trivial(type), -EINVAL);
-        assert_return(ptr, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error);
+        bus_assert_return(member_name_is_valid(member), -EINVAL, error);
+        bus_assert_return(bus_type_is_trivial(type), -EINVAL, error);
+        bus_assert_return(ptr, -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
@@ -342,13 +353,16 @@ _public_ int sd_bus_get_property_trivial(
 
         r = sd_bus_message_enter_container(reply, 'v', CHAR_TO_STR(type));
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_read_basic(reply, type, ptr);
         if (r < 0)
-                return r;
+                goto fail;
 
         return 0;
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_get_property_string(
@@ -365,14 +379,16 @@ _public_ int sd_bus_get_property_string(
         char *n;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
-        assert_return(member_name_is_valid(member), -EINVAL);
-        assert_return(ret, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error);
+        bus_assert_return(member_name_is_valid(member), -EINVAL, error);
+        bus_assert_return(ret, -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
@@ -380,18 +396,23 @@ _public_ int sd_bus_get_property_string(
 
         r = sd_bus_message_enter_container(reply, 'v', "s");
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_read_basic(reply, 's', &s);
         if (r < 0)
-                return r;
+                goto fail;
 
         n = strdup(s);
-        if (!n)
-                return -ENOMEM;
+        if (!n) {
+                r = -ENOMEM;
+                goto fail;
+        }
 
         *ret = n;
         return 0;
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_get_property_strv(
@@ -406,14 +427,16 @@ _public_ int sd_bus_get_property_strv(
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
-        assert_return(member_name_is_valid(member), -EINVAL);
-        assert_return(ret, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error);
+        bus_assert_return(member_name_is_valid(member), -EINVAL, error);
+        bus_assert_return(ret, -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
         if (r < 0)
@@ -421,13 +444,16 @@ _public_ int sd_bus_get_property_strv(
 
         r = sd_bus_message_enter_container(reply, 'v', NULL);
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_read_strv(reply, ret);
         if (r < 0)
-                return r;
+                goto fail;
 
         return 0;
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_set_property(
@@ -443,38 +469,43 @@ _public_ int sd_bus_set_property(
         va_list ap;
         int r;
 
-        assert_return(bus, -EINVAL);
-        assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
-        assert_return(member_name_is_valid(member), -EINVAL);
-        assert_return(signature_is_single(type, false), -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
+        bus_assert_return(bus, -EINVAL, error);
+        bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error);
+        bus_assert_return(member_name_is_valid(member), -EINVAL, error);
+        bus_assert_return(signature_is_single(type, false), -EINVAL, error);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = sd_bus_message_new_method_call(bus, &m, destination, path, "org.freedesktop.DBus.Properties", "Set");
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_append(m, "ss", strempty(interface), member);
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_open_container(m, 'v', type);
         if (r < 0)
-                return r;
+                goto fail;
 
         va_start(ap, type);
         r = bus_message_append_ap(m, type, ap);
         va_end(ap);
         if (r < 0)
-                return r;
+                goto fail;
 
         r = sd_bus_message_close_container(m);
         if (r < 0)
-                return r;
+                goto fail;
 
         return sd_bus_call(bus, m, 0, error, NULL);
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds) {
index 1c365b7fcd54960da7dfc2e1cae6504882cbe304..130fbf7a23f45c00cc516da08e4d2ed9b8e4edf1 100644 (file)
 #include "fileio.h"
 #include "audit.h"
 #include "bus-message.h"
-#include "bus-util.h"
 #include "strv.h"
 #include "bus-creds.h"
 #include "bus-label.h"
+#include "bus-internal.h"
 
 enum {
         CAP_OFFSET_INHERITABLE = 0,
index fea796cd30483d01c7984a010f9072030fe120d1..f4ab57f5bc2e9c8a361739c0e1566677c4435a87 100644 (file)
@@ -371,3 +371,45 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
 
         return 1;
 }
+
+bool is_kdbus_wanted(void) {
+        _cleanup_free_ char *value = NULL;
+#ifdef ENABLE_KDBUS
+        const bool configured = true;
+#else
+        const bool configured = false;
+#endif
+        int r;
+
+        if (get_proc_cmdline_key("kdbus", NULL) > 0)
+                return true;
+
+        r = get_proc_cmdline_key("kdbus=", &value);
+        if (r <= 0)
+                return configured;
+
+        return parse_boolean(value) == 1;
+}
+
+bool is_kdbus_available(void) {
+        static int cached = -1;
+        _cleanup_close_ int fd = -1;
+        struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
+
+        if (cached >= 0)
+                return (bool) cached;
+
+        if (!is_kdbus_wanted()) {
+                cached = false;
+                return false;
+        }
+
+        fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
+        if (fd < 0) {
+                cached = false;
+                return false;
+        }
+
+        cached = ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
+        return cached;
+}
index c3e20ee1bf70167000a212f98ad659a40634f079..9b68fdd64207e94bee436538839d3d05797bcfe8 100644 (file)
 #include "bus-kernel.h"
 #include "kdbus.h"
 
+typedef enum BusTransport {
+        BUS_TRANSPORT_LOCAL,
+        BUS_TRANSPORT_REMOTE,
+        BUS_TRANSPORT_MACHINE,
+        _BUS_TRANSPORT_MAX,
+        _BUS_TRANSPORT_INVALID = -1
+} BusTransport;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_flush_close_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref);
+
+#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp)
+#define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp)
+#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp)
+#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp)
+#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp)
+#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp)
+#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free)
+
 struct reply_callback {
         sd_bus_message_handler_t callback;
         usec_t timeout;
@@ -393,3 +416,12 @@ int bus_remove_match_by_string(sd_bus *bus, const char *match, sd_bus_message_ha
 int bus_get_root_path(sd_bus *bus);
 
 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);
+
+bool is_kdbus_wanted(void);
+bool is_kdbus_available(void);
+
+#define bus_assert_return(expr, r, error)                               \
+        do {                                                            \
+                if (!assert_log(expr))                                  \
+                        return sd_bus_error_set_errno(error, r);        \
+        } while (false)
index 22a43c4542c1a1ad34a3f237243baf358db71885..21f37001289e37c13be341caea156abe9641f546 100644 (file)
@@ -45,7 +45,6 @@
 #include "bus-message.h"
 #include "bus-kernel.h"
 #include "bus-bloom.h"
-#include "bus-util.h"
 #include "bus-label.h"
 
 #define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
index 18c36ce2431594d4344615b1a0fe0e75eaeada97..f3b49c0c9058a10b05df24db7527aca18563edf5 100644 (file)
@@ -22,7 +22,6 @@
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-match.h"
-#include "bus-util.h"
 #include "strv.h"
 
 /* Example:
index 94427ed664f0cf470123b62f044f82acfdf17ae9..a212f0b398bd9de9e581ea73e1ae094ef61f7b84 100644 (file)
@@ -35,7 +35,6 @@
 #include "bus-type.h"
 #include "bus-signature.h"
 #include "bus-gvariant.h"
-#include "bus-util.h"
 
 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
 
@@ -144,11 +143,7 @@ static void message_free(sd_bus_message *m) {
         if (m->iovec != m->iovec_fixed)
                 free(m->iovec);
 
-        if (m->destination_ptr) {
-                free(m->destination_ptr);
-                m->destination_ptr = NULL;
-        }
-
+        m->destination_ptr = mfree(m->destination_ptr);
         message_reset_containers(m);
         free(m->root_container.signature);
         free(m->root_container.offsets);
@@ -2687,7 +2682,7 @@ _public_ int sd_bus_message_append_array_memfd(
         int r;
 
         assert_return(m, -EINVAL);
-        assert_return(memfd >= 0, -EINVAL);
+        assert_return(memfd >= 0, -EBADF);
         assert_return(bus_type_is_trivial(type), -EINVAL);
         assert_return(size > 0, -EINVAL);
         assert_return(!m->sealed, -EPERM);
@@ -2763,7 +2758,7 @@ _public_ int sd_bus_message_append_string_memfd(
         int r;
 
         assert_return(m, -EINVAL);
-        assert_return(memfd >= 0, -EINVAL);
+        assert_return(memfd >= 0, -EBADF);
         assert_return(size > 0, -EINVAL);
         assert_return(!m->sealed, -EPERM);
         assert_return(!m->poisoned, -ESTALE);
index c25293e5e96cb9782091ee414417fdc7a0c8a5cd..17ce2975105641a47e6f644b15d74e09a93b497b 100644 (file)
@@ -26,7 +26,6 @@
 #include "bus-type.h"
 #include "bus-signature.h"
 #include "bus-introspect.h"
-#include "bus-util.h"
 #include "bus-slot.h"
 #include "bus-objects.h"
 
index e43891be258477a686b397855e741d979e2e613e..7803e39c3def331a8024d0896af68d9823644d22 100644 (file)
@@ -20,7 +20,6 @@
 ***/
 
 #include "sd-bus.h"
-#include "bus-util.h"
 #include "bus-internal.h"
 #include "bus-track.h"
 
index a1f0f30d6cdc39284e5ec44e208af9bb46424b95..181621ffc7298a701e19433636c176458b9452d2 100644 (file)
@@ -30,7 +30,6 @@
 #include "set.h"
 
 #include "sd-bus.h"
-#include "bus-internal.h"
 #include "bus-util.h"
 #include "bus-dump.h"
 #include "bus-signature.h"
index 0f075907d55d9f5926d0afe6fcfaa4d11f4a2c00..db4f21e9ff2e2ddcb949313560f2c94cf2fd3859 100644 (file)
@@ -43,7 +43,6 @@
 #include "bus-kernel.h"
 #include "bus-control.h"
 #include "bus-objects.h"
-#include "bus-util.h"
 #include "bus-container.h"
 #include "bus-protocol.h"
 #include "bus-track.h"
@@ -214,8 +213,8 @@ _public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
 _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
         assert_return(bus, -EINVAL);
         assert_return(bus->state == BUS_UNSET, -EPERM);
-        assert_return(input_fd >= 0, -EINVAL);
-        assert_return(output_fd >= 0, -EINVAL);
+        assert_return(input_fd >= 0, -EBADF);
+        assert_return(output_fd >= 0, -EBADF);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
         bus->input_fd = input_fd;
@@ -1173,7 +1172,10 @@ int bus_set_address_system(sd_bus *b) {
         if (e)
                 return sd_bus_set_address(b, e);
 
-        return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
+        if (is_kdbus_available())
+                return sd_bus_set_address(b, KERNEL_SYSTEM_BUS_ADDRESS);
+
+        return sd_bus_set_address(b, UNIX_SYSTEM_BUS_ADDRESS);
 }
 
 _public_ int sd_bus_open_system(sd_bus **ret) {
@@ -1221,16 +1223,17 @@ int bus_set_address_user(sd_bus *b) {
                 return sd_bus_set_address(b, e);
 
         e = secure_getenv("XDG_RUNTIME_DIR");
-        if (e) {
+        if (is_kdbus_available())
+                (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid());
+        else if (e) {
                 _cleanup_free_ char *ee = NULL;
 
                 ee = bus_address_escape(e);
                 if (!ee)
                         return -ENOMEM;
 
-                (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, getuid(), ee);
-        } else
-                (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid());
+                (void) asprintf(&b->address, UNIX_USER_BUS_ADDRESS_FMT, ee);
+        }
 
         if (!b->address)
                 return -ENOMEM;
@@ -1948,37 +1951,39 @@ _public_ int sd_bus_call(
         unsigned i;
         int r;
 
-        assert_return(m, -EINVAL);
-        assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
-        assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
-        assert_return(!bus_error_is_dirty(error), -EINVAL);
+        bus_assert_return(m, -EINVAL, error);
+        bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
+        bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
+        bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
 
         if (!bus)
                 bus = m->bus;
 
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-        assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
+        bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
+        bus_assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS, error);
 
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
+        if (!BUS_IS_OPEN(bus->state)) {
+                r = -ENOTCONN;
+                goto fail;
+        }
 
         r = bus_ensure_running(bus);
         if (r < 0)
-                return r;
+                goto fail;
 
         i = bus->rqueue_size;
 
         r = bus_seal_message(bus, m, usec);
         if (r < 0)
-                return r;
+                goto fail;
 
         r = bus_remarshal_message(bus, &m);
         if (r < 0)
-                return r;
+                goto fail;
 
         r = bus_send_internal(bus, m, &cookie, true);
         if (r < 0)
-                return r;
+                goto fail;
 
         timeout = calc_elapse(m->timeout);
 
@@ -2009,14 +2014,17 @@ _public_ int sd_bus_call(
                                         }
 
                                         r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
+                                        sd_bus_message_unref(incoming);
+                                        return r;
 
-                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
+                                } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
                                         r = sd_bus_error_copy(error, &incoming->error);
-                                else
+                                        sd_bus_message_unref(incoming);
+                                        return r;
+                                } else {
                                         r = -EIO;
-
-                                sd_bus_message_unref(incoming);
-                                return r;
+                                        goto fail;
+                                }
 
                         } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
                                    bus->unique_name &&
@@ -2032,7 +2040,8 @@ _public_ int sd_bus_call(
                                  * immediately. */
 
                                 sd_bus_message_unref(incoming);
-                                return -ELOOP;
+                                r = -ELOOP;
+                                goto fail;
                         }
 
                         /* Try to read more, right-away */
@@ -2043,10 +2052,10 @@ _public_ int sd_bus_call(
                 if (r < 0) {
                         if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
                                 bus_enter_closing(bus);
-                                return -ECONNRESET;
+                                r = -ECONNRESET;
                         }
 
-                        return r;
+                        goto fail;
                 }
                 if (r > 0)
                         continue;
@@ -2055,8 +2064,10 @@ _public_ int sd_bus_call(
                         usec_t n;
 
                         n = now(CLOCK_MONOTONIC);
-                        if (n >= timeout)
-                                return -ETIMEDOUT;
+                        if (n >= timeout) {
+                                r = -ETIMEDOUT;
+                                goto fail;
+                        }
 
                         left = timeout - n;
                 } else
@@ -2064,20 +2075,25 @@ _public_ int sd_bus_call(
 
                 r = bus_poll(bus, true, left);
                 if (r < 0)
-                        return r;
-                if (r == 0)
-                        return -ETIMEDOUT;
+                        goto fail;
+                if (r == 0) {
+                        r = -ETIMEDOUT;
+                        goto fail;
+                }
 
                 r = dispatch_wqueue(bus);
                 if (r < 0) {
                         if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
                                 bus_enter_closing(bus);
-                                return -ECONNRESET;
+                                r = -ECONNRESET;
                         }
 
-                        return r;
+                        goto fail;
                 }
         }
+
+fail:
+        return sd_bus_error_set_errno(error, r);
 }
 
 _public_ int sd_bus_get_fd(sd_bus *bus) {
index d14110aa04e9951d3599bfeda1d145828b4245ea..d3bf6da850ca2e4a414029f985e4d0bc7554a32c 100644 (file)
@@ -28,7 +28,6 @@
 #include "sd-bus.h"
 #include "bus-kernel.h"
 #include "bus-internal.h"
-#include "bus-util.h"
 
 #define MAX_SIZE (2*1024*1024)
 
index 754335b5e7d98afbe8be0406710f6a0537d64f70..a0aecc1f550923aa9d6ef6f1000ff3f456f18eb5 100644 (file)
@@ -33,7 +33,6 @@
 #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)));
@@ -119,9 +118,7 @@ static int server_init(sd_bus **_bus) {
         return 0;
 
 fail:
-        if (bus)
-                sd_bus_unref(bus);
-
+        sd_bus_unref(bus);
         return r;
 }
 
index f58688059304e821be5be2495317eeaf9814eb9f..b483d47468481736f4d6d940f1634b525fa69080 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdio.h>
 
 #include "sd-bus.h"
-#include "bus-util.h"
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "refcnt.h"
index 5753c04b0e818dac8e9a69fe3818a02cf9744e25..f2cfbc706fbb827984337ba654b8ced54151bc5a 100644 (file)
@@ -20,7 +20,6 @@
 ***/
 
 #include "sd-bus.h"
-#include "bus-error.h"
 #include "bus-util.h"
 #include "errno-list.h"
 #include "bus-common-errors.h"
index b078bdc5f6809c26fa82ab2166b549608a524264..414d4e9a58f09c4264358bcf60883c0607b14539 100644 (file)
@@ -27,7 +27,6 @@
 #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"
index 6506eaab2e52e414e15735c8c21aad3de08dc465..6284153a58d63974a3ec0ea3d91d3ddbaf20a699 100644 (file)
@@ -25,8 +25,8 @@
 #include "log.h"
 
 #include "sd-bus.h"
-#include "bus-kernel.h"
 #include "bus-util.h"
+#include "bus-kernel.h"
 #include "bus-dump.h"
 
 int main(int argc, char *argv[]) {
index 83cb5c62c2c4fb88180ecedb7d93ae0cf61ac9e3..f659ba3124d1f4945603b020ba31ac96db465646 100644 (file)
@@ -24,7 +24,6 @@
 
 #include "bus-match.h"
 #include "bus-message.h"
-#include "bus-util.h"
 #include "bus-slot.h"
 
 static bool mask[32];
index 359984c7f3045d14ccdceb29291ffad8dc88197f..1457759d0e5d05cd87c16930b7aefabc57d5a759 100644 (file)
@@ -30,7 +30,6 @@
 #include "sd-bus.h"
 #include "bus-internal.h"
 #include "bus-message.h"
-#include "bus-util.h"
 #include "bus-dump.h"
 
 struct context {
index 080d8eddb76ddc2fa4c939c13050cf6a5a3eefa7..604df098cc67f42c6a2fd426ec628c96b085ef34 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "sd-bus.h"
 #include "bus-internal.h"
-#include "bus-util.h"
 
 struct context {
         int fds[2];
index 82ac72c72a0f8d48b583a1272722a237c296a6ae..d230a48dafbb99d6bfc6b8d03a2417c4962eb1c4 100644 (file)
@@ -90,7 +90,7 @@ finish:
 _public_ int sd_is_fifo(int fd, const char *path) {
         struct stat st_fd;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
 
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
@@ -120,7 +120,7 @@ _public_ int sd_is_fifo(int fd, const char *path) {
 _public_ int sd_is_special(int fd, const char *path) {
         struct stat st_fd;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
 
         if (fstat(fd, &st_fd) < 0)
                 return -errno;
@@ -155,7 +155,7 @@ _public_ int sd_is_special(int fd, const char *path) {
 static int sd_is_socket_internal(int fd, int type, int listening) {
         struct stat st_fd;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(type >= 0, -EINVAL);
 
         if (fstat(fd, &st_fd) < 0)
@@ -198,7 +198,7 @@ static int sd_is_socket_internal(int fd, int type, int listening) {
 _public_ int sd_is_socket(int fd, int family, int type, int listening) {
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(family >= 0, -EINVAL);
 
         r = sd_is_socket_internal(fd, type, listening);
@@ -226,7 +226,7 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
         socklen_t l = sizeof(sockaddr);
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(IN_SET(family, 0, AF_INET, AF_INET6), -EINVAL);
 
         r = sd_is_socket_internal(fd, type, listening);
@@ -269,7 +269,7 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
         socklen_t l = sizeof(sockaddr);
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
 
         r = sd_is_socket_internal(fd, type, listening);
         if (r <= 0)
@@ -310,7 +310,7 @@ _public_ int sd_is_socket_unix(int fd, int type, int listening, const char *path
 _public_ int sd_is_mq(int fd, const char *path) {
         struct mq_attr attr;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
 
         if (mq_getattr(fd, &attr) < 0)
                 return -errno;
index 754fb7614e3c65997e528ba2d4f4aa958a831d5b..0e33ced342bf4040de3e56898465cf0266665617 100644 (file)
@@ -816,7 +816,7 @@ _public_ int sd_event_add_io(
         int r;
 
         assert_return(e, -EINVAL);
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
         assert_return(callback, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
@@ -1311,7 +1311,7 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
         int r;
 
         assert_return(s, -EINVAL);
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(s->type == SOURCE_IO, -EDOM);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
index e3885ecba66fadcdecb19e6a55b7fad8ba42e005..9bbf8974ddb8804bcfe352b5369fefc545883c6a 100644 (file)
@@ -94,7 +94,7 @@ _public_ int sd_peer_get_session(int fd, char **session) {
         struct ucred ucred = {};
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(session, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -108,7 +108,7 @@ _public_ int sd_peer_get_owner_uid(int fd, uid_t *uid) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(uid, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -122,7 +122,7 @@ _public_ int sd_peer_get_unit(int fd, char **unit) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(unit, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -136,7 +136,7 @@ _public_ int sd_peer_get_user_unit(int fd, char **unit) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(unit, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -150,7 +150,7 @@ _public_ int sd_peer_get_machine_name(int fd, char **machine) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(machine, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -164,7 +164,7 @@ _public_ int sd_peer_get_slice(int fd, char **slice) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(slice, -EINVAL);
 
         r = getpeercred(fd, &ucred);
@@ -178,7 +178,7 @@ _public_ int sd_peer_get_user_slice(int fd, char **slice) {
         struct ucred ucred;
         int r;
 
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
         assert_return(slice, -EINVAL);
 
         r = getpeercred(fd, &ucred);
index 3ba62a6be98e88284480b59fcf40b7174e8e640d..aee2ced2d93e1f43adedacc30d4707e3e043d7c8 100644 (file)
@@ -501,7 +501,7 @@ static int netlink_message_read_internal(sd_netlink_message *m, unsigned short t
         assert_return(m, -EINVAL);
         assert_return(m->sealed, -EPERM);
         assert_return(data, -EINVAL);
-        assert(m->n_containers <= RTNL_CONTAINER_DEPTH);
+        assert(m->n_containers < RTNL_CONTAINER_DEPTH);
         assert(m->containers[m->n_containers].attributes);
         assert(type < m->containers[m->n_containers].n_attributes);
 
index c413b1c26671e16468c4507947ddb80db45416fb..d248869c8dab917e01718e836112ee94dc33fe6b 100644 (file)
@@ -106,7 +106,7 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) {
         int r;
 
         assert_return(ret, -EINVAL);
-        assert_return(fd >= 0, -EINVAL);
+        assert_return(fd >= 0, -EBADF);
 
         r = sd_netlink_new(&rtnl);
         if (r < 0)
index cb4052fdd5124c8fde4eb66387f1b0a8a6b12542..e9489f04c28a035982b5ea3505a643fcd1789f90 100644 (file)
@@ -222,7 +222,7 @@ static int x11_read_data(Context *c) {
                 if (in_section && first_word(l, "Option")) {
                         _cleanup_strv_free_ char **a = NULL;
 
-                        r = strv_split_quoted(&a, l, 0);
+                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                         if (r < 0)
                                 return r;
 
@@ -245,7 +245,7 @@ static int x11_read_data(Context *c) {
                 } else if (!in_section && first_word(l, "Section")) {
                         _cleanup_strv_free_ char **a = NULL;
 
-                        r = strv_split_quoted(&a, l, 0);
+                        r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
                         if (r < 0)
                                 return -ENOMEM;
 
@@ -544,7 +544,7 @@ static int read_next_mapping(const char* filename,
                 if (l[0] == 0 || l[0] == '#')
                         continue;
 
-                r = strv_split_quoted(&b, l, 0);
+                r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
                 if (r < 0)
                         return r;
 
index a261e6a71949b5cbee7034895c760d9f9aa71221..cfae186edd615c5c8e4e3c799acca50f3aaa8c26 100644 (file)
@@ -109,20 +109,24 @@ int inhibitor_save(Inhibitor *i) {
                 _cleanup_free_ char *cc = NULL;
 
                 cc = cescape(i->who);
-                if (!cc)
+                if (!cc) {
                         r = -ENOMEM;
-                else
-                        fprintf(f, "WHO=%s\n", cc);
+                        goto fail;
+                }
+
+                fprintf(f, "WHO=%s\n", cc);
         }
 
         if (i->why) {
                 _cleanup_free_ char *cc = NULL;
 
                 cc = cescape(i->why);
-                if (!cc)
+                if (!cc) {
                         r = -ENOMEM;
-                else
-                        fprintf(f, "WHY=%s\n", cc);
+                        goto fail;
+                }
+
+                fprintf(f, "WHY=%s\n", cc);
         }
 
         if (i->fifo_path)
index cf71c0ec5a4c8ccbad96493d0816a97b89d0abe7..8ac2aceb9b37b540d49a21db09aee093fb465428 100644 (file)
@@ -153,17 +153,12 @@ static void manager_free(Manager *m) {
 
         safe_close(m->console_active_fd);
 
-        if (m->udev_seat_monitor)
-                udev_monitor_unref(m->udev_seat_monitor);
-        if (m->udev_device_monitor)
-                udev_monitor_unref(m->udev_device_monitor);
-        if (m->udev_vcsa_monitor)
-                udev_monitor_unref(m->udev_vcsa_monitor);
-        if (m->udev_button_monitor)
-                udev_monitor_unref(m->udev_button_monitor);
-
-        if (m->udev)
-                udev_unref(m->udev);
+        udev_monitor_unref(m->udev_seat_monitor);
+        udev_monitor_unref(m->udev_device_monitor);
+        udev_monitor_unref(m->udev_vcsa_monitor);
+        udev_monitor_unref(m->udev_button_monitor);
+
+        udev_unref(m->udev);
 
         if (m->unlink_nologin)
                 (void) unlink("/run/nologin");
@@ -1170,8 +1165,7 @@ finish:
                   "STOPPING=1\n"
                   "STATUS=Shutting down...");
 
-        if (m)
-                manager_free(m);
+        manager_free(m);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 1eeeaf17a50420260df7869d1e265f0d5fb709c8..c8ad157326549f3004cc197f88552d6104ac1277 100644 (file)
@@ -355,8 +355,7 @@ int main(int argc, char *argv[]) {
         log_debug("systemd-machined stopped as pid "PID_FMT, getpid());
 
 finish:
-        if (m)
-                manager_free(m);
+        manager_free(m);
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
index 0e74f20f1ac9c7aa37af90b0183e29ae9f8d1517..347260013a33ad45499fd813184dae99c9a0c58d 100644 (file)
@@ -655,17 +655,22 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case ARG_BIND:
                 case ARG_BIND_RO: {
+                        const char *current = optarg;
                         _cleanup_free_ char *source = NULL, *destination = NULL;
                         CustomMount *m;
-                        char *e;
+                        _cleanup_strv_free_ char **strv = NULL;
 
-                        e = strchr(optarg, ':');
-                        if (e) {
-                                source = strndup(optarg, e - optarg);
-                                destination = strdup(e + 1);
-                        } else {
-                                source = strdup(optarg);
-                                destination = strdup(optarg);
+                        r = extract_many_words(&current, ":", EXTRACT_DONT_COALESCE_SEPARATORS, &source, &destination, NULL);
+                        switch (r) {
+                        case 1:
+                                destination = strdup(source);
+                        case 2:
+                                break;
+                        case -ENOMEM:
+                                return log_oom();
+                        default:
+                                log_error("Invalid bind mount specification: %s", optarg);
+                                return -EINVAL;
                         }
 
                         if (!source || !destination)
@@ -690,18 +695,21 @@ static int parse_argv(int argc, char *argv[]) {
                 }
 
                 case ARG_TMPFS: {
+                        const char *current = optarg;
                         _cleanup_free_ char *path = NULL, *opts = NULL;
                         CustomMount *m;
-                        char *e;
 
-                        e = strchr(optarg, ':');
-                        if (e) {
-                                path = strndup(optarg, e - optarg);
-                                opts = strdup(e + 1);
-                        } else {
-                                path = strdup(optarg);
-                                opts = strdup("mode=0755");
+                        r = extract_first_word(&current, &path, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                        if (r == -ENOMEM)
+                                return log_oom();
+                        else if (r < 0) {
+                                log_error("Invalid tmpfs specification: %s", optarg);
+                                return r;
                         }
+                        if (r)
+                                opts = strdup(current);
+                        else
+                                opts = strdup("mode=0755");
 
                         if (!path || !opts)
                                 return log_oom();
@@ -731,9 +739,13 @@ static int parse_argv(int argc, char *argv[]) {
                         unsigned n = 0;
                         char **i;
 
-                        lower = strv_split(optarg, ":");
-                        if (!lower)
+                        r = strv_split_extract(&lower, optarg, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                        if (r == -ENOMEM)
                                 return log_oom();
+                        else if (r < 0) {
+                                log_error("Invalid overlay specification: %s", optarg);
+                                return r;
+                        }
 
                         STRV_FOREACH(i, lower) {
                                 if (!path_is_absolute(*i)) {
@@ -1227,6 +1239,21 @@ static int mount_tmpfs(const char *dest, CustomMount *m) {
         return 0;
 }
 
+static char *joined_and_escaped_lower_dirs(char * const *lower) {
+        _cleanup_strv_free_ char **sv = NULL;
+
+        sv = strv_copy(lower);
+        if (!sv)
+                return NULL;
+
+        strv_reverse(sv);
+
+        if (!strv_shell_escape(sv, ",:"))
+                return NULL;
+
+        return strv_join(sv, ":");
+}
+
 static int mount_overlay(const char *dest, CustomMount *m) {
         _cleanup_free_ char *lower = NULL;
         const char *where, *options;
@@ -1243,19 +1270,32 @@ static int mount_overlay(const char *dest, CustomMount *m) {
 
         (void) mkdir_p_label(m->source, 0755);
 
-        strv_reverse(m->lower);
-        lower = strv_join(m->lower, ":");
-        strv_reverse(m->lower);
+        lower = joined_and_escaped_lower_dirs(m->lower);
         if (!lower)
                 return log_oom();
 
-        if (m->read_only)
-                options = strjoina("lowerdir=", m->source, ":", lower);
-        else {
+        if (m->read_only) {
+                _cleanup_free_ char *escaped_source = NULL;
+
+                escaped_source = shell_escape(m->source, ",:");
+                if (!escaped_source)
+                        return log_oom();
+
+                options = strjoina("lowerdir=", escaped_source, ":", lower);
+        } else {
+                _cleanup_free_ char *escaped_source = NULL, *escaped_work_dir = NULL;
+
                 assert(m->work_dir);
                 (void) mkdir_label(m->work_dir, 0700);
 
-                options = strjoina("lowerdir=", lower, ",upperdir=", m->source, ",workdir=", m->work_dir);
+                escaped_source = shell_escape(m->source, ",:");
+                if (!escaped_source)
+                        return log_oom();
+                escaped_work_dir = shell_escape(m->work_dir, ",:");
+                if (!escaped_work_dir)
+                        return log_oom();
+
+                options = strjoina("lowerdir=", lower, ",upperdir=", escaped_source, ",workdir=", escaped_work_dir);
         }
 
         if (mount("overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options) < 0)
index ab96cb231efa1f145b9ed14a0bb2758babf5119f..69069cc75d2ede9191aa7571e69bfe6c5036b979 100644 (file)
@@ -39,7 +39,6 @@
 
 #define LOCALADDRESS_IPV4 (htonl(0x7F000002))
 #define LOCALADDRESS_IPV6 &in6addr_loopback
-#define LOOPBACK_INTERFACE "lo"
 
 NSS_GETHOSTBYNAME_PROTOTYPES(myhostname);
 NSS_GETHOSTBYADDR_PROTOTYPES(myhostname);
@@ -117,7 +116,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         }
 
         /* If this call fails we fill in 0 as scope. Which is fine */
-        lo_ifi = n_addresses <= 0 ? if_nametoindex(LOOPBACK_INTERFACE) : 0;
+        lo_ifi = n_addresses <= 0 ? LOOPBACK_IFINDEX : 0;
 
         l = strlen(canonical);
         ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
index 0edba415b60b39a9ab997fe04e3bc0e1fe280354..7525d7c32feb1fff5ae1e9b9a93be06ba263efef 100644 (file)
@@ -41,7 +41,8 @@ static uint16_t arg_class = 0;
 static bool arg_legend = true;
 static uint64_t arg_flags = 0;
 
-static void print_source(int ifindex, uint64_t flags) {
+static void print_source(int ifindex, uint64_t flags, usec_t rtt) {
+        char rtt_str[FORMAT_TIMESTAMP_MAX];
 
         if (!arg_legend)
                 return;
@@ -62,6 +63,10 @@ static void print_source(int ifindex, uint64_t flags) {
                 printf(" interface %s", strna(if_indextoname(ifindex, ifname)));
         }
 
+        assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
+
+        printf(" in %s", rtt_str);
+
         fputc('.', stdout);
         fputc('\n', stdout);
 }
@@ -74,6 +79,7 @@ static int resolve_host(sd_bus *bus, const char *name) {
         unsigned c = 0;
         int r, ifindex;
         uint64_t flags;
+        usec_t ts;
 
         assert(name);
 
@@ -93,12 +99,16 @@ static int resolve_host(sd_bus *bus, const char *name) {
         if (r < 0)
                 return bus_log_create_error(r);
 
+        ts = now(CLOCK_MONOTONIC);
+
         r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
                 log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r));
                 return r;
         }
 
+        ts = now(CLOCK_MONOTONIC) - ts;
+
         r = sd_bus_message_read(reply, "i", &ifindex);
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -182,7 +192,7 @@ static int resolve_host(sd_bus *bus, const char *name) {
                 return -ESRCH;
         }
 
-        print_source(ifindex, flags);
+        print_source(ifindex, flags, ts);
 
         return 0;
 }
@@ -195,6 +205,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
         uint64_t flags;
         unsigned c = 0;
         const char *n;
+        usec_t ts;
         int r;
 
         assert(bus);
@@ -243,12 +254,16 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
         if (r < 0)
                 return bus_log_create_error(r);
 
+        ts = now(CLOCK_MONOTONIC);
+
         r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
                 log_error("%s: resolve call failed: %s", pretty, bus_error_message(&error, r));
                 return r;
         }
 
+        ts = now(CLOCK_MONOTONIC) - ts;
+
         r = sd_bus_message_read(reply, "i", &ifindex);
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -283,7 +298,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
                 return -ESRCH;
         }
 
-        print_source(ifindex, flags);
+        print_source(ifindex, flags, ts);
 
         return 0;
 }
@@ -321,6 +336,7 @@ static int resolve_record(sd_bus *bus, const char *name) {
         unsigned n = 0;
         uint64_t flags;
         int r, ifindex;
+        usec_t ts;
 
         assert(name);
 
@@ -336,21 +352,21 @@ static int resolve_record(sd_bus *bus, const char *name) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        r = sd_bus_message_set_auto_start(req, false);
-        if (r < 0)
-                return bus_log_create_error(r);
-
         assert((uint16_t) arg_type == arg_type);
         r = sd_bus_message_append(req, "isqqt", arg_ifindex, name, arg_class, arg_type, arg_flags);
         if (r < 0)
                 return bus_log_create_error(r);
 
+        ts = now(CLOCK_MONOTONIC);
+
         r = sd_bus_call(bus, req, DNS_CALL_TIMEOUT_USEC, &error, &reply);
         if (r < 0) {
                 log_error("%s: resolve call failed: %s", name, bus_error_message(&error, r));
                 return r;
         }
 
+        ts = now(CLOCK_MONOTONIC) - ts;
+
         r = sd_bus_message_read(reply, "i", &ifindex);
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -418,7 +434,7 @@ static int resolve_record(sd_bus *bus, const char *name) {
                 return -ESRCH;
         }
 
-        print_source(ifindex, flags);
+        print_source(ifindex, flags, ts);
 
         return 0;
 }
index 9ffaf4b19f21169cf99d9e94b3987b7f3d2547b7..81ea1cafcbe6ff105d273f9c39b864d73b164419 100644 (file)
@@ -95,14 +95,19 @@ void dns_cache_flush(DnsCache *c) {
         c->by_expiry = prioq_free(c->by_expiry);
 }
 
-static void dns_cache_remove(DnsCache *c, DnsResourceKey *key) {
+static bool dns_cache_remove(DnsCache *c, DnsResourceKey *key) {
         DnsCacheItem *i;
+        bool exist = false;
 
         assert(c);
         assert(key);
 
-        while ((i = hashmap_get(c->by_key, key)))
+        while ((i = hashmap_get(c->by_key, key))) {
                 dns_cache_item_remove_and_free(c, i);
+                exist = true;
+        }
+
+        return exist;
 }
 
 static void dns_cache_make_space(DnsCache *c, unsigned add) {
@@ -263,6 +268,7 @@ static int dns_cache_put_positive(
                 const union in_addr_union *owner_address) {
 
         _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
+        _cleanup_free_ char *key_str = NULL;
         DnsCacheItem *existing;
         int r;
 
@@ -272,7 +278,14 @@ static int dns_cache_put_positive(
 
         /* New TTL is 0? Delete the entry... */
         if (rr->ttl <= 0) {
-                dns_cache_remove(c, rr->key);
+                if (dns_cache_remove(c, rr->key)) {
+                        r = dns_resource_key_to_string(rr->key, &key_str);
+                        if (r < 0)
+                                return r;
+
+                        log_debug("Removed zero TTL entry from cache: %s", key_str);
+                }
+
                 return 0;
         }
 
@@ -311,6 +324,12 @@ static int dns_cache_put_positive(
         if (r < 0)
                 return r;
 
+        r = dns_resource_key_to_string(i->key, &key_str);
+        if (r < 0)
+                return r;
+
+        log_debug("Added cache entry for %s", key_str);
+
         i = NULL;
         return 0;
 }
@@ -325,6 +344,7 @@ static int dns_cache_put_negative(
                 const union in_addr_union *owner_address) {
 
         _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
+        _cleanup_free_ char *key_str = NULL;
         int r;
 
         assert(c);
@@ -337,8 +357,15 @@ static int dns_cache_put_negative(
                 return 0;
         if (key->type == DNS_TYPE_ANY)
                 return 0;
-        if (soa_ttl <= 0)
+        if (soa_ttl <= 0) {
+                r = dns_resource_key_to_string(key, &key_str);
+                if (r < 0)
+                        return r;
+
+                log_debug("Ignored negative cache entry with zero SOA TTL: %s", key_str);
+
                 return 0;
+        }
 
         if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
                 return 0;
@@ -364,6 +391,12 @@ static int dns_cache_put_negative(
         if (r < 0)
                 return r;
 
+        r = dns_resource_key_to_string(i->key, &key_str);
+        if (r < 0)
+                return r;
+
+        log_debug("Added %s cache entry for %s", i->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", key_str);
+
         i = NULL;
         return 0;
 }
@@ -468,11 +501,19 @@ int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **ret) {
         }
 
         for (i = 0; i < q->n_keys; i++) {
+                _cleanup_free_ char *key_str = NULL;
                 DnsCacheItem *j;
 
                 if (q->keys[i]->type == DNS_TYPE_ANY ||
                     q->keys[i]->class == DNS_CLASS_ANY) {
                         /* If we have ANY lookups we simply refresh */
+
+                        r = dns_resource_key_to_string(q->keys[i], &key_str);
+                        if (r < 0)
+                                return r;
+
+                        log_debug("Ignoring cache for ANY lookup: %s", key_str);
+
                         *ret = NULL;
                         *rcode = 0;
                         return 0;
@@ -481,9 +522,24 @@ int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **ret) {
                 j = hashmap_get(c->by_key, q->keys[i]);
                 if (!j) {
                         /* If one question cannot be answered we need to refresh */
+
+                        r = dns_resource_key_to_string(q->keys[i], &key_str);
+                        if (r < 0)
+                                return r;
+
+                        log_debug("Cache miss for %s", key_str);
+
                         *ret = NULL;
                         *rcode = 0;
                         return 0;
+                } else {
+                        r = dns_resource_key_to_string(j->key, &key_str);
+                        if (r < 0)
+                                return r;
+
+                        log_debug("%s cache hit for %s",
+                                   j->type == DNS_CACHE_POSITIVE ? "Positive" :
+                                                                  (j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN"), key_str);
                 }
 
                 LIST_FOREACH(by_key, j, j) {
index 39951a362c83e5fa2d3dc80a91fb8b5982e75764..35ad8995442bcfddd311f39136821599347259d1 100644 (file)
@@ -1712,7 +1712,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
                 if (r < 0)
                         goto fail;
 
-                r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
+                r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
                 if (r < 0)
                         goto fail;
 
index 418d9721ef54e33522cc9bd069b08244b0c6313b..3ada442006f927129f90ac2a45a4d8667b8552ae 100644 (file)
@@ -19,6 +19,8 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "hostname-util.h"
+#include "dns-domain.h"
 
 #include "resolved-dns-query.h"
 
@@ -212,6 +214,156 @@ static int dns_query_add_transaction_split(DnsQuery *q, DnsScope *s) {
         return 0;
 }
 
+static int SYNTHESIZE_IFINDEX(int ifindex) {
+
+        /* When the caller asked for resolving on a specific interface,
+         * we synthesize the answer for that interface. However, if
+         * nothing specific was claimed, we synthesize the answer for
+         * localhost. */
+
+        if (ifindex > 0)
+                return ifindex;
+
+        return LOOPBACK_IFINDEX;
+}
+
+static int SYNTHESIZE_FAMILY(uint64_t flags) {
+
+        /* Picks an address family depending on set flags. This is
+         * purely for synthesized answers, where the family we return
+         * for the reply should match what was requested in the
+         * question, even though we are synthesizing the answer
+         * here. */
+
+        if (!(flags & SD_RESOLVED_DNS)) {
+                if (flags & SD_RESOLVED_LLMNR_IPV4)
+                        return AF_INET;
+                if (flags & SD_RESOLVED_LLMNR_IPV6)
+                        return AF_INET6;
+        }
+
+        return AF_UNSPEC;
+}
+
+static DnsProtocol SYNTHESIZE_PROTOCOL(uint64_t flags) {
+
+        /* Similar as SYNTHESIZE_FAMILY() but does this for the
+         * protocol. If resolving via DNS was requested, we claim it
+         * was DNS. Similar, if nothing specific was
+         * requested. However, if only resolving via LLMNR was
+         * requested we return that. */
+
+        if (flags & SD_RESOLVED_DNS)
+                return DNS_PROTOCOL_DNS;
+        if (flags & SD_RESOLVED_LLMNR)
+                return DNS_PROTOCOL_LLMNR;
+
+        return DNS_PROTOCOL_DNS;
+}
+
+static void dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
+        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+        unsigned i;
+        int r;
+
+        assert(q);
+        assert(state);
+
+        /* Tries to synthesize localhost RR replies where appropriate */
+
+        if (!IN_SET(*state,
+                    DNS_TRANSACTION_FAILURE,
+                    DNS_TRANSACTION_NO_SERVERS,
+                    DNS_TRANSACTION_TIMEOUT,
+                    DNS_TRANSACTION_ATTEMPTS_MAX_REACHED))
+                return;
+
+        for (i = 0; i < q->question->n_keys; i++) {
+                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
+                const char *name;
+
+                if (q->question->keys[i]->class != DNS_CLASS_IN &&
+                    q->question->keys[i]->class != DNS_CLASS_ANY)
+                        continue;
+
+                name = DNS_RESOURCE_KEY_NAME(q->question->keys[i]);
+
+                if (is_localhost(name)) {
+
+                        switch (q->question->keys[i]->type) {
+
+                        case DNS_TYPE_A:
+                        case DNS_TYPE_ANY:
+                                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, name);
+                                if (!rr) {
+                                        log_oom();
+                                        return;
+                                }
+
+                                rr->a.in_addr.s_addr = htobe32(INADDR_LOOPBACK);
+                                break;
+
+                        case DNS_TYPE_AAAA:
+                                rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_AAAA, name);
+                                if (!rr) {
+                                        log_oom();
+                                        return;
+                                }
+
+                                rr->aaaa.in6_addr = in6addr_loopback;
+                                break;
+                        }
+
+                } else if (IN_SET(q->question->keys[i]->type, DNS_TYPE_PTR, DNS_TYPE_ANY) &&
+                           (dns_name_endswith(name, "127.in-addr.arpa") > 0 ||
+                            dns_name_equal(name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0)) {
+
+                        rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_PTR, name);
+                        if (!rr) {
+                                log_oom();
+                                return;
+                        }
+
+                        rr->ptr.name = strdup("localhost");
+                        if (!rr->ptr.name) {
+                                log_oom();
+                                return;
+                        }
+                }
+
+                if (!rr)
+                        continue;
+
+                if (!answer) {
+                        answer = dns_answer_new(q->question->n_keys);
+                        if (!answer) {
+                                log_oom();
+                                return;
+                        }
+                }
+
+                r = dns_answer_add(answer, rr);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to add synthetic RR to answer: %m");
+                        return;
+                }
+        }
+
+        if (!answer)
+                return;
+
+        dns_answer_unref(q->answer);
+        q->answer = answer;
+        answer = NULL;
+
+        q->answer_ifindex = SYNTHESIZE_IFINDEX(q->ifindex);
+        q->answer_family = SYNTHESIZE_FAMILY(q->flags);
+        q->answer_protocol = SYNTHESIZE_PROTOCOL(q->flags);
+        q->answer_rcode = DNS_RCODE_SUCCESS;
+
+        *state = DNS_TRANSACTION_SUCCESS;
+}
+
 int dns_query_go(DnsQuery *q) {
         DnsScopeMatch found = DNS_SCOPE_NO;
         DnsScope *s, *first = NULL;
@@ -253,8 +405,17 @@ int dns_query_go(DnsQuery *q) {
                 }
         }
 
-        if (found == DNS_SCOPE_NO)
+        if (found == DNS_SCOPE_NO) {
+                DnsTransactionState state = DNS_TRANSACTION_NO_SERVERS;
+
+                dns_query_synthesize_reply(q, &state);
+                if (state != DNS_TRANSACTION_NO_SERVERS) {
+                        dns_query_complete(q, state);
+                        return 1;
+                }
+
                 return -ESRCH;
+        }
 
         r = dns_query_add_transaction_split(q, first);
         if (r < 0)
@@ -428,6 +589,9 @@ void dns_query_ready(DnsQuery *q) {
                 q->answer_family = scope ? scope->family : AF_UNSPEC;
         }
 
+        /* Try to synthesize a reply if we couldn't resolve something. */
+        dns_query_synthesize_reply(q, &state);
+
         dns_query_complete(q, state);
 }
 
index b8414da87e07f445c0c97e7dc11ce628ddd31497..57d9071dfcf49549f4806aa2abdc96fbe5ecedef 100644 (file)
@@ -325,10 +325,6 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
         if ((SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family) & flags) == 0)
                 return DNS_SCOPE_NO;
 
-        STRV_FOREACH(i, s->domains)
-                if (dns_name_endswith(domain, *i) > 0)
-                        return DNS_SCOPE_YES;
-
         if (dns_name_root(domain) != 0)
                 return DNS_SCOPE_NO;
 
@@ -340,6 +336,10 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
             dns_name_equal(domain, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0)
                 return DNS_SCOPE_NO;
 
+        STRV_FOREACH(i, s->domains)
+                if (dns_name_endswith(domain, *i) > 0)
+                        return DNS_SCOPE_YES;
+
         if (s->protocol == DNS_PROTOCOL_DNS) {
                 if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
                     dns_name_endswith(domain, "0.8.e.f.ip6.arpa") == 0 &&
index 53779f33721c65d16e5aeaffff193cfa961cf631..2d9d1a47eea093b7100f2b3538fa872703ea75b9 100644 (file)
@@ -624,7 +624,6 @@ int dns_transaction_go(DnsTransaction *t) {
                 if (r < 0)
                         return r;
                 if (r > 0) {
-                        log_debug("Cache hit!");
                         if (t->cached_rcode == DNS_RCODE_SUCCESS)
                                 dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
                         else
@@ -661,8 +660,6 @@ int dns_transaction_go(DnsTransaction *t) {
                 return 0;
         }
 
-        log_debug("Cache miss!");
-
         /* Otherwise, we need to ask the network */
         r = dns_transaction_make_packet(t);
         if (r == -EDOM) {
index 5be01d3cb8a7ae079d56e3ad59476e0099d579e0..645f2a824cc79f04c75d5871d60c53563e62e36e 100644 (file)
@@ -176,8 +176,7 @@ static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, voi
                 break;
 
         case RTM_DELADDR:
-                if (a)
-                        link_address_free(a);
+                link_address_free(a);
                 break;
         }
 
index aa87cd0910239d5efbc186355db131fbf958be6e..0df0594ea3ec42c52285ed7893ea00a4696c17d9 100644 (file)
@@ -2027,37 +2027,3 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
         *ret_external = external;
         return 1;
 }
-
-bool is_kdbus_wanted(void) {
-        _cleanup_free_ char *value = NULL;
-#ifdef ENABLE_KDBUS
-        const bool configured = true;
-#else
-        const bool configured = false;
-#endif
-
-        int r;
-
-        if (get_proc_cmdline_key("kdbus", NULL) > 0)
-                return true;
-
-        r = get_proc_cmdline_key("kdbus=", &value);
-        if (r <= 0)
-                return configured;
-
-        return parse_boolean(value) == 1;
-}
-
-bool is_kdbus_available(void) {
-        _cleanup_close_ int fd = -1;
-        struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
-
-        if (!is_kdbus_wanted())
-                return false;
-
-        fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
-        if (fd < 0)
-                return false;
-
-        return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
-}
index 4ae216b7d9c400cab586d4e18fccb0a23260d3a3..0c683c071301281c225c32b8bf07f90da0452784 100644 (file)
 
 #include "sd-event.h"
 #include "sd-bus.h"
+#include "bus-error.h"
+#include "bus-internal.h"
 #include "hashmap.h"
 #include "install.h"
 #include "time-util.h"
 
-typedef enum BusTransport {
-        BUS_TRANSPORT_LOCAL,
-        BUS_TRANSPORT_REMOTE,
-        BUS_TRANSPORT_MACHINE,
-        _BUS_TRANSPORT_MAX,
-        _BUS_TRANSPORT_INVALID = -1
-} BusTransport;
-
 typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
 
 struct bus_properties_map {
@@ -135,21 +129,6 @@ typedef struct UnitInfo {
 
 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_flush_close_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref);
-
-#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp)
-#define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp)
-#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp)
-#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp)
-#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp)
-#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp)
-#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free)
-
 #define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type)              \
         int function(sd_bus *bus,                                       \
                      const char *path,                                  \
@@ -197,6 +176,3 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un
 
 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
-
-bool is_kdbus_wanted(void);
-bool is_kdbus_available(void);
index 24871b0daedb2b3491e78aaff0f42803ad1a79cc..f58e84a3d0daf62d5e8334c39b8bbdda8fc05d3d 100644 (file)
@@ -101,7 +101,7 @@ static int condition_test_kernel_command_line(Condition *c) {
                 _cleanup_free_ char *word = NULL;
                 bool found;
 
-                r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
                 if (r < 0)
                         return r;
                 if (r == 0)
index 4e850ea1cfa1078e7e5dc4edb020806e8c377a7d..1a9dbadbe143c8c3a07e202b1f40014d5787e395 100644 (file)
@@ -7292,6 +7292,7 @@ static int halt_now(enum action a) {
                 reboot(RB_POWER_OFF);
                 return -errno;
 
+        case ACTION_KEXEC:
         case ACTION_REBOOT: {
                 _cleanup_free_ char *param = NULL;
 
index 3a92d120d26d65b1b9b88be79282fb2ba39caf45..b5e09cad26d91e460baa80ee70644c55d17ad5b0 100644 (file)
@@ -1380,7 +1380,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
 
         /* Parse columns */
         p = buffer;
-        r = unquote_many_words(&p, 0, &action, &name, &id, &description, &home, NULL);
+        r = extract_many_words(&p, NULL, EXTRACT_QUOTES, &action, &name, &id, &description, &home, NULL);
         if (r < 0) {
                 log_error("[%s:%u] Syntax error.", fname, line);
                 return r;
@@ -1389,7 +1389,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
                 log_error("[%s:%u] Missing action and name columns.", fname, line);
                 return -EINVAL;
         }
-        if (*p != 0) {
+        if (!isempty(p)) {
                 log_error("[%s:%u] Trailing garbage.", fname, line);
                 return -EINVAL;
         }
index 6e3c81395c81189312a52e60beebdb54e1e308b4..bff43950a9077cd602eb6b29f48f3c05d60343ea 100644 (file)
@@ -165,7 +165,7 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         assert_se(p);
         assert_se(streq(p, quoted));
 
-        r = strv_split_quoted(&s, quoted, 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
         assert_se(r == 0);
         assert_se(s);
         STRV_FOREACH(t, s) {
@@ -182,7 +182,7 @@ static void test_strv_unquote(const char *quoted, char **list) {
         char **t;
         int r;
 
-        r = strv_split_quoted(&s, quoted, 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
         assert_se(r == 0);
         assert_se(s);
         j = strv_join(s, " | ");
@@ -199,7 +199,7 @@ static void test_invalid_unquote(const char *quoted) {
         char **s = NULL;
         int r;
 
-        r = strv_split_quoted(&s, quoted, 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
         assert_se(s == NULL);
         assert_se(r == -EINVAL);
 }
@@ -219,6 +219,21 @@ static void test_strv_split(void) {
         }
 }
 
+static void test_strv_split_extract(void) {
+        _cleanup_strv_free_ char **l = NULL;
+        const char *str = ":foo\\:bar::waldo:";
+        int r;
+
+        r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+        assert_se(r == 0);
+        assert_se(streq_ptr(l[0], ""));
+        assert_se(streq_ptr(l[1], "foo:bar"));
+        assert_se(streq_ptr(l[2], ""));
+        assert_se(streq_ptr(l[3], "waldo"));
+        assert_se(streq_ptr(l[4], ""));
+        assert_se(streq_ptr(l[5], NULL));
+}
+
 static void test_strv_split_newlines(void) {
         unsigned i = 0;
         char **s;
@@ -542,6 +557,18 @@ static void test_strv_reverse(void) {
         assert_se(streq_ptr(d[3], NULL));
 }
 
+static void test_strv_shell_escape(void) {
+        _cleanup_strv_free_ char **v = NULL;
+
+        v = strv_new("foo:bar", "bar,baz", "wal\\do", NULL);
+        assert_se(v);
+        assert_se(strv_shell_escape(v, ",:"));
+        assert_se(streq_ptr(v[0], "foo\\:bar"));
+        assert_se(streq_ptr(v[1], "bar\\,baz"));
+        assert_se(streq_ptr(v[2], "wal\\\\do"));
+        assert_se(streq_ptr(v[3], NULL));
+}
+
 int main(int argc, char *argv[]) {
         test_specifier_printf();
         test_strv_foreach();
@@ -583,6 +610,7 @@ int main(int argc, char *argv[]) {
         test_invalid_unquote("'x'y'g");
 
         test_strv_split();
+        test_strv_split_extract();
         test_strv_split_newlines();
         test_strv_split_nulstr();
         test_strv_parse_nulstr();
@@ -598,6 +626,7 @@ int main(int argc, char *argv[]) {
         test_strv_equal();
         test_strv_is_uniq();
         test_strv_reverse();
+        test_strv_shell_escape();
 
         return 0;
 }
index 03e18df0802cf8a612ff376a7998269e6fc99818..3c1bac4606b1c2076badc8c077340e24c4485521 100644 (file)
@@ -1487,350 +1487,448 @@ static void test_execute_directory(void) {
         (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
 }
 
-static void test_unquote_first_word(void) {
+static void test_extract_first_word(void) {
         const char *p, *original;
         char *t;
 
         p = original = "foobar waldo";
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
         assert_se(streq(t, "foobar"));
         free(t);
         assert_se(p == original + 7);
 
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
         assert_se(streq(t, "waldo"));
         free(t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
-        assert_se(unquote_first_word(&p, &t, 0) == 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
         assert_se(!t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
         p = original = "\"foobar\" \'waldo\'";
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
+        assert_se(streq(t, "\"foobar\""));
+        free(t);
+        assert_se(p == original + 9);
+
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
+        assert_se(streq(t, "\'waldo\'"));
+        free(t);
+        assert_se(isempty(p));
+
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
+        assert_se(!t);
+        assert_se(isempty(p));
+
+        p = original = "\"foobar\" \'waldo\'";
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
         assert_se(streq(t, "foobar"));
         free(t);
         assert_se(p == original + 9);
 
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
         assert_se(streq(t, "waldo"));
         free(t);
-        assert_se(p == original + 16);
+        assert_se(isempty(p));
 
-        assert_se(unquote_first_word(&p, &t, 0) == 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
         assert_se(!t);
-        assert_se(p == original + 16);
+        assert_se(isempty(p));
 
         p = original = "\"";
-        assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
+        assert_se(streq(t, "\""));
+        assert_se(isempty(p));
+
+        p = original = "\"";
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
         assert_se(p == original + 1);
 
         p = original = "\'";
-        assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
+        assert_se(streq(t, "\'"));
+        assert_se(isempty(p));
+
+        p = original = "\'";
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
         assert_se(p == original + 1);
 
         p = original = "\'fooo";
-        assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
+        assert_se(streq(t, "\'fooo"));
+        assert_se(isempty(p));
+
+        p = original = "\'fooo";
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\'fooo";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
         assert_se(streq(t, "fooo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "yay\'foo\'bar";
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
+        assert_se(streq(t, "yay\'foo\'bar"));
+        free(t);
+        assert_se(isempty(p));
+
+        p = original = "yay\'foo\'bar";
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
         assert_se(streq(t, "yayfoobar"));
         free(t);
-        assert_se(p == original + 11);
+        assert_se(isempty(p));
 
         p = original = "   foobar   ";
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
         assert_se(streq(t, "foobar"));
         free(t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
         p = original = " foo\\ba\\x6ar ";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
         assert_se(streq(t, "foo\ba\x6ar"));
         free(t);
-        assert_se(p == original + 13);
+        assert_se(isempty(p));
 
         p = original = " foo\\ba\\x6ar ";
-        assert_se(unquote_first_word(&p, &t, 0) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
         assert_se(streq(t, "foobax6ar"));
         free(t);
-        assert_se(p == original + 13);
+        assert_se(isempty(p));
 
         p = original = "    f\\u00f6o \"pi\\U0001F4A9le\"   ";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
         assert_se(streq(t, "föo"));
         free(t);
         assert_se(p == original + 13);
 
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
         assert_se(streq(t, "pi\360\237\222\251le"));
         free(t);
-        assert_se(p == original + 32);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
         assert_se(streq(t, "fooo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "fooo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
         assert_se(streq(t, "fooo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "fooo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word(&p, &t, 0) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
+        assert_se(streq(t, "foo"));
+        free(t);
+        assert_se(isempty(p));
+
+        p = original = "foo::bar";
+        assert_se(extract_first_word(&p, &t, ":", 0) == 1);
         assert_se(streq(t, "foo"));
         free(t);
         assert_se(p == original + 5);
 
+        assert_se(extract_first_word(&p, &t, ":", 0) == 1);
+        assert_se(streq(t, "bar"));
+        free(t);
+        assert_se(isempty(p));
+
+        assert_se(extract_first_word(&p, &t, ":", 0) == 0);
+        assert_se(!t);
+        assert_se(isempty(p));
+
+        p = original = "foo\\:bar::waldo";
+        assert_se(extract_first_word(&p, &t, ":", 0) == 1);
+        assert_se(streq(t, "foo:bar"));
+        free(t);
+        assert_se(p == original + 10);
+
+        assert_se(extract_first_word(&p, &t, ":", 0) == 1);
+        assert_se(streq(t, "waldo"));
+        free(t);
+        assert_se(isempty(p));
+
+        assert_se(extract_first_word(&p, &t, ":", 0) == 0);
+        assert_se(!t);
+        assert_se(isempty(p));
+
         p = original = "\"foo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
         assert_se(streq(t, "foo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
         assert_se(streq(t, "foo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
         assert_se(streq(t, "fooo bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "fooo bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE_RELAX|UNQUOTE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
         assert_se(streq(t, "fooo bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "fooo\\ bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "\\w+@\\K[\\d.]+";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) == -EINVAL);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
         assert_se(p == original + 1);
 
         p = original = "\\w+@\\K[\\d.]+";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "\\w+@\\K[\\d.]+"));
         free(t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
         p = original = "\\w+\\b";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_CUNESCAPE_RELAX) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
         assert_se(streq(t, "\\w+\b"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "-N ''";
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
         assert_se(streq(t, "-N"));
         free(t);
         assert_se(p == original + 3);
 
-        assert_se(unquote_first_word(&p, &t, UNQUOTE_CUNESCAPE) > 0);
+        assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
         assert_se(streq(t, ""));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
+
+        p = original = ":foo\\:bar::waldo:";
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+        assert_se(t);
+        assert_se(streq(t, ""));
+        free(t);
+        assert_se(p == original + 1);
+
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+        assert_se(streq(t, "foo:bar"));
+        free(t);
+        assert_se(p == original + 10);
+
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+        assert_se(t);
+        assert_se(streq(t, ""));
+        free(t);
+        assert_se(p == original + 11);
+
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+        assert_se(streq(t, "waldo"));
+        free(t);
+        assert_se(p == original + 17);
+
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
+        assert_se(streq(t, ""));
+        free(t);
+        assert_se(p == NULL);
+
+        assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
+        assert_se(!t);
+        assert_se(!p);
 }
 
-static void test_unquote_first_word_and_warn(void) {
+static void test_extract_first_word_and_warn(void) {
         const char *p, *original;
         char *t;
 
         p = original = "foobar waldo";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foobar"));
         free(t);
         assert_se(p == original + 7);
 
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "waldo"));
         free(t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
         assert_se(!t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
         p = original = "\"foobar\" \'waldo\'";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foobar"));
         free(t);
         assert_se(p == original + 9);
 
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "waldo"));
         free(t);
-        assert_se(p == original + 16);
+        assert_se(isempty(p));
 
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
         assert_se(!t);
-        assert_se(p == original + 16);
+        assert_se(isempty(p));
 
         p = original = "\"";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
         assert_se(p == original + 1);
 
         p = original = "\'";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
         assert_se(p == original + 1);
 
         p = original = "\'fooo";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\'fooo";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = " foo\\ba\\x6ar ";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foo\ba\x6ar"));
         free(t);
-        assert_se(p == original + 13);
+        assert_se(isempty(p));
 
         p = original = " foo\\ba\\x6ar ";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foobax6ar"));
         free(t);
-        assert_se(p == original + 13);
+        assert_se(isempty(p));
 
         p = original = "    f\\u00f6o \"pi\\U0001F4A9le\"   ";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "föo"));
         free(t);
         assert_se(p == original + 13);
 
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "pi\360\237\222\251le"));
         free(t);
-        assert_se(p == original + 32);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo\\"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) == -EINVAL);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
         assert_se(p == original + 5);
 
         p = original = "\"foo\\";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE|UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "foo"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_RELAX, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word_and_warn(&p, &t, 0, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "fooo\\ bar quux";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "fooo\\ bar"));
         free(t);
         assert_se(p == original + 10);
 
         p = original = "\\w+@\\K[\\d.]+";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "\\w+@\\K[\\d.]+"));
         free(t);
-        assert_se(p == original + 12);
+        assert_se(isempty(p));
 
         p = original = "\\w+\\b";
-        assert_se(unquote_first_word_and_warn(&p, &t, UNQUOTE_CUNESCAPE, NULL, "fake", 1, original) > 0);
+        assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
         assert_se(streq(t, "\\w+\b"));
         free(t);
-        assert_se(p == original + 5);
+        assert_se(isempty(p));
 }
 
-static void test_unquote_many_words(void) {
+static void test_extract_many_words(void) {
         const char *p, *original;
         char *a, *b, *c;
 
         p = original = "foobar waldi piep";
-        assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 3);
-        assert_se(p == original + 17);
+        assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
+        assert_se(isempty(p));
         assert_se(streq_ptr(a, "foobar"));
         assert_se(streq_ptr(b, "waldi"));
         assert_se(streq_ptr(c, "piep"));
@@ -1839,8 +1937,17 @@ static void test_unquote_many_words(void) {
         free(c);
 
         p = original = "'foobar' wa\"ld\"i   ";
-        assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 2);
-        assert_se(p == original + 19);
+        assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
+        assert_se(isempty(p));
+        assert_se(streq_ptr(a, "'foobar'"));
+        assert_se(streq_ptr(b, "wa\"ld\"i"));
+        assert_se(streq_ptr(c, NULL));
+        free(a);
+        free(b);
+
+        p = original = "'foobar' wa\"ld\"i   ";
+        assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
+        assert_se(isempty(p));
         assert_se(streq_ptr(a, "foobar"));
         assert_se(streq_ptr(b, "waldi"));
         assert_se(streq_ptr(c, NULL));
@@ -1848,32 +1955,32 @@ static void test_unquote_many_words(void) {
         free(b);
 
         p = original = "";
-        assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
-        assert_se(p == original);
+        assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
+        assert_se(isempty(p));
         assert_se(streq_ptr(a, NULL));
         assert_se(streq_ptr(b, NULL));
         assert_se(streq_ptr(c, NULL));
 
         p = original = "  ";
-        assert_se(unquote_many_words(&p, 0, &a, &b, &c, NULL) == 0);
-        assert_se(p == original+2);
+        assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
+        assert_se(isempty(p));
         assert_se(streq_ptr(a, NULL));
         assert_se(streq_ptr(b, NULL));
         assert_se(streq_ptr(c, NULL));
 
         p = original = "foobar";
-        assert_se(unquote_many_words(&p, 0, NULL) == 0);
+        assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
         assert_se(p == original);
 
         p = original = "foobar waldi";
-        assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
+        assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
         assert_se(p == original+7);
         assert_se(streq_ptr(a, "foobar"));
         free(a);
 
         p = original = "     foobar    ";
-        assert_se(unquote_many_words(&p, 0, &a, NULL) == 1);
-        assert_se(p == original+15);
+        assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
+        assert_se(isempty(p));
         assert_se(streq_ptr(a, "foobar"));
         free(a);
 }
@@ -1993,6 +2100,21 @@ static void test_sparse_write(void) {
         test_sparse_write_one(fd, test_e, sizeof(test_e));
 }
 
+static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
+        _cleanup_free_ char *r;
+
+        assert_se(r = shell_escape(s, bad));
+        assert_se(streq_ptr(r, expected));
+}
+
+static void test_shell_escape(void) {
+        test_shell_escape_one("", "", "");
+        test_shell_escape_one("\\", "", "\\\\");
+        test_shell_escape_one("foobar", "", "foobar");
+        test_shell_escape_one("foobar", "o", "f\\o\\obar");
+        test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
+}
+
 static void test_shell_maybe_quote_one(const char *s, const char *expected) {
         _cleanup_free_ char *r;
 
@@ -2149,14 +2271,15 @@ int main(int argc, char *argv[]) {
         test_search_and_fopen_nulstr();
         test_glob_exists();
         test_execute_directory();
-        test_unquote_first_word();
-        test_unquote_first_word_and_warn();
-        test_unquote_many_words();
+        test_extract_first_word();
+        test_extract_first_word_and_warn();
+        test_extract_many_words();
         test_parse_proc_cmdline();
         test_raw_clone();
         test_same_fd();
         test_uid_ptr();
         test_sparse_write();
+        test_shell_escape();
         test_shell_maybe_quote();
         test_parse_mode();
         test_tempfn();
index d6f78015615c22907c5a25ee4fa508cd5de477d2..8f29256c6da9175983b1d3a4487a278a3104838e 100644 (file)
@@ -662,7 +662,7 @@ static int parse_xattrs_from_arg(Item *i) {
         for (;;) {
                 _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL, *xattr_replaced = NULL;
 
-                r = unquote_first_word(&p, &xattr, UNQUOTE_CUNESCAPE);
+                r = extract_first_word(&p, &xattr, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
                 if (r < 0)
                         log_warning_errno(r, "Failed to parse extended attribute '%s', ignoring: %m", p);
                 if (r <= 0)
@@ -1760,9 +1760,10 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         assert(line >= 1);
         assert(buffer);
 
-        r = unquote_many_words(
+        r = extract_many_words(
                         &buffer,
-                        0,
+                        NULL,
+                        EXTRACT_QUOTES,
                         &action,
                         &path,
                         &mode,
index 1dad4476f33de248f408b01620a8dc03bfa2f399..b8066ea6e9c40fef5be6987a2fbd3c9be657b7f0 100644 (file)
@@ -143,6 +143,11 @@ static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
 
                 if (sd_id128_equal(type, GPT_ESP)) {
                         sd_id128_t id, esp;
+                        unsigned long long flags;
+
+                        flags = blkid_partition_get_flags(pp);
+                        if (flags & GPT_FLAG_NO_AUTO)
+                                continue;
 
                         /* We found an ESP, let's see if it matches
                          * the ESP we booted from. */
index aa5cda6fe77fc85a53e5e1e9320fe97a0cd33dda..f529ffcf256d8688479c924d9dc5f247aa64fa34 100644 (file)
@@ -117,8 +117,7 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
 
         format_lun_number(parent, &lun);
         path_prepend(path, "fc-%s-%s", port, lun);
-        if (lun)
-                free(lun);
+        free(lun);
 out:
         udev_device_unref(fcdev);
         return parent;
@@ -156,8 +155,7 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent,
 
         format_lun_number(parent, &lun);
         path_prepend(path, "sas-%s-%s", sas_address, lun);
-        if (lun)
-                free(lun);
+        free(lun);
 out:
         udev_device_unref(sasdev);
         return parent;
@@ -251,8 +249,7 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa
         else
                  path_prepend(path, "sas-phy%s-%s", phy_id, lun);
 
-        if (lun)
-                free(lun);
+        free(lun);
 out:
         udev_device_unref(target_sasdev);
         udev_device_unref(expander_sasdev);
@@ -313,8 +310,7 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
 
         format_lun_number(parent, &lun);
         path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun);
-        if (lun)
-                free(lun);
+        free(lun);
 out:
         udev_device_unref(sessiondev);
         udev_device_unref(conndev);
index b0ad277f735c9dba5f5e590fdd7b50b567cfbfef..b4ae0944eb61cf77c0f37e9edc436ed646f54808 100644 (file)
@@ -379,13 +379,14 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
         cmsg_close_all(&smsg);
 
         cmsg = CMSG_FIRSTHDR(&smsg);
-        cred = (struct ucred *) CMSG_DATA(cmsg);
 
         if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
                 log_error("no sender credentials received, message ignored");
                 goto err;
         }
 
+        cred = (struct ucred *) CMSG_DATA(cmsg);
+
         if (cred->uid != 0) {
                 log_error("sender uid="UID_FMT", message ignored", cred->uid);
                 goto err;
index ea9b0c9c8436054f2b1e7e2ab1da5814f3a3e854..61bcf02b2f27a734af77f9c39eb23cc61abc77d6 100644 (file)
@@ -286,8 +286,6 @@ finish:
                 audit_close(c.audit_fd);
 #endif
 
-        if (c.bus)
-                sd_bus_unref(c.bus);
-
+        sd_bus_unref(c.bus);
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }