]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #15495 from keszybz/resolve-debugging-and-stub-handling
authorLennart Poettering <lennart@poettering.net>
Tue, 21 Apr 2020 07:34:21 +0000 (09:34 +0200)
committerGitHub <noreply@github.com>
Tue, 21 Apr 2020 07:34:21 +0000 (09:34 +0200)
Resolve debugging and stub handling

18 files changed:
man/custom-html.xsl
man/resolvectl.xml
man/rules/meson.build
man/sd-bus.xml
man/sd_bus_get_current_handler.xml
man/sd_bus_get_fd.xml
man/sd_bus_set_close_on_exit.xml
man/sd_bus_set_description.xml
man/sd_bus_set_exit_on_disconnect.xml [new file with mode: 0644]
man/sd_bus_set_server.xml
src/libsystemd-network/sd-dhcp-lease.c
src/libsystemd-network/sd-dhcp-server.c
src/network/networkd-dhcp-server.c
src/network/networkd-util.c
src/network/networkd-util.h
src/resolve/resolved-dns-scope.c
src/systemd/sd-dhcp-lease.h
src/systemd/sd-dhcp-server.h

index fccaf51ff5e446341808cdb289033e89f3da968a..7eebfdb5a142673ab433dfb338e346a3fc2220b6 100644 (file)
@@ -1,9 +1,5 @@
 <?xml version='1.0'?> <!--*-nxml-*-->
-
-<!--
-  SPDX-License-Identifier: LGPL-2.1+
-
--->
+<!-- SPDX-License-Identifier: LGPL-2.1+ -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 
   </a>
 </xsl:template>
 
+<xsl:template match="citerefentry[@project='debian']">
+  <a>
+    <xsl:attribute name="href">
+      <xsl:text>https://manpages.debian.org/unstable/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>/</xsl:text>
+      <xsl:value-of select="refentrytitle"/>
+      <xsl:text>.</xsl:text>
+      <xsl:value-of select="manvolnum"/>
+      <xsl:text>.en.html</xsl:text>
+    </xsl:attribute>
+    <xsl:call-template name="inline.charseq"/>
+  </a>
+</xsl:template>
+
 <xsl:template match="citerefentry[@project='freebsd']">
   <a>
     <xsl:attribute name="href">
index 75be5fe072677967ae91d2b22c3035f242d747c6..cc049945941d3ae9b5a2789758d6d1d12e27ca49 100644 (file)
   </refsect1>
 
   <refsect1>
-    <title>Compatibility with <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry></title>
+    <title>Compatibility with
+    <citerefentry project="debian"><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry></title>
 
     <para><command>resolvectl</command> is a multi-call binary. When invoked as <literal>resolvconf</literal>
     (generally achieved by means of a symbolic link of this name to the <command>resolvectl</command> binary) it
-    is run in a limited <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    is run in a limited
+    <citerefentry project="debian"><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     compatibility mode. It accepts mostly the same arguments and pushes all data into
     <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
     similar to how <option>dns</option> and <option>domain</option> commands operate. Note that
     <command>systemd-resolved.service</command> is the only supported backend, which is different from other
-    implementations of this command. Note that not all operations supported by other implementations are supported
-    natively. Specifically:</para>
+    implementations of this command.</para>
+
+    <para><filename>/etc/resolv.conf</filename> will only be updated with servers added with this command
+    when <filename>/etc/resolv.conf</filename> is a symlink to
+    <filename>/run/systemd/resolve/resolv.conf</filename>, and not a static file. See the discussion of
+    <filename>/etc/resolv.conf</filename> handling in
+    <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+    </para>
+
+    <para>Not all operations supported by other implementations are supported natively. Specifically:</para>
 
     <variablelist>
       <varlistentry>
 
     </variablelist>
 
-    <para>See <citerefentry><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry> for details on this command line options.</para>
+    <para>See
+    <citerefentry project="debian"><refentrytitle>resolvconf</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    for details on those command line options.</para>
   </refsect1>
 
   <refsect1>
index 772ac1dc248604f48c6aa28aaf06f9d43289abf5..7b5b13b17682a3e8860cbba6ecd67d25fecfac46 100644 (file)
@@ -379,12 +379,16 @@ manpages = [
   '3',
   ['sd_bus_get_allow_interactive_authorization',
    'sd_bus_get_description',
+   'sd_bus_get_scope',
+   'sd_bus_get_tid',
+   'sd_bus_get_unique_name',
    'sd_bus_is_anonymous',
    'sd_bus_is_trusted',
    'sd_bus_set_allow_interactive_authorization',
    'sd_bus_set_anonymous',
    'sd_bus_set_trusted'],
   ''],
+ ['sd_bus_set_exit_on_disconnect', '3', ['sd_bus_get_exit_on_disconnect'], ''],
  ['sd_bus_set_method_call_timeout',
   '3',
   ['sd_bus_get_method_call_timeout'],
@@ -398,7 +402,13 @@ manpages = [
    'sd_bus_set_propertyv'],
   ''],
  ['sd_bus_set_sender', '3', ['sd_bus_get_sender'], ''],
- ['sd_bus_set_server', '3', ['sd_bus_get_bus_id'], ''],
+ ['sd_bus_set_server',
+  '3',
+  ['sd_bus_get_bus_id',
+   'sd_bus_is_bus_client',
+   'sd_bus_is_server',
+   'sd_bus_set_bus_client'],
+  ''],
  ['sd_bus_set_watch_bind', '3', ['sd_bus_get_watch_bind'], ''],
  ['sd_bus_slot_get_bus',
   '3',
index f47e78cd6824ee59f0ba4fcd6205b0bef5d4fb7e..9918e0c737b537f2c6617d0975f80796a3ac31bd 100644 (file)
 <citerefentry><refentrytitle>sd_bus_get_current_message</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_get_current_slot</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_get_current_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_get_exit_on_disconnect</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_get_n_queued_read</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_get_scope</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_get_tid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_get_unique_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_is_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_is_server</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_message_append_array</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_message_append_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_request_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_address</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_set_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_connected_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>sd_bus_set_exit_on_disconnect</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_property</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_propertyv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_server</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_set_watch_bind</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-<citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_slot_get_current_handler</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_slot_get_current_message</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>sd_bus_slot_get_current_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
index 496116d5cbca74d038df9d3f580cbdb2c8e972ae..07c61cd416405a421ffc4c8cac6e4896c06308c4 100644 (file)
 
     <para>Whenever sd-bus is about to invoke a user-supplied callback function, it stores the
     current callback, D-Bus message, slot and userdata pointer and allows these to be queried via
-    these <function>sd_bus_get_current_handler()</function>,
+    <function>sd_bus_get_current_handler()</function>,
     <function>sd_bus_get_current_message()</function>,
     <function>sd_bus_get_current_slot()</function> and
     <function>sd_bus_get_current_userdata()</function>, respectively. If <parameter>bus</parameter>
     cannot be resolved or if execution does not reside in a user-supplied callback of
-    <parameter>bus</parameter> when calling any of these functions, they return
-    <constant>NULL</constant>.</para>
+    <parameter>bus</parameter>, these functions return <constant>NULL</constant>.</para>
   </refsect1>
 
   <refsect1>
index 213d13901991b7bf3249cee7e9b43f6d60a33b43..d9586f9003e27a7c26c5ea0dcc1b23792eede1a8 100644 (file)
@@ -26,7 +26,8 @@
     <refname>sd_bus_get_events</refname>
     <refname>sd_bus_get_timeout</refname>
 
-    <refpurpose>Get the file descriptor, I/O events and time-out to wait for from a message bus object</refpurpose>
+    <refpurpose>Get the file descriptor, I/O events and time-out to wait for from a message bus
+    object</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
   <refsect1>
     <title>Description</title>
 
-    <para><function>sd_bus_get_fd()</function> returns the file descriptor used to communicate from a message bus
-    object. This descriptor can be used with <citerefentry
-    project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry> or a similar
-    function to wait for I/O events on the specified bus connection object. If the bus object was configured with the
-    <function>sd_bus_set_fd()</function> function, then the <parameter>input_fd</parameter> file descriptor used in
-    that call is returned.</para>
-
-    <para><function>sd_bus_set_fd()</function> sets the file descriptors used to communicate from a message bus
-    object. Both <parameter>input_fd</parameter> and <parameter>output_fd</parameter> must be valid file descriptors.
-    The same file descriptor may be used as both the input and the output file descriptor. This function must be called
-    before the bus is started.</para>
-
-    <para><function>sd_bus_get_events()</function> returns the I/O events to wait for, suitable for passing to
-    <function>poll()</function> or a similar call. Returns a combination of <constant>POLLIN</constant>,
-    <constant>POLLOUT</constant>, … events, or negative on error.</para>
+    <para><function>sd_bus_get_fd()</function> returns the file descriptor used to communicate from
+    a message bus object. This descriptor can be used with
+    <citerefentry project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    or a similar function to wait for I/O events on the specified bus connection object. If the bus
+    object was configured with the <function>sd_bus_set_fd()</function> function, then the
+    <parameter>input_fd</parameter> file descriptor used in that call is returned.</para>
+
+    <para><function>sd_bus_set_fd()</function> sets the file descriptors used to communicate from a
+    message bus object. Both <parameter>input_fd</parameter> and <parameter>output_fd</parameter>
+    must be valid file descriptors. The same file descriptor may be used as both the input and the
+    output file descriptor. This function must be called before the bus is started.</para>
+
+    <para><function>sd_bus_get_events()</function> returns the I/O events to wait for, suitable for
+    passing to <function>poll()</function> or a similar call. Returns a combination of
+    <constant>POLLIN</constant>, <constant>POLLOUT</constant>, … events, or negative on error.
+    </para>
 
     <para><function>sd_bus_get_timeout()</function> returns the time-out in µs to pass to to
-    <function>poll()</function> or a similar call when waiting for events on the specified bus connection. The returned
-    time-out may be zero, in which case a subsequent I/O polling call should be invoked in non-blocking mode. The
-    returned timeout may be <constant>UINT64_MAX</constant> in which case the I/O polling call may block indefinitely,
-    without any applied time-out. Note that the returned time-out should be considered only a maximum sleeping time. It
-    is permissible (and even expected) that shorter time-outs are used by the calling program, in case other event
-    sources are polled in the same event loop. Note that the returned time-value is relative and specified in
-    microseconds. When converting this value in order to pass it as third argument to <function>poll()</function>
-    (which expects milliseconds), care should be taken to use a division that rounds up to ensure the I/O polling
-    operation doesn't sleep for shorter than necessary, which might result in unintended busy looping (alternatively,
-    use <citerefentry project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    instead of plain <function>poll()</function>, which understands time-outs with nano-second granularity).</para>
-
-    <para>These three functions are useful to hook up a bus connection object with an external or manual event loop
-    involving <function>poll()</function> or a similar I/O polling call. Before each invocation of the I/O polling
-    call, all three functions should be invoked: the file descriptor returned by <function>sd_bus_get_fd()</function>
-    should be polled for the events indicated by <function>sd_bus_get_events()</function>, and the I/O call should
-    block for that up to the time-out returned by <function>sd_bus_get_timeout()</function>. After each I/O polling
+    <function>poll()</function> or a similar call when waiting for events on the specified bus
+    connection. The returned time-out may be zero, in which case a subsequent I/O polling call
+    should be invoked in non-blocking mode. The returned timeout may be
+    <constant>UINT64_MAX</constant> in which case the I/O polling call may block indefinitely,
+    without any applied time-out. Note that the returned time-out should be considered only a
+    maximum sleeping time. It is permissible (and even expected) that shorter time-outs are used by
+    the calling program, in case other event sources are polled in the same event loop. Note that
+    the returned time-value is relative and specified in microseconds. When converting this value in
+    order to pass it as third argument to <function>poll()</function> (which expects milliseconds),
+    care should be taken to use a division that rounds up to ensure the I/O polling operation
+    doesn't sleep for shorter than necessary, which might result in unintended busy looping
+    (alternatively, use
+    <citerefentry project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    instead of plain <function>poll()</function>, which understands time-outs with nano-second
+    granularity).</para>
+
+    <para>These three functions are useful to hook up a bus connection object with an external or
+    manual event loop involving <function>poll()</function> or a similar I/O polling call. Before
+    each invocation of the I/O polling call, all three functions should be invoked: the file
+    descriptor returned by <function>sd_bus_get_fd()</function> should be polled for the events
+    indicated by <function>sd_bus_get_events()</function>, and the I/O call should block for that up
+    to the time-out returned by <function>sd_bus_get_timeout()</function>. After each I/O polling
     call the bus connection needs to process incoming or outgoing data, by invoking
-    <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+    <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+    </para>
 
-    <para>Note that these function are only one of three supported ways to implement I/O event handling for bus
-    connections. Alternatively use
-    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry> to attach a
-    bus connection to an <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    event loop. Or use <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    <para>Note that these functions are only one of three supported ways to implement I/O event
+    handling for bus connections. Alternatively use
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    to attach a bus connection to an
+    <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    event loop. Or use
+    <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     as a simple synchronous, blocking I/O waiting call.</para>
   </refsect1>
 
   <refsect1>
     <title>Return Value</title>
 
-    <para>On success, <function>sd_bus_get_fd()</function> returns the file descriptor used for communication. On failure,
-    it returns a negative errno-style error code.</para>
+    <para>On success, <function>sd_bus_get_fd()</function> returns the file descriptor used for
+    communication. On failure, it returns a negative errno-style error code.</para>
 
-    <para>On success, <function>sd_bus_set_fd()</function> returns a non-negative integer. On failure, it returns a
-    negative errno-style error code.</para>
+    <para>On success, <function>sd_bus_set_fd()</function> returns a non-negative integer. On
+    failure, it returns a negative errno-style error code.</para>
 
-    <para>On success, <function>sd_bus_get_events()</function> returns the I/O event mask to use for I/O event watching.
-    On failure, it returns a negative errno-style error code.</para>
+    <para>On success, <function>sd_bus_get_events()</function> returns the I/O event mask to use for
+    I/O event watching. On failure, it returns a negative errno-style error code.</para>
 
-    <para>On success, <function>sd_bus_get_timeout()</function> returns a non-negative integer. On failure, it returns a
-    negative errno-style error code.</para>
+    <para>On success, <function>sd_bus_get_timeout()</function> returns a non-negative integer. On
+    failure, it returns a negative errno-style error code.</para>
 
     <refsect2>
       <title>Errors</title>
         <varlistentry>
           <term><constant>-ECHILD</constant></term>
 
-          <listitem><para>The bus connection was allocated in a parent process and is being reused in a child
-          process after <function>fork()</function>.</para></listitem>
+          <listitem><para>The bus connection was allocated in a parent process and is being reused
+          in a child process after <function>fork()</function>.</para></listitem>
         </varlistentry>
 
         <varlistentry>
         <varlistentry>
           <term><constant>-EBADF</constant></term>
 
-          <listitem><para>An invalid file descriptor was passed to <function>sd_bus_set_fd()</function>.
-          </para></listitem>
+          <listitem><para>An invalid file descriptor was passed to
+          <function>sd_bus_set_fd()</function>.</para></listitem>
         </varlistentry>
 
         <varlistentry>
index 751fc0a729e672e23a6cf9726b06f641f8472ec3..64ca35644398cd21e507e30420140e7286964452 100644 (file)
@@ -20,7 +20,8 @@
     <refname>sd_bus_set_close_on_exit</refname>
     <refname>sd_bus_get_close_on_exit</refname>
 
-    <refpurpose>Control whether to close the bus connection during the event loop exit phase</refpurpose>
+    <refpurpose>Control whether to close the bus connection during the event loop exit phase
+    </refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
   <refsect1>
     <title>Description</title>
 
-    <para><function>sd_bus_set_close_on_exit()</function> may be used to enable or disable whether the bus connection
-    is automatically flushed (as in
-    <citerefentry><refentrytitle>sd_bus_flush</refentrytitle><manvolnum>3</manvolnum></citerefentry>) and closed (as in
-    <citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>) during the exit
-    phase of the event loop. This logic only applies to bus connections that are attached to an
-    <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry> event loop, see
-    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>. By default
-    this mechanism is enabled and makes sure that any pending messages that have not been written to the bus connection
-    are written out when the event loop is shutting down. In some cases this behaviour is not desirable, for example
-    when the bus connection shall remain usable until after the event loop exited. If <parameter>b</parameter> is
-    true, the feature is enabled (which is the default), otherwise disabled.</para>
-
-    <para><function>sd_bus_get_close_on_exit()</function> may be used to query the current setting of this feature. It
-    returns zero when the feature is disabled, and positive if enabled.</para>
+    <para><function>sd_bus_set_close_on_exit()</function> may be used to enable or disable whether
+    the bus connection is automatically flushed (as in
+    <citerefentry><refentrytitle>sd_bus_flush</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
+    and closed (as in
+    <citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
+    during the exit phase of the event loop. This logic only applies to bus connections that are
+    attached to an
+    <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    event loop, see
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+    By default this mechanism is enabled and makes sure that any pending messages that have not been
+    written to the bus connection are written out when the event loop is shutting down. In some
+    cases this behaviour is not desirable, for example when the bus connection shall remain usable
+    until after the event loop exited. If <parameter>b</parameter> is true, the feature is enabled
+    (which is the default), otherwise disabled.</para>
+
+    <para><function>sd_bus_get_close_on_exit()</function> may be used to query the current setting
+    of this feature. It returns zero when the feature is disabled, and positive if enabled.</para>
   </refsect1>
 
   <refsect1>
     <title>Return Value</title>
 
-    <para>On success, <function>sd_bus_set_close_on_exit()</function> returns 0 or a positive integer. On failure, it returns a negative errno-style
-    error code.</para>
+    <para>On success, <function>sd_bus_set_close_on_exit()</function> returns a non-negative
+    integer. On failure, it returns a negative errno-style error code.</para>
 
-    <para><function>sd_bus_get_close_on_exit()</function> returns 0 if the feature is currently turned off or a
-    positive integer if it is on. On failure, it returns a negative errno-style error code.</para>
+    <para><function>sd_bus_get_close_on_exit()</function> returns 0 if the feature is currently
+    disabled or a positive integer if it is enabled. On failure, it returns a negative errno-style
+    error code.</para>
 
     <refsect2>
       <title>Errors</title>
@@ -78,7 +84,8 @@
         <varlistentry>
           <term><constant>-ECHILD</constant></term>
 
-          <listitem><para>The bus connection has been created in a different process.</para></listitem>
+          <listitem><para>The bus connection was created in a different process.</para>
+          </listitem>
         </varlistentry>
       </variablelist>
     </refsect2>
       <citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
-
 </refentry>
index b855008eb8ecbf16310c74381f308d72bb439549..bd3ec78864b251f63814fe8a44bfabc1f25f5182 100644 (file)
@@ -24,6 +24,9 @@
     <refname>sd_bus_is_trusted</refname>
     <refname>sd_bus_set_allow_interactive_authorization</refname>
     <refname>sd_bus_get_allow_interactive_authorization</refname>
+    <refname>sd_bus_get_scope</refname>
+    <refname>sd_bus_get_tid</refname>
+    <refname>sd_bus_get_unique_name</refname>
 
     <refpurpose>Set or query properties of a bus object</refpurpose>
   </refnamediv>
         <funcdef>int <function>sd_bus_get_allow_interactive_authorization</function></funcdef>
         <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
       </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_scope</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>const char **<parameter>scope</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_tid</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>pid_t *<parameter>tid</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_unique_name</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>const char **<parameter>unique</parameter></paramdef>
+      </funcprototype>
     </funcsynopsis>
   </refsynopsisdiv>
 
   <refsect1>
     <title>Description</title>
 
-    <para><function>sd_bus_set_description()</function> sets the description string
-    that is used in logging to the specified string. The string is copied internally
-    and freed when the bus object is deallocated. The
-    <parameter>description</parameter> argument may be <constant>NULL</constant>, in
-    which case the description is unset. This function must be called before the bus
-    is started.</para>
+    <para><function>sd_bus_set_description()</function> sets the description string that is used in
+    logging to the specified string. The string is copied internally and freed when the bus object
+    is deallocated. The <parameter>description</parameter> argument may be
+    <constant>NULL</constant>, in which case the description is unset. This function must be called
+    before the bus is started.</para>
 
-    <para><function>sd_bus_get_description()</function> returns a description string
-    in <parameter>description</parameter>. This string may have been previously set
-    with <function>sd_bus_set_description()</function> or
+    <para><function>sd_bus_get_description()</function> returns a description string in
+    <parameter>description</parameter>. This string may have been previously set with
+    <function>sd_bus_set_description()</function> or
     <citerefentry><refentrytitle>sd_bus_open_with_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    or similar. If not set this way, a default string like <literal>system</literal>
-    or <literal>user</literal> will be returned for the system or user buses,
-    and <constant>NULL</constant> otherwise.</para>
+    or similar. If not set this way, a default string like <literal>system</literal> or
+    <literal>user</literal> will be returned for the system or user buses, and
+    <constant>NULL</constant> otherwise.</para>
 
-    <para><function>sd_bus_set_anonymous()</function> enables or disables "anonymous
-    authentication", i.e. lack of authentication, of the bus peer. This function must
-    be called before the bus is started. See the <ulink
-    url="view-source:https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms">Authentication
-    Mechanisms</ulink> section of the D-Bus specification for details.</para>
+    <para><function>sd_bus_set_anonymous()</function> enables or disables "anonymous authentication",
+    i.e. lack of authentication, of the bus peer. This function must be called before the bus is
+    started. See the
+    <ulink url="view-source:https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms">
+    Authentication Mechanisms</ulink> section of the D-Bus specification for details.</para>
 
-    <para><function>sd_bus_is_anonymous()</function> returns true if the bus connection allows anonymous
-    authentication (in the sense described in previous paragraph).</para>
+    <para><function>sd_bus_is_anonymous()</function> returns true if the bus connection allows
+    anonymous authentication (in the sense described in previous paragraph).</para>
 
     <para><function>sd_bus_set_trusted()</function> sets the "trusted" state on the
-    <parameter>bus</parameter> object. If true, all connections on the bus are
-    trusted and access to all privileged and unprivileged methods is granted. This
-    function must be called before the bus is started.</para>
+    <parameter>bus</parameter> object. If true, all connections on the bus are trusted and access to
+    all privileged and unprivileged methods is granted. This function must be called before the bus
+    is started.</para>
 
-    <para><function>sd_bus_is_trusted()</function> returns true if the bus connection is trusted (in the
-    sense described in previous paragraph).</para>
+    <para><function>sd_bus_is_trusted()</function> returns true if the bus connection is trusted (in
+    the sense described in previous paragraph).</para>
 
-    <para><function>sd_bus_set_allow_interactive_authorization()</function>
-    enables or disables interactive authorization for method calls. If true,
-    messages are marked with the
+    <para><function>sd_bus_set_allow_interactive_authorization()</function> enables or disables
+    interactive authorization for method calls. If true, messages are marked with the
     <constant>ALLOW_INTERACTIVE_AUTHORIZATION</constant> flag specified by the
-    <ulink
-    url="view-source:https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus</ulink>
-    specification, informing the receiving side that the caller is prepared to
-    wait for interactive authorization, which might take a considerable time to
-    complete. If this flag is set, the user may be queried for passwords or
-    confirmation via <ulink
-    url="http://www.freedesktop.org/wiki/Software/polkit">polkit</ulink> or a
-    similar framework.</para>
-
-    <para><function>sd_bus_get_allow_interactive_authorization()</function> returns
-    true if interactive authorization is allowed and false if not.</para>
+    <ulink url="view-source:https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus</ulink>
+    specification, informing the receiving side that the caller is prepared to wait for interactive
+    authorization, which might take a considerable time to complete. If this flag is set, the user
+    may be queried for passwords or confirmation via
+    <ulink url="http://www.freedesktop.org/wiki/Software/polkit">polkit</ulink> or a similar
+    framework.</para>
+
+    <para><function>sd_bus_get_allow_interactive_authorization()</function> returns true if
+    interactive authorization is allowed and false if not.</para>
+
+    <para><function>sd_bus_get_scope()</function> stores the scope of the given bus object in
+    <parameter>scope</parameter>. The scope of the system bus is <literal>system</literal>. The
+    scope of a user session bus is <literal>user</literal>. If the given bus object is not the
+    system or a user session bus, <function>sd_bus_get_scope()</function> returns an error.</para>
+
+    <para><function>sd_bus_get_tid()</function> stores the kernel thread id of the thread associated
+    with the given bus object in <parameter>tid</parameter>. If <parameter>bus</parameter> is a
+    default bus object obtained by calling one of the functions of the
+    <citerefentry><refentrytitle>sd_bus_default</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    family of functions, it stores the thread id of the thread the bus object was created in.
+    Otherwise, if the bus object is attached to an event loop, it stores the thread id of the
+    thread the event loop object was created in. If <parameter>bus</parameter> is not a default bus
+    object and is not attached to an event loop, <function>sd_bus_get_tid()</function> returns an
+    error.</para>
+
+    <para><function>sd_bus_get_unique_name()</function> stores the unique name of the bus object on
+    the bus in <parameter>unique</parameter>. See
+    <ulink url="https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus">
+    The D-Bus specification</ulink> for more information on bus names. Note that the caller does not
+    own the string stored in <parameter>unique</parameter> and should not free it.</para>
   </refsect1>
 
   <refsect1>
 
           <listitem><para>Memory allocation failed.</para></listitem>
         </varlistentry>
-      </variablelist>
 
+        <varlistentry>
+          <term><constant>-ENODATA</constant></term>
+
+          <listitem><para>The bus object passed to <function>sd_bus_get_scope()</function> was not a
+          system or user session bus.</para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>-ENXIO</constant></term>
+
+          <listitem><para>The bus object passed to <function>sd_bus_get_tid()</function> was not a
+          default bus object and is not attached to an event loop.</para></listitem>
+        </varlistentry>
+      </variablelist>
     </refsect2>
   </refsect1>
 
diff --git a/man/sd_bus_set_exit_on_disconnect.xml b/man/sd_bus_set_exit_on_disconnect.xml
new file mode 100644 (file)
index 0000000..8bd904b
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version='1.0'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1+ -->
+
+<refentry id="sd_bus_set_exit_on_disconnect"
+          xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_set_exit_on_disconnect</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_set_exit_on_disconnect</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_set_exit_on_disconnect</refname>
+    <refname>sd_bus_get_exit_on_disconnect</refname>
+
+    <refpurpose>Control the exit behavior when the bus object disconnects</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_set_exit_on_disconnect</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_exit_on_disconnect</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_set_exit_on_disconnect()</function> may be used to configure the exit
+    behavior when the given bus object disconnects. If <parameter>b</parameter> is zero, no special
+    logic is executed when the bus object disconnects. If <parameter>b</parameter> is non-zero, the
+    behavior on disconnect depends on whether the bus object is attached to an event loop or not. If
+    the bus object is attached to an event loop (see
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>),
+    the event loop is closed when the bus object disconnects (as if calling
+    <citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
+    Otherwise,
+    <citerefentry project='man-pages'><refentrytitle>exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    is called. The exit code passed to <function>sd_event_exit()</function> and
+    <function>exit()</function> is <constant>EXIT_FAILURE</constant>. If the bus object has already
+    disconnected when enabling the exit behavior, the exit behavior is executed immediately. By
+    default, the exit behavior is disabled.</para>
+
+    <para><function>sd_bus_get_exit_on_disconnect()</function> returns whether the exit on
+    disconnect behavior is enabled for the given bus object.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>sd_bus_set_exit_on_disconnect()</function> returns a non-negative
+    integer. On failure, it returns a negative errno-style error code.</para>
+
+    <para><function>sd_bus_get_exit_on_disconnect()</function> returns a positive integer if the
+    exit on disconnect behavior is enabled. Otherwise, it returns zero.</para>
+
+    <refsect2>
+      <title>Errors</title>
+
+      <para>Returned errors may indicate the following problems:</para>
+
+      <variablelist>
+        <varlistentry>
+          <term><constant>-EINVAL</constant></term>
+
+          <listitem><para>A required parameter was <constant>NULL</constant>.</para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>-ENOPKG</constant></term>
+
+          <listitem><para>The bus object could not be resolved.</para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><constant>-ECHILD</constant></term>
+
+          <listitem><para>The bus connection was created in a different process.</para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+  </refsect1>
+
+  <xi:include href="libsystemd-pkgconfig.xml" />
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+</refentry>
index 2e065596a2d076870e0fc61e7d89ba2a905c3f13..6b93b92594bb1171e2364377075db044d3f82cb0 100644 (file)
 
   <refnamediv>
     <refname>sd_bus_set_server</refname>
+    <refname>sd_bus_is_server</refname>
     <refname>sd_bus_get_bus_id</refname>
+    <refname>sd_bus_set_bus_client</refname>
+    <refname>sd_bus_is_bus_client</refname>
 
-    <refpurpose>Configure server mode for a bus object</refpurpose>
+    <refpurpose>Configure direct connection mode for a bus object</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
         <paramdef>sd_id128_t <parameter>id</parameter></paramdef>
       </funcprototype>
 
+      <funcprototype>
+        <funcdef>int <function>sd_bus_is_server</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+      </funcprototype>
+
       <funcprototype>
         <funcdef>int <function>sd_bus_get_bus_id</function></funcdef>
         <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
         <paramdef>sd_id128_t *<parameter>id</parameter></paramdef>
       </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_set_bus_client</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>int <parameter>b</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_is_bus_client</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+      </funcprototype>
     </funcsynopsis>
   </refsynopsisdiv>
 
     <citerefentry><refentrytitle>sd_id128_randomize</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     can be used to generate a random id instead.</para>
 
+    <para><function>sd_bus_is_server()</function> returns whether the server mode is enabled for
+    the given bus object.</para>
+
     <para><function>sd_bus_get_bus_id()</function> stores the D-Bus server id configured using
     <function>sd_bus_set_server()</function> (for server bus objects) or received during
     D-Bus authentication (for client bus objects) in <parameter>id</parameter>.</para>
+
+    <para><function>sd_bus_set_bus_client()</function> configures the bus object as a D-Bus daemon
+    client. <parameter>b</parameter> enables/disables the client mode. If zero, the client mode is
+    disabled and the bus object should connect directly to a D-Bus server. Otherwise, the client
+    mode is enabled and the bus object should connect to a D-Bus daemon. When connecting to an
+    existing bus using any of the functions in the
+    <citerefentry><refentrytitle>sd_bus_open</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    family of functions or any of the functions in the
+    <citerefentry><refentrytitle>sd_bus_default</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    family of functions, the bus object is automatically configured as a bus client. However, when
+    connecting to a D-Bus daemon by calling
+    <citerefentry><refentrytitle>sd_bus_set_address</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    followed by
+    <citerefentry><refentrytitle>sd_bus_start</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+    the bus object should be manually configured as a bus client using
+    <function>sd_bus_set_bus_client()</function>. By default, a bus object is not configured as a
+    D-Bus daemon client.</para>
+
+    <para><function>sd_bus_is_bus_client()</function> returns whether the client mode is
+    enabled/disabled for the given bus object.</para>
   </refsect1>
 
   <refsect1>
     <title>Return Value</title>
 
-    <para>On success, these functions return a non-negative integer. On failure, they return a
-    negative errno-style error code.</para>
+    <para>On success, <function>sd_bus_set_server()</function>,
+    <function>sd_bus_get_bus_id()</function> and <function>sd_bus_set_bus_client()</function> return
+    a non-negative integer. On failure, they return a negative errno-style error code.</para>
+
+    <para><function>sd_bus_is_server()</function> and <function>sd_bus_is_bus_client()</function>
+    return a positive integer when the server or client mode is enabled, respectively. Otherwise,
+    they return zero.
+    </para>
 
     <refsect2>
       <title>Errors</title>
index 1b7b6e1068733a8ad22c526757fabb6eba404c61..5154af23049ef1ff75b28ff0affc683aa829aa2e 100644 (file)
@@ -96,59 +96,70 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
         return 0;
 }
 
-int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
+int sd_dhcp_lease_get_servers(
+                sd_dhcp_lease *lease,
+                sd_dhcp_lease_info what,
+                const struct in_addr **addr) {
+
         assert_return(lease, -EINVAL);
         assert_return(addr, -EINVAL);
 
-        if (lease->dns_size <= 0)
-                return -ENODATA;
+        switch (what) {
+        case SD_DHCP_LEASE_DNS_SERVERS:
+                if (lease->dns_size <= 0)
+                        return -ENODATA;
 
-        *addr = lease->dns;
-        return (int) lease->dns_size;
-}
+                *addr = lease->dns;
+                return (int) lease->dns_size;
 
-int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
+        case SD_DHCP_LEASE_NTP_SERVERS:
+                if (lease->ntp_size <= 0)
+                        return -ENODATA;
 
-        if (lease->ntp_size <= 0)
-                return -ENODATA;
+                *addr = lease->ntp;
+                return (int) lease->ntp_size;
 
-        *addr = lease->ntp;
-        return (int) lease->ntp_size;
-}
+        case SD_DHCP_LEASE_SIP_SERVERS:
+                if (lease->sip_size <= 0)
+                        return -ENODATA;
 
-int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
+                *addr = lease->sip;
+                return (int) lease->sip_size;
 
-        if (lease->sip_size <= 0)
-                return -ENODATA;
+        case SD_DHCP_LEASE_POP3_SERVERS:
+                if (lease->pop3_server_size <= 0)
+                        return -ENODATA;
 
-        *addr = lease->sip;
-        return (int) lease->sip_size;
-}
+                *addr = lease->pop3_server;
+                return (int) lease->pop3_server_size;
 
-int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
+        case SD_DHCP_LEASE_SMTP_SERVERS:
+                if (lease->smtp_server_size <= 0)
+                        return -ENODATA;
 
-        if (lease->pop3_server_size <= 0)
-                return -ENODATA;
+                *addr = lease->smtp_server;
+                return (int) lease->smtp_server_size;
 
-        *addr = lease->pop3_server;
-        return (int) lease->pop3_server_size;
+        default:
+                log_debug("Uknown DHCP lease info item %d.", what);
+                return -ENXIO;
+        }
 }
 
+int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_DNS_SERVERS, addr);
+}
+int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_NTP_SERVERS, addr);
+}
+int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP_SERVERS, addr);
+}
+int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
+        return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3_SERVERS, addr);
+}
 int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
-        assert_return(lease, -EINVAL);
-        assert_return(addr, -EINVAL);
-
-        if (lease->smtp_server_size <= 0)
-                return -ENODATA;
-
-        *addr = lease->smtp_server;
-        return (int) lease->smtp_server_size;
+        return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP_SERVERS, addr);
 }
 
 int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
index ee4a7249c269ca37efbbad5f1eb44b0d607441eb..a4dcddd95d32c3f51129e11ebece787d0549a53f 100644 (file)
@@ -1123,132 +1123,81 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
         return 1;
 }
 
-int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) {
-        assert_return(server, -EINVAL);
-        assert_return(dns || n <= 0, -EINVAL);
-
-        if (server->n_dns == n &&
-            memcmp(server->dns, dns, sizeof(struct in_addr) * n) == 0)
-                return 0;
-
-        if (n <= 0) {
-                server->dns = mfree(server->dns);
-                server->n_dns = 0;
-        } else {
-                struct in_addr *c;
-
-                c = newdup(struct in_addr, dns, n);
-                if (!c)
-                        return -ENOMEM;
+int sd_dhcp_server_set_servers(
+                sd_dhcp_server *server,
+                sd_dhcp_lease_info what,
+                const struct in_addr addresses[],
+                unsigned n_addresses) {
 
-                free(server->dns);
-                server->dns = c;
-                server->n_dns = n;
-        }
-
-        return 1;
-}
-
-int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) {
         assert_return(server, -EINVAL);
-        assert_return(ntp || n <= 0, -EINVAL);
+        assert_return(addresses || n_addresses == 0, -EINVAL);
 
-        if (server->n_ntp == n &&
-            memcmp(server->ntp, ntp, sizeof(struct in_addr) * n) == 0)
-                return 0;
+        struct in_addr **a;
+        unsigned *n_a;
 
-        if (n <= 0) {
-                server->ntp = mfree(server->ntp);
-                server->n_ntp = 0;
-        } else {
-                struct in_addr *c;
-
-                c = newdup(struct in_addr, ntp, n);
-                if (!c)
-                        return -ENOMEM;
-
-                free(server->ntp);
-                server->ntp = c;
-                server->n_ntp = n;
-        }
-
-        return 1;
-}
+        switch (what) {
+        case SD_DHCP_LEASE_DNS_SERVERS:
+                a = &server->dns;
+                n_a = &server->n_dns;
+                break;
 
-int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n) {
-        assert_return(server, -EINVAL);
-        assert_return(sip || n <= 0, -EINVAL);
+        case SD_DHCP_LEASE_NTP_SERVERS:
+                a = &server->ntp;
+                n_a = &server->n_ntp;
+                break;
 
-        if (server->n_sip == n &&
-            memcmp(server->sip, sip, sizeof(struct in_addr) * n) == 0)
-                return 0;
+        case SD_DHCP_LEASE_SIP_SERVERS:
+                a = &server->sip;
+                n_a = &server->n_sip;
+                break;
 
-        if (n <= 0) {
-                server->sip = mfree(server->sip);
-                server->n_sip = 0;
-        } else {
-                struct in_addr *c;
+        case SD_DHCP_LEASE_POP3_SERVERS:
+                a = &server->pop3_server;
+                n_a = &server->n_pop3_server;
+                break;
 
-                c = newdup(struct in_addr, sip, n);
-                if (!c)
-                        return -ENOMEM;
+        case SD_DHCP_LEASE_SMTP_SERVERS:
+                a = &server->smtp_server;
+                n_a = &server->n_smtp_server;
+                break;
 
-                free(server->sip);
-                server->sip = c;
-                server->n_sip = n;
+        default:
+                log_debug("Uknown DHCP lease info item %d.", what);
+                return -ENXIO;
         }
 
-        return 1;
-}
-
-int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n) {
-        assert_return(server, -EINVAL);
-        assert_return(pop3_server || n <= 0, -EINVAL);
-
-        if (server->n_pop3_server == n &&
-            memcmp(server->pop3_server, pop3_server, sizeof(struct in_addr) * n) == 0)
+        if (*n_a == n_addresses &&
+            memcmp(*a, addresses, sizeof(struct in_addr) * n_addresses) == 0)
                 return 0;
 
-        if (n <= 0) {
-                server->pop3_server = mfree(server->pop3_server);
-                server->n_pop3_server = 0;
-        } else {
-                struct in_addr *c;
+        struct in_addr *c = NULL;
 
-                c = newdup(struct in_addr, pop3_server, n);
+        if (n_addresses > 0) {
+                c = newdup(struct in_addr, addresses, n_addresses);
                 if (!c)
                         return -ENOMEM;
-
-                free_and_replace(server->pop3_server, c);
-                server->n_pop3_server = n;
         }
 
+        free(*a);
+        *a = c;
+        *n_a = n_addresses;
         return 1;
 }
 
-int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n) {
-        assert_return(server, -EINVAL);
-        assert_return(smtp_server || n <= 0, -EINVAL);
-
-        if (server->n_smtp_server == n &&
-            memcmp(server->smtp_server, smtp_server, sizeof(struct in_addr) * n) == 0)
-                return 0;
-
-        if (n <= 0) {
-                server->smtp_server = mfree(server->smtp_server);
-                server->n_smtp_server = 0;
-        } else {
-                struct in_addr *c;
-
-                c = newdup(struct in_addr, smtp_server, n);
-                if (!c)
-                        return -ENOMEM;
-
-                free_and_replace(server->smtp_server, c);
-                server->n_smtp_server = n;
-        }
-
-        return 1;
+int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n) {
+        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_DNS_SERVERS, dns, n);
+}
+int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n) {
+        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_NTP_SERVERS, ntp, n);
+}
+int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n) {
+        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SIP_SERVERS, sip, n);
+}
+int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3[], unsigned n) {
+        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_POP3_SERVERS, pop3, n);
+}
+int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp[], unsigned n) {
+        return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP_SERVERS, smtp, n);
 }
 
 int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
index bbaa10f5ab276e0b945144331178cbcd3be624db..ce2244a8fec1469f6b5b2b529baa12c0c98d7a65 100644 (file)
@@ -45,11 +45,6 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
         size_t n_addresses = 0, n_allocated = 0;
         unsigned i;
 
-        log_link_debug(link, "Copying DNS server information from link");
-
-        if (!link->network)
-                return 0;
-
         for (i = 0; i < link->network->n_dns; i++) {
                 struct in_addr ia;
 
@@ -91,164 +86,53 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
         return sd_dhcp_server_set_dns(s, addresses, n_addresses);
 }
 
-static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
-        _cleanup_free_ struct in_addr *addresses = NULL;
-        size_t n_addresses = 0, n_allocated = 0;
-        char **a;
-
-        if (!link->network)
-                return 0;
-
-        log_link_debug(link, "Copying NTP server information from link");
-
-        STRV_FOREACH(a, link->network->ntp) {
-                union in_addr_union ia;
-
-                /* Only look for IPv4 addresses */
-                if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
-                        continue;
-
-                /* Never propagate obviously borked data */
-                if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
-                        continue;
-
-                if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
-                        return log_oom();
-
-                addresses[n_addresses++] = ia.in;
-        }
-
-        if (link->network->dhcp_use_ntp && link->dhcp_lease) {
-                const struct in_addr *da = NULL;
-                int j, n;
-
-                n = sd_dhcp_lease_get_ntp(link->dhcp_lease, &da);
-                if (n > 0) {
-
-                        if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
-                                return log_oom();
-
-                        for (j = 0; j < n; j++)
-                                if (in4_addr_is_non_local(&da[j]))
-                                        addresses[n_addresses++] = da[j];
-                }
-        }
-
-        if (n_addresses <= 0)
-                return 0;
-
-        return sd_dhcp_server_set_ntp(s, addresses, n_addresses);
-}
-
-static int link_push_uplink_pop3_to_dhcp_server(Link *link, sd_dhcp_server *s) {
-        _cleanup_free_ struct in_addr *addresses = NULL;
-        size_t n_addresses = 0, n_allocated = 0;
-        char **a;
-
-        if (!link->network)
-                return 0;
-
-        log_link_debug(link, "Copying POP3 server information from link");
-
-        STRV_FOREACH(a, link->network->pop3) {
-                union in_addr_union ia;
-
-                /* Only look for IPv4 addresses */
-                if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
-                        continue;
-
-                /* Never propagate obviously borked data */
-                if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
-                        continue;
-
-                if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
-                        return log_oom();
-
-                addresses[n_addresses++] = ia.in;
-        }
-
-        if (link->dhcp_lease) {
-                const struct in_addr *da = NULL;
-                int j, n;
-
-                n = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &da);
-                if (n > 0) {
-
-                        if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
-                                return log_oom();
-
-                        for (j = 0; j < n; j++)
-                                if (in4_addr_is_non_local(&da[j]))
-                                        addresses[n_addresses++] = da[j];
-                }
-        }
+static int link_push_uplink_to_dhcp_server(
+                Link *link,
+                sd_dhcp_lease_info what,
+                sd_dhcp_server *s) {
 
-        if (n_addresses <= 0)
-                return 0;
-
-        return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses);
-}
-
-static int link_push_uplink_smtp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
         _cleanup_free_ struct in_addr *addresses = NULL;
         size_t n_addresses = 0, n_allocated = 0;
-        char **a;
+        bool lease_condition;
+        char **servers;
 
         if (!link->network)
                 return 0;
 
-        log_link_debug(link, "Copying SMTP server information from link");
-
-        STRV_FOREACH(a, link->network->smtp) {
-                union in_addr_union ia;
-
-                /* Only look for IPv4 addresses */
-                if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
-                        continue;
-
-                /* Never propagate obviously borked data */
-                if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
-                        continue;
+        log_link_debug(link, "Copying %s from link", dhcp_lease_info_to_string(what));
 
-                if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
-                        return log_oom();
+        switch (what) {
+        case SD_DHCP_LEASE_DNS_SERVERS:
+                /* DNS servers are stored as parsed data, so special handling is required.
+                 * TODO: check if DNS servers should be stored unparsed too. */
+                return link_push_uplink_dns_to_dhcp_server(link, s);
 
-                addresses[n_addresses++] = ia.in;
-        }
+        case SD_DHCP_LEASE_NTP_SERVERS:
+                servers = link->network->ntp;
+                lease_condition = link->network->dhcp_use_ntp;
+                break;
 
-        if (link->dhcp_lease) {
-                const struct in_addr *da = NULL;
-                int j, n;
+        case SD_DHCP_LEASE_POP3_SERVERS:
+                servers = link->network->pop3;
+                lease_condition = true;
+                break;
 
-                n = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &da);
-                if (n > 0) {
+        case SD_DHCP_LEASE_SMTP_SERVERS:
+                servers = link->network->smtp;
+                lease_condition = true;
+                break;
 
-                        if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
-                                return log_oom();
+        case SD_DHCP_LEASE_SIP_SERVERS:
+                servers = link->network->sip;
+                lease_condition = link->network->dhcp_use_sip;
+                break;
 
-                        for (j = 0; j < n; j++)
-                                if (in4_addr_is_non_local(&da[j]))
-                                        addresses[n_addresses++] = da[j];
-                }
+        default:
+                assert_not_reached("Uknown DHCP lease info item");
         }
 
-        if (n_addresses <= 0)
-                return 0;
-
-        return sd_dhcp_server_set_smtp_server(s, addresses, n_addresses);
-}
-
-static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
-        _cleanup_free_ struct in_addr *addresses = NULL;
-        size_t n_addresses = 0, n_allocated = 0;
         char **a;
-
-        if (!link->network)
-                return 0;
-
-        log_link_debug(link, "Copying SIP server information from link");
-
-        STRV_FOREACH(a, link->network->sip) {
+        STRV_FOREACH(a, servers) {
                 union in_addr_union ia;
 
                 /* Only look for IPv4 addresses */
@@ -265,26 +149,24 @@ static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
                 addresses[n_addresses++] = ia.in;
         }
 
-        if (link->network->dhcp_use_sip && link->dhcp_lease) {
-                const struct in_addr *da = NULL;
-                int j, n;
+        if (lease_condition && link->dhcp_lease) {
+                const struct in_addr *da;
 
-                n = sd_dhcp_lease_get_sip(link->dhcp_lease, &da);
+                size_t n = sd_dhcp_lease_get_servers(link->dhcp_lease, what, &da);
                 if (n > 0) {
-
                         if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
                                 return log_oom();
 
-                        for (j = 0; j < n; j++)
-                                if (in4_addr_is_non_local(&da[j]))
-                                        addresses[n_addresses++] = da[j];
+                        for (unsigned i = 0; i < n; i++)
+                                if (in4_addr_is_non_local(&da[i]))
+                                        addresses[n_addresses++] = da[i];
                 }
         }
 
         if (n_addresses <= 0)
                 return 0;
 
-        return sd_dhcp_server_set_sip(s, addresses, n_addresses);
+        return sd_dhcp_server_set_servers(s, what, addresses, n_addresses);
 }
 
 int dhcp4_server_configure(Link *link) {
@@ -326,89 +208,63 @@ int dhcp4_server_configure(Link *link) {
                         return log_link_error_errno(link, r, "Failed to set default lease time for DHCPv4 server instance: %m");
         }
 
-        if (link->network->dhcp_server_emit_dns) {
-                if (link->network->n_dhcp_server_dns > 0)
-                        r = sd_dhcp_server_set_dns(link->dhcp_server, link->network->dhcp_server_dns, link->network->n_dhcp_server_dns);
-                else {
-                        uplink = manager_find_uplink(link->manager, link);
-                        acquired_uplink = true;
-
-                        if (!uplink) {
-                                log_link_debug(link, "Not emitting DNS server information on link, couldn't find suitable uplink.");
-                                r = 0;
-                        } else
-                                r = link_push_uplink_dns_to_dhcp_server(uplink, link->dhcp_server);
-                }
-                if (r < 0)
-                        log_link_warning_errno(link, r, "Failed to set DNS server for DHCP server, ignoring: %m");
-        }
-
-        if (link->network->dhcp_server_emit_ntp) {
-                if (link->network->n_dhcp_server_ntp > 0)
-                        r = sd_dhcp_server_set_ntp(link->dhcp_server, link->network->dhcp_server_ntp, link->network->n_dhcp_server_ntp);
-                else {
-                        if (!acquired_uplink)
-                                uplink = manager_find_uplink(link->manager, link);
-
-                        if (!uplink) {
-                                log_link_debug(link, "Not emitting NTP server information on link, couldn't find suitable uplink.");
-                                r = 0;
-                        } else
-                                r = link_push_uplink_ntp_to_dhcp_server(uplink, link->dhcp_server);
-
-                }
-                if (r < 0)
-                        log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
-        }
-
-        if (link->network->dhcp_server_emit_sip) {
-                if (link->network->n_dhcp_server_sip > 0)
-                        r = sd_dhcp_server_set_sip(link->dhcp_server, link->network->dhcp_server_sip, link->network->n_dhcp_server_sip);
-                else {
-                        if (!acquired_uplink)
-                                uplink = manager_find_uplink(link->manager, link);
-
-                        if (!uplink) {
-                                log_link_debug(link, "Not emitting sip server information on link, couldn't find suitable uplink.");
-                                r = 0;
-                        } else
-                                r = link_push_uplink_sip_to_dhcp_server(uplink, link->dhcp_server);
-
+        const struct {
+                bool condition;
+                const struct in_addr *servers;
+                unsigned n_servers;
+        } configs[] = {
+                [SD_DHCP_LEASE_DNS_SERVERS] = {
+                        link->network->dhcp_server_emit_dns,
+                        link->network->dhcp_server_dns,
+                        link->network->n_dhcp_server_dns,
+                },
+                [SD_DHCP_LEASE_NTP_SERVERS] = {
+                        link->network->dhcp_server_emit_ntp,
+                        link->network->dhcp_server_ntp,
+                        link->network->n_dhcp_server_ntp,
+                },
+                [SD_DHCP_LEASE_SIP_SERVERS] = {
+                        link->network->dhcp_server_emit_sip,
+                        link->network->dhcp_server_sip,
+                        link->network->n_dhcp_server_sip,
+                },
+                [SD_DHCP_LEASE_POP3_SERVERS] = {
+                        true,
+                        link->network->dhcp_server_pop3,
+                        link->network->n_dhcp_server_pop3,
+                },
+                [SD_DHCP_LEASE_SMTP_SERVERS] = {
+                        true,
+                        link->network->dhcp_server_smtp,
+                        link->network->n_dhcp_server_smtp,
+                },
+        };
+        assert_cc(ELEMENTSOF(configs) == _SD_DHCP_LEASE_INFO_MAX);
+
+        for (unsigned n = 0; n < ELEMENTSOF(configs); n++)
+                if (configs[n].condition) {
+                        if (configs[n].n_servers > 0)
+                                r = sd_dhcp_server_set_servers(link->dhcp_server, n,
+                                                               configs[n].servers, configs[n].n_servers);
+                        else {
+                                if (!acquired_uplink) {
+                                        uplink = manager_find_uplink(link->manager, link);
+                                        acquired_uplink = true;
+                                }
+
+                                if (!uplink) {
+                                        log_link_debug(link,
+                                                       "Not emitting %s on link, couldn't find suitable uplink.",
+                                                       dhcp_lease_info_to_string(n));
+                                        r = 0;
+                                } else
+                                        r = link_push_uplink_to_dhcp_server(uplink, n, link->dhcp_server);
+                        }
+                        if (r < 0)
+                                log_link_warning_errno(link, r,
+                                                       "Failed to set %s for DHCP server, ignoring: %m",
+                                                       dhcp_lease_info_to_string(n));
                 }
-                if (r < 0)
-                        log_link_warning_errno(link, r, "Failed to set SIP server for DHCP server, ignoring: %m");
-        }
-
-        if (link->network->n_dhcp_server_pop3 > 0)
-                r = sd_dhcp_server_set_pop3_server(link->dhcp_server, link->network->dhcp_server_pop3, link->network->n_dhcp_server_pop3);
-        else {
-                if (!acquired_uplink)
-                        uplink = manager_find_uplink(link->manager, link);
-
-                if (!uplink) {
-                        log_link_debug(link, "Not emitting POP3 server information on link, couldn't find suitable uplink.");
-                        r = 0;
-                } else
-                        r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server);
-        }
-        if (r < 0)
-                log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m");
-
-        if (link->network->n_dhcp_server_smtp > 0)
-                r = sd_dhcp_server_set_smtp_server(link->dhcp_server, link->network->dhcp_server_smtp, link->network->n_dhcp_server_smtp);
-        else {
-                if (!acquired_uplink)
-                        uplink = manager_find_uplink(link->manager, link);
-
-                if (!uplink) {
-                        log_link_debug(link, "Not emitting SMTP server information on link, couldn't find suitable uplink.");
-                        r = 0;
-                } else
-                        r = link_push_uplink_smtp_to_dhcp_server(uplink, link->dhcp_server);
-        }
-        if (r < 0)
-                log_link_warning_errno(link, r, "Failed to SMTP server for DHCP server, ignoring: %m");
-
 
         r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
         if (r < 0)
@@ -458,30 +314,23 @@ int dhcp4_server_configure(Link *link) {
         return 0;
 }
 
-int config_parse_dhcp_server_dns(
+static int config_parse_dhcp_lease_server_list(
                 const char *unit,
                 const char *filename,
                 unsigned line,
-                const char *section,
-                unsigned section_line,
                 const char *lvalue,
-                int ltype,
                 const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        Network *n = data;
-        const char *p = rvalue;
-        int r;
+                struct in_addr **addresses,
+                unsigned *n_addresses) {
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
 
-        for (;;) {
+        for (const char *p = rvalue;;) {
                 _cleanup_free_ char *w = NULL;
                 union in_addr_union a;
-                struct in_addr *m;
+                int r;
 
                 r = extract_first_word(&p, &w, NULL, 0);
                 if (r == -ENOMEM)
@@ -492,27 +341,25 @@ int config_parse_dhcp_server_dns(
                         return 0;
                 }
                 if (r == 0)
-                        break;
+                        return 0;
 
                 r = in_addr_from_string(AF_INET, w, &a);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse DNS server address '%s', ignoring assignment: %m", w);
+                                   "Failed to parse %s= address '%s', ignoring: %m", lvalue, w);
                         continue;
                 }
 
-                m = reallocarray(n->dhcp_server_dns, n->n_dhcp_server_dns + 1, sizeof(struct in_addr));
+                struct in_addr *m = reallocarray(*addresses, *n_addresses + 1, sizeof(struct in_addr));
                 if (!m)
                         return log_oom();
 
-                m[n->n_dhcp_server_dns++] = a.in;
-                n->dhcp_server_dns = m;
+                m[(*n_addresses)++] = a.in;
+                *addresses = m;
         }
-
-        return 0;
 }
 
-int config_parse_dhcp_server_ntp(
+int config_parse_dhcp_server_dns(
                 const char *unit,
                 const char *filename,
                 unsigned line,
@@ -525,43 +372,29 @@ int config_parse_dhcp_server_ntp(
                 void *userdata) {
 
         Network *n = data;
-        const char *p = rvalue;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
 
-        for (;;) {
-                _cleanup_free_ char *w = NULL;
-                union in_addr_union a;
-                struct in_addr *m;
-
-                r = extract_first_word(&p, &w, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to extract word, ignoring: %s", rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
+        return config_parse_dhcp_lease_server_list(unit, filename, line,
+                                                   lvalue, rvalue,
+                                                   &n->dhcp_server_dns, &n->n_dhcp_server_dns);
+}
 
-                r = in_addr_from_string(AF_INET, w, &a);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse NTP server address '%s', ignoring: %m", w);
-                        continue;
-                }
+int config_parse_dhcp_server_ntp(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
-                m = reallocarray(n->dhcp_server_ntp, n->n_dhcp_server_ntp + 1, sizeof(struct in_addr));
-                if (!m)
-                        return log_oom();
+        Network *n = data;
 
-                m[n->n_dhcp_server_ntp++] = a.in;
-                n->dhcp_server_ntp = m;
-        }
+        return config_parse_dhcp_lease_server_list(unit, filename, line,
+                                                   lvalue, rvalue,
+                                                   &n->dhcp_server_ntp, &n->n_dhcp_server_ntp);
 }
 
 int config_parse_dhcp_server_sip(
@@ -577,45 +410,10 @@ int config_parse_dhcp_server_sip(
                 void *userdata) {
 
         Network *n = data;
-        const char *p = rvalue;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        for (;;) {
-                _cleanup_free_ char *w = NULL;
-                union in_addr_union a;
-                struct in_addr *m;
-
-                r = extract_first_word(&p, &w, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to extract word, ignoring: %s", rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
-
-                r = in_addr_from_string(AF_INET, w, &a);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse SIP server address '%s', ignoring: %m", w);
-                        continue;
-                }
 
-                m = reallocarray(n->dhcp_server_sip, n->n_dhcp_server_sip + 1, sizeof(struct in_addr));
-                if (!m)
-                        return log_oom();
-
-                m[n->n_dhcp_server_sip++] = a.in;
-                n->dhcp_server_sip = m;
-        }
-
-        return 0;
+        return config_parse_dhcp_lease_server_list(unit, filename, line,
+                                                   lvalue, rvalue,
+                                                   &n->dhcp_server_sip, &n->n_dhcp_server_sip);
 }
 
 int config_parse_dhcp_server_pop3_servers(
@@ -631,45 +429,10 @@ int config_parse_dhcp_server_pop3_servers(
                 void *userdata) {
 
         Network *n = data;
-        const char *p = rvalue;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
 
-        for (;;) {
-                _cleanup_free_ char *w = NULL;
-                union in_addr_union a;
-                struct in_addr *m;
-
-                r = extract_first_word(&p, &w, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to extract word, ignoring: %s", rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
-
-                r = in_addr_from_string(AF_INET, w, &a);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse POP3 server address '%s', ignoring: %m", w);
-                        continue;
-                }
-
-                m = reallocarray(n->dhcp_server_pop3, n->n_dhcp_server_pop3 + 1, sizeof(struct in_addr));
-                if (!m)
-                        return log_oom();
-
-                m[n->n_dhcp_server_pop3++] = a.in;
-                n->dhcp_server_pop3 = m;
-        }
-
-        return 0;
+        return config_parse_dhcp_lease_server_list(unit, filename, line,
+                                                   lvalue, rvalue,
+                                                   &n->dhcp_server_pop3, &n->n_dhcp_server_pop3);
 }
 
 int config_parse_dhcp_server_smtp_servers(
@@ -685,43 +448,9 @@ int config_parse_dhcp_server_smtp_servers(
                 void *userdata) {
 
         Network *n = data;
-        const char *p = rvalue;
-        int r;
 
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
+        return config_parse_dhcp_lease_server_list(unit, filename, line,
+                                                   lvalue, rvalue,
+                                                   &n->dhcp_server_smtp, &n->n_dhcp_server_smtp);
 
-        for (;;) {
-                _cleanup_free_ char *w = NULL;
-                union in_addr_union a;
-                struct in_addr *m;
-
-                r = extract_first_word(&p, &w, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to extract word, ignoring: %s", rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
-
-                r = in_addr_from_string(AF_INET, w, &a);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to parse SMTP server address '%s', ignoring: %m", w);
-                        continue;
-                }
-
-                m = reallocarray(n->dhcp_server_smtp, n->n_dhcp_server_smtp + 1, sizeof(struct in_addr));
-                if (!m)
-                        return log_oom();
-
-                m[n->n_dhcp_server_smtp++] = a.in;
-                n->dhcp_server_smtp = m;
-        }
-
-        return 0;
 }
index deba9953726afbfafd33dc2afb60f95154ead026..3d1d3bd68456454d39ee0423dd29a641d5e7f075 100644 (file)
@@ -8,14 +8,14 @@
 #include "string-util.h"
 #include "util.h"
 
-static const char * const address_family_table[_ADDRESS_FAMILY_MAX] = {
+static const char* const address_family_table[_ADDRESS_FAMILY_MAX] = {
         [ADDRESS_FAMILY_NO]            = "no",
         [ADDRESS_FAMILY_YES]           = "yes",
         [ADDRESS_FAMILY_IPV4]          = "ipv4",
         [ADDRESS_FAMILY_IPV6]          = "ipv6",
 };
 
-static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
+static const char* const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
         [ADDRESS_FAMILY_NO]            = "no",
         [ADDRESS_FAMILY_YES]           = "yes",
         [ADDRESS_FAMILY_IPV4]          = "ipv4",
@@ -24,25 +24,34 @@ static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] =
         [ADDRESS_FAMILY_FALLBACK_IPV4] = "ipv4-fallback",
 };
 
-static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
+static const char* const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
         [ADDRESS_FAMILY_YES]           = "both",
         [ADDRESS_FAMILY_IPV4]          = "ipv4",
         [ADDRESS_FAMILY_IPV6]          = "ipv6",
 };
 
-static const char * const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
+static const char* const duplicate_address_detection_address_family_table[_ADDRESS_FAMILY_MAX] = {
         [ADDRESS_FAMILY_NO]            = "none",
         [ADDRESS_FAMILY_YES]           = "both",
         [ADDRESS_FAMILY_IPV4]          = "ipv4",
         [ADDRESS_FAMILY_IPV6]          = "ipv6",
 };
 
+static const char* const dhcp_lease_info_table[_SD_DHCP_LEASE_INFO_MAX] = {
+        [SD_DHCP_LEASE_DNS_SERVERS]  = "DNS servers",
+        [SD_DHCP_LEASE_NTP_SERVERS]  = "NTP servers",
+        [SD_DHCP_LEASE_SIP_SERVERS]  = "SIP servers",
+        [SD_DHCP_LEASE_POP3_SERVERS] = "POP3 servers",
+        [SD_DHCP_LEASE_SMTP_SERVERS] = "SMTP servers",
+};
+
 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
 DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
 DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
                          AddressFamily, "Failed to parse option");
+DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_info, sd_dhcp_lease_info);
 
 int config_parse_address_family_with_kernel(
                 const char* unit,
index 28dd9d3fe564720a3761ebc17ac54becfcc85dd6..48411b0cf52c93e232c36c5e48e0c76cc4c4b014 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
+#include "sd-dhcp-lease.h"
+
 #include "conf-parser.h"
 #include "hash-funcs.h"
 #include "macro.h"
@@ -38,6 +40,9 @@ AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pur
 const char *duplicate_address_detection_address_family_to_string(AddressFamily b) _const_;
 AddressFamily duplicate_address_detection_address_family_from_string(const char *s) _pure_;
 
+const char *dhcp_lease_info_to_string(sd_dhcp_lease_info info) _const_;
+sd_dhcp_lease_info dhcp_lease_info_from_string(const char *s) _pure_;
+
 int kernel_route_expiration_supported(void);
 
 int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);
index d7e7b5a853ca3fb590fbca0b4a343048bffab806..d06e428011b276938864804cf63faadcf7d79e24 100644 (file)
@@ -496,9 +496,8 @@ DnsScopeMatch dns_scope_good_domain(
         assert(s);
         assert(domain);
 
-        /* Checks if the specified domain is something to look up on
-         * this scope. Note that this accepts non-qualified hostnames,
-         * i.e. those without any search path prefixed yet. */
+        /* Checks if the specified domain is something to look up on this scope. Note that this accepts
+         * non-qualified hostnames, i.e. those without any search path suffixed. */
 
         if (ifindex != 0 && (!s->link || s->link->ifindex != ifindex))
                 return DNS_SCOPE_NO;
index 1ed5bf27a3a5b592cb9cc6281f9ec7b893896750..70544e13f1d8ca2f2ca8782595b4cde1444414f1 100644 (file)
@@ -33,6 +33,15 @@ typedef struct sd_dhcp_route sd_dhcp_route;
 sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
 sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
 
+typedef enum sd_dhcp_lease_info {
+        SD_DHCP_LEASE_DNS_SERVERS = 0,
+        SD_DHCP_LEASE_NTP_SERVERS,
+        SD_DHCP_LEASE_SIP_SERVERS,
+        SD_DHCP_LEASE_POP3_SERVERS,
+        SD_DHCP_LEASE_SMTP_SERVERS,
+        _SD_DHCP_LEASE_INFO_MAX,
+} sd_dhcp_lease_info;
+
 int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
 int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
@@ -42,6 +51,7 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
 int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
 int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
+int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_info what, const struct in_addr **addr);
 int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
 int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
 int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
index 5f04034b82a722f1c101ec34a3438054edad071a..4c7938ca70c4f0680bd9f63f9f4ad2a895473341 100644 (file)
@@ -21,6 +21,7 @@
 #include <inttypes.h>
 #include <netinet/in.h>
 
+#include "sd-dhcp-lease.h"
 #include "sd-dhcp-option.h"
 #include "sd-event.h"
 
@@ -47,12 +48,19 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
 int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size);
 
 int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
+int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
+
+int sd_dhcp_server_set_servers(
+                sd_dhcp_server *server,
+                sd_dhcp_lease_info what,
+                const struct in_addr addresses[],
+                unsigned n_addresses);
+
 int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
 int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
 int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
 int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n);
 int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n);
-int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
 
 int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v);
 int sd_dhcp_server_add_vendor_option(sd_dhcp_server *server, sd_dhcp_option *v);