Compare commits

..

14 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek c083264115
Merge pull request #15278 from vcaputo/more-trivial-cleanups
Expand use of _cleanup_close_ where trivial
2020-04-01 00:16:56 +02:00
Lennart Poettering 9e76a88faf man: mention that stdout logging works the same as stderr logging
Apparently people wondered about that:

https://lists.freedesktop.org/archives/systemd-devel/2020-March/044091.html
2020-04-01 00:15:41 +02:00
Daan De Meyer 47203ed085 sd-bus: sd_bus_call docs improvements 2020-04-01 00:15:11 +02:00
Daan De Meyer e3e5a6eebd sd-bus: Add sd_bus_get/set_priority docs + fixes 2020-04-01 00:11:33 +02:00
Zbigniew Jędrzejewski-Szmek b1b9e829c2
Merge pull request #15229 from ssahani/mud
network: Introduce MUD
2020-04-01 00:10:13 +02:00
Vito Caputo 8e06af804b *: use _cleanup_close_ with fdopendir() where trivial
Also convert these to use take_fdopendir().
2020-03-31 06:48:03 -07:00
Vito Caputo b46c3e4913 *: use _cleanup_close_ with fdopen() where trivial
Also convert these to use take_fdopen().
2020-03-31 06:48:03 -07:00
Vito Caputo 9f81a592c1 *: convert amenable fdopendir() calls to take_fdopendir()
Some fdopendir() calls remain where safe_close() is manually
performed, those could be simplified as well by converting to
use the _cleanup_close_ machinery, but makes things less trivial
to review so left for a future cleanup.
2020-03-31 06:48:03 -07:00
Vito Caputo f61457b0fe fileio: add take_fdopendir() variant
fdopendir() wrapper analogous to take_fdopen()
2020-03-31 06:48:03 -07:00
Vito Caputo 4fa744a35c *: convert amenable fdopen calls to take_fdopen
Mechanical change to eliminate some cruft by using the
new take_fdopen{_unlocked}() wrappers where trivial.
2020-03-31 06:48:03 -07:00
Vito Caputo 3ebbb6cb39 fileio: introduce take_fdopen{_unlocked}() variant
With the addition of _cleanup_close_ there's a repetitious
pattern of assigning -1 to the fd after a successful fdopen
to prevent its close on cleanup now that the FILE * owns the
fd.

This introduces a wrapper that instead takes a pointer to the
fd being opened, and always overwrites the fd with -1 on success.

A future commit will cleanup all the fdopen call sites to use the
wrapper and elide the manual -1 fd assignment.
2020-03-31 06:48:00 -07:00
Vito Caputo 3aeea37d88 home: narrow scope of 'size_t n'
trivial cosmetic cleanup
2020-03-31 00:29:26 -07:00
Susant Sahani 7b8d23a9bb network: DHCPv4 - introduce The Manufacturer Usage Description (MUD) 2020-03-30 20:27:48 +02:00
Susant Sahani d11d4a6459 sd-dhcpv4: introduce The Manufacturer Usage Description (MUD) 2020-03-30 19:16:01 +02:00
37 changed files with 250 additions and 110 deletions

View File

@ -289,7 +289,9 @@ manpages = [
'sd_bus_message_get_interface',
'sd_bus_message_get_member',
'sd_bus_message_get_path',
'sd_bus_message_get_priority',
'sd_bus_message_get_sender',
'sd_bus_message_set_priority',
'sd_bus_message_set_sender'],
''],
['sd_bus_message_set_expect_reply',

View File

@ -67,6 +67,8 @@
<citerefentry><refentrytitle>sd_bus_message_dump</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_cookie</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_priority</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_signature</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_get_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
@ -79,6 +81,8 @@
<citerefentry><refentrytitle>sd_bus_message_rewind</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_seal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_set_priority</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_set_expect_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_skip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_message_verify_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>,

View File

@ -68,16 +68,14 @@
#define SD_INFO "&lt;6&gt;" /* informational */
#define SD_DEBUG "&lt;7&gt;" /* debug-level messages */</programlisting>
<para>These prefixes are intended to be used in conjunction with
stderr-based logging as implemented by systemd. If a systemd
service definition file is configured with
<varname>StandardError=journal</varname>,
<varname>StandardError=syslog</varname> or
<varname>StandardError=kmsg</varname>, these prefixes can be used
to encode a log level in lines printed. This is similar to the
kernel <function>printk()</function>-style logging. See
<citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
for more information.</para>
<para>These prefixes are intended to be used in conjunction with stderr-based logging (or stdout-based
logging) as implemented by systemd. If a systemd service definition file is configured with
<varname>StandardError=journal</varname>, <varname>StandardError=syslog</varname> or
<varname>StandardError=kmsg</varname> (and similar with <varname>StandardOutput=</varname>), these
prefixes can be used to encode a log level in lines printed. This is similar to the kernel
<function>printk()</function>-style logging. See
<citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for more
information.</para>
<para>The log levels are identical to
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s

View File

@ -52,34 +52,39 @@
<title>Description</title>
<para><function>sd_bus_call()</function> takes a complete bus message object and calls the
corresponding D-Bus method. The response is stored in <parameter>reply</parameter>.
corresponding D-Bus method. On success, the response is stored in <parameter>reply</parameter>.
<parameter>usec</parameter> indicates the timeout in microseconds. If
<parameter>ret_error</parameter> is not <constant>NULL</constant> and
<function>sd_bus_call()</function> returns an error, <parameter>ret_error</parameter> is
initialized to an instance of <structname>sd_bus_error</structname> describing the error.</para>
<function>sd_bus_call()</function> fails (either because of an internal error or because it
received a D-Bus error reply), <parameter>ret_error</parameter> is initialized to an instance of
<structname>sd_bus_error</structname> describing the error.</para>
<para><function>sd_bus_call_async()</function> is like <function>sd_bus_call()</function> but
works asynchronously. The <parameter>callback</parameter> shall reference a function to call
when the event source is triggered. The <parameter>userdata</parameter> pointer will be passed
to the callback function, and may be chosen freely by the caller. If <parameter>slot</parameter>
is not <constant>NULL</constant> and <function>sd_bus_call_async()</function> succeeds,
works asynchronously. The <parameter>callback</parameter> indicates the function to call when
the response arrives. The <parameter>userdata</parameter> pointer will be passed to the callback
function, and may be chosen freely by the caller. If <parameter>slot</parameter> is not
<constant>NULL</constant> and <function>sd_bus_call_async()</function> succeeds,
<parameter>slot</parameter> is set to a slot object which can be used to cancel the method call
at a later time using
<citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
If <parameter>slot</parameter> is <constant>NULL</constant>, the lifetime of the method call is
bound to the lifetime of the bus object itself, and it cannot be cancelled independently. See
<citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for details. The <parameter>callback</parameter> function is called when the response arrives
and receives the response, <parameter>userdata</parameter> and a
<structname>sd_bus_error</structname> object as its arguments. The
<structname>sd_bus_error</structname> object is unused here and should be ignored. If
<parameter>callback</parameter> returns a non-negative integer when called, a debug message is
logged along with details about the response.</para>
<para>To determine whether the method call succeeded, use
for details. <parameter>callback</parameter> is called when a reply arrives with the reply,
<parameter>userdata</parameter> and an <structname>sd_bus_error</structname> output
parameter as its arguments. Unlike <function>sd_bus_call()</function>, the
<structname>sd_bus_error</structname> output parameter passed to the callback will be empty. To
determine whether the method call succeeded, use
<citerefentry><refentrytitle>sd_bus_message_is_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>
on the reply object returned by <function>sd_bus_call()</function> or passed to the callback of
<function>sd_bus_call_async()</function>.</para>
on the reply message passed to the callback instead. If the callback returns zero and the
<structname>sd_bus_error</structname> output parameter is still empty when the callback
inishes, other handlers registered with functions such as
<citerefentry><refentrytitle>sd_bus_add_filter</refentrytitle><manvolnum>3</manvolnum></citerefentry> or
<citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>
are given a chance to process the message. If the callback returns a non-zero value or the
<structname>sd_bus_error</structname> output parameter is not empty when the callback finishes,
no further processing of the message is done. Generally, you want to return zero from the
callback to give other registered handlers a chance to process the reply as well.</para>
<para>If <parameter>usec</parameter> is zero, the default D-Bus method call timeout is used. See
<citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>.

View File

@ -19,6 +19,8 @@
<refname>sd_bus_message_get_path</refname>
<refname>sd_bus_message_get_interface</refname>
<refname>sd_bus_message_get_member</refname>
<refname>sd_bus_message_set_priority</refname>
<refname>sd_bus_message_get_priority</refname>
<refname>sd_bus_message_set_sender</refname>
<refname>sd_bus_message_get_sender</refname>
@ -55,6 +57,18 @@
<paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_bus_message_set_priority</function></funcdef>
<paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
<paramdef>int64_t <parameter>priority</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_bus_message_get_priority</function></funcdef>
<paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
<paramdef>int64_t *<parameter>priority</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_bus_message_set_sender</function></funcdef>
<paramdef>sd_bus_message *<parameter>message</parameter></paramdef>
@ -82,11 +96,13 @@
member fields from <parameter>message</parameter> header. The return value will be
<constant>NULL</constant> is <parameter>message</parameter> is <constant>NULL</constant> or the
message is of a type that doesn't use those fields or the message doesn't have them set. See
<citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry> and
<citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for more discussion of those values.</para>
<para><function>sd_bus_message_set_priority()</function> and
<function>sd_bus_message_get_priority()</function> modify and query a message's priority
respectively. sd-bus currently doesn't make use of a message's priority.</para>
<para><function>sd_bus_message_set_sender()</function> sets the sender service name for the specified bus message
object. The specified name must be a valid unique or well-known service name. This function is useful only for
@ -123,9 +139,10 @@
<varlistentry>
<term><constant>-EPERM</constant></term>
<listitem><para>For <function>sd_bus_message_set_destination</function> or
<function>sd_bus_message_set_sender</function>, the message is already
sealed.</para></listitem>
<listitem><para>For <function>sd_bus_message_set_destination()</function>,
<function>sd_bus_message_set_sender()</function> and
<function>sd_bus_message_set_priority()</function>, the message is already sealed.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -1430,6 +1430,18 @@
sent even if this is set to true.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MUDURL=</varname></term>
<listitem>
<para>When configured, the Manufacturer Usage Descriptions (MUD) URL will be sent to the
DHCPv4 server. Takes an URL of length up to 255 characters. A superficial verification that
the string is a valid URL will be performed. DHCPv4 clients are intended to have at most one
MUD URL associated with them. See
<ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseHostname=</varname></term>
<listitem>

View File

@ -15,6 +15,7 @@
#include "copy.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "io-util.h"
#include "macro.h"
@ -569,10 +570,9 @@ static int fd_copy_directory(
if (fdf < 0)
return -errno;
d = fdopendir(fdf);
d = take_fdopendir(&fdf);
if (!d)
return -errno;
fdf = -1;
exists = false;
if (copy_flags & COPY_MERGE_EMPTY) {

View File

@ -54,6 +54,44 @@ int fdopen_unlocked(int fd, const char *options, FILE **ret) {
return 0;
}
int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) {
int r;
assert(fd);
r = fdopen_unlocked(*fd, options, ret);
if (r < 0)
return r;
*fd = -1;
return 0;
}
FILE* take_fdopen(int *fd, const char *options) {
assert(fd);
FILE *f = fdopen(*fd, options);
if (!f)
return NULL;
*fd = -1;
return f;
}
DIR* take_fdopendir(int *dfd) {
assert(dfd);
DIR *d = fdopendir(*dfd);
if (!d)
return NULL;
*dfd = -1;
return d;
}
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) {
FILE *f = open_memstream(ptr, sizeloc);
if (!f)

View File

@ -39,6 +39,9 @@ typedef enum {
int fopen_unlocked(const char *path, const char *options, FILE **ret);
int fdopen_unlocked(int fd, const char *options, FILE **ret);
int take_fdopen_unlocked(int *fd, const char *options, FILE **ret);
FILE* take_fdopen(int *fd, const char *options);
DIR* take_fdopendir(int *dfd);
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc);
FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode);

View File

@ -10,6 +10,7 @@
#include "alloc-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "macro.h"
#include "missing_fs.h"
@ -77,10 +78,9 @@ int dir_is_empty_at(int dir_fd, const char *path) {
if (fd < 0)
return -errno;
d = fdopendir(fd);
d = take_fdopendir(&fd);
if (!d)
return -errno;
fd = -1;
FOREACH_DIRENT(de, d, return -errno)
return 0;

View File

@ -48,14 +48,12 @@ int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
* context and never shared externally, hence locking is not necessary. */
r = fdopen_unlocked(fd, "w", &f);
r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0) {
(void) unlink(t);
return r;
}
TAKE_FD(fd);
if (ret_f)
*ret_f = TAKE_PTR(f);
@ -80,18 +78,16 @@ int mkostemp_safe(char *pattern) {
}
int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) {
int fd;
_cleanup_close_ int fd = -1;
FILE *f;
fd = mkostemp_safe(pattern);
if (fd < 0)
return fd;
f = fdopen(fd, mode);
if (!f) {
safe_close(fd);
f = take_fdopen(&fd, mode);
if (!f)
return -errno;
}
*ret_f = f;
return 0;

View File

@ -982,8 +982,9 @@ static int install_loader_config(const char *esp_path, sd_id128_t machine_id) {
char machine_string[SD_ID128_STRING_MAX];
_cleanup_(unlink_and_freep) char *t = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -1;
const char *p;
int r, fd;
int r;
p = prefix_roota(esp_path, "/loader/loader.conf");
if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
@ -993,11 +994,9 @@ static int install_loader_config(const char *esp_path, sd_id128_t machine_id) {
if (fd < 0)
return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p);
f = fdopen(fd, "w");
if (!f) {
safe_close(fd);
f = take_fdopen(&fd, "w");
if (!f)
return log_oom();
}
fprintf(f, "#timeout 3\n"
"#console-mode keep\n"

View File

@ -3107,7 +3107,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
}
int manager_open_serialization(Manager *m, FILE **_f) {
int fd;
_cleanup_close_ int fd = -1;
FILE *f;
assert(_f);
@ -3116,11 +3116,9 @@ int manager_open_serialization(Manager *m, FILE **_f) {
if (fd < 0)
return fd;
f = fdopen(fd, "w+");
if (!f) {
safe_close(fd);
f = take_fdopen(&fd, "w+");
if (!f)
return -errno;
}
*_f = f;
return 0;

View File

@ -560,7 +560,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
FOREACH_DIRENT(dent, proc_fd_dir, return -errno) {
_cleanup_fclose_ FILE *fdinfo = NULL;
_cleanup_free_ char *fdname = NULL;
int fd;
_cleanup_close_ int fd = -1;
r = readlinkat_malloc(dirfd(proc_fd_dir), dent->d_name, &fdname);
if (r < 0)
@ -574,11 +574,9 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
if (fd < 0)
continue;
fdinfo = fdopen(fd, "r");
if (!fdinfo) {
safe_close(fd);
fdinfo = take_fdopen(&fd, "r");
if (!fdinfo)
continue;
}
for (;;) {
_cleanup_free_ char *line = NULL;

View File

@ -360,12 +360,10 @@ static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
if (lseek(fd, SEEK_SET, 0) == (off_t) -1)
return log_error_errno(errno, "Failed to seek to beginning of memfd: %m");
f = fdopen(fd, "r");
f = take_fdopen(&fd, "r");
if (!f)
return log_error_errno(errno, "Failed to reopen memfd: %m");
TAKE_FD(fd);
if (DEBUG_LOGGING) {
_cleanup_free_ char *text = NULL;

View File

@ -142,7 +142,8 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
_cleanup_(closedirp) DIR *d = NULL;
int r, copy;
_cleanup_close_ int copy = -1;
int r;
assert(h);
assert(user_record_storage(h) == USER_CIFS);
@ -166,11 +167,9 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
if (copy < 0)
return -errno;
d = fdopendir(copy);
if (!d) {
safe_close(copy);
d = take_fdopendir(&copy);
if (!d)
return -errno;
}
errno = 0;
if (readdir_no_dot(d))

View File

@ -38,7 +38,6 @@ int user_record_authenticate(
bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false,
pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false;
size_t n;
int r;
assert(h);
@ -70,7 +69,7 @@ int user_record_authenticate(
}
/* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */
for (n = 0; n < h->n_pkcs11_encrypted_key; n++) {
for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
#if HAVE_P11KIT
_cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
.user_record = h,
@ -280,12 +279,10 @@ static int read_identity_file(int root_fd, JsonVariant **ret) {
if (r < 0)
return log_error_errno(r, "Embedded identity file is not a regular file, refusing: %m");
identity_file = fdopen(identity_fd, "r");
identity_file = take_fdopen(&identity_fd, "r");
if (!identity_file)
return log_oom();
identity_fd = -1;
r = json_parse_file(identity_file, ".identity", JSON_PARSE_SENSITIVE, ret, &line, &column);
if (r < 0)
return log_error_errno(r, "[.identity:%u:%u] Failed to parse JSON data: %m", line, column);
@ -319,14 +316,12 @@ static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) {
if (identity_fd < 0)
return log_error_errno(errno, "Failed to create .identity file in home directory: %m");
identity_file = fdopen(identity_fd, "w");
identity_file = take_fdopen(&identity_fd, "w");
if (!identity_file) {
r = log_oom();
goto fail;
}
identity_fd = -1;
json_variant_dump(normalized, JSON_FORMAT_PRETTY, identity_file, NULL);
r = fflush_and_check(identity_file);

View File

@ -123,18 +123,16 @@ static int request_meta_ensure_tmp(RequestMeta *m) {
if (m->tmp)
rewind(m->tmp);
else {
int fd;
_cleanup_close_ int fd = -1;
fd = open_tmpfile_unlinkable("/tmp", O_RDWR|O_CLOEXEC);
if (fd < 0)
return fd;
m->tmp = fdopen(fd, "w+");
if (!m->tmp) {
safe_close(fd);
m->tmp = take_fdopen(&fd, "w+");
if (!m->tmp)
return -errno;
}
}
return 0;
}

View File

@ -1718,7 +1718,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
goto fail;
}
} else {
int dfd;
_cleanup_close_ int dfd = -1;
/* If there's no path specified, then we use the top-level fd itself. We duplicate the fd here, since
* opendir() will take possession of the fd, and close it, which we don't want. */
@ -1731,10 +1731,9 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) {
goto fail;
}
d = fdopendir(dfd);
d = take_fdopendir(&dfd);
if (!d) {
r = -errno;
safe_close(dfd);
goto fail;
}

View File

@ -27,6 +27,7 @@
#include "random-util.h"
#include "string-util.h"
#include "strv.h"
#include "web-util.h"
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
@ -83,6 +84,7 @@ struct sd_dhcp_client {
size_t client_id_len;
char *hostname;
char *vendor_class_identifier;
char *mudurl;
char **user_class;
uint32_t mtu;
uint32_t xid;
@ -493,6 +495,18 @@ int sd_dhcp_client_set_vendor_class_identifier(
return free_and_strdup(&client->vendor_class_identifier, vci);
}
int sd_dhcp_client_set_mud_url(
sd_dhcp_client *client,
const char *mudurl) {
assert_return(client, -EINVAL);
assert_return(mudurl, -EINVAL);
assert_return(strlen(mudurl) <= 255, -EINVAL);
assert_return(http_url_is_valid(mudurl), -EINVAL);
return free_and_strdup(&client->mudurl, mudurl);
}
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const* user_class) {
@ -895,6 +909,15 @@ static int client_send_discover(sd_dhcp_client *client) {
return r;
}
if (client->mudurl) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_MUD_URL,
strlen(client->mudurl),
client->mudurl);
if (r < 0)
return r;
}
if (client->user_class) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_USER_CLASS,
@ -1032,6 +1055,16 @@ static int client_send_request(sd_dhcp_client *client) {
return r;
}
if (client->mudurl) {
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_MUD_URL,
strlen(client->mudurl),
client->mudurl);
if (r < 0)
return r;
}
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
@ -2101,6 +2134,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
free(client->req_opts);
free(client->hostname);
free(client->vendor_class_identifier);
free(client->mudurl);
client->user_class = strv_free(client->user_class);
ordered_hashmap_free(client->extra_options);
ordered_hashmap_free(client->vendor_options);

View File

@ -20,6 +20,7 @@
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
@ -399,12 +400,10 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
pair[1] = safe_close(pair[1]);
f = fdopen(pair[0], "r");
f = take_fdopen(&pair[0], "r");
if (!f)
return -errno;
pair[0] = -1;
r = load_env_file_pairs(f, "/etc/os-release", &l);
if (r < 0)
return r;

View File

@ -620,12 +620,10 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
return -errno;
f = fdopen(operation->extra_fd, "r");
f = take_fdopen(&operation->extra_fd, "r");
if (!f)
return -errno;
operation->extra_fd = -1;
/* The resulting temporary file starts with a boolean value that indicates success or not. */
errno = 0;
n = fread(&success, 1, sizeof(success), f);

View File

@ -5,6 +5,7 @@
#include <linux/if.h>
#include <linux/if_arp.h>
#include "escape.h"
#include "alloc-util.h"
#include "dhcp-client-internal.h"
#include "hostname-util.h"
@ -17,6 +18,7 @@
#include "string-table.h"
#include "string-util.h"
#include "sysctl-util.h"
#include "web-util.h"
static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all);
@ -1456,6 +1458,13 @@ int dhcp4_configure(Link *link) {
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m");
}
if (link->network->dhcp_mudurl) {
r = sd_dhcp_client_set_mud_url(link->dhcp_client,
link->network->dhcp_mudurl);
if (r < 0)
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m");
}
if (link->network->dhcp_user_class) {
r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
if (r < 0)
@ -1744,6 +1753,48 @@ int config_parse_dhcp_ip_service_type(
return 0;
}
int config_parse_dhcp_mud_url(
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) {
_cleanup_free_ char *unescaped = NULL;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
network->dhcp_mudurl = mfree(network->dhcp_mudurl);
return 0;
}
r = cunescape(rvalue, 0, &unescaped);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to Failed to unescape MUD URL, ignoring: %s", rvalue);
return 0;
}
if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Failed to parse MUD URL '%s', ignoring: %m", rvalue);
return 0;
}
return free_and_strdup_warn(&network->dhcp_mudurl, unescaped);
}
static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = {
[DHCP_CLIENT_ID_MAC] = "mac",
[DHCP_CLIENT_ID_DUID] = "duid",

View File

@ -28,3 +28,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);

View File

@ -170,6 +170,7 @@ DHCPv4.SendHostname, config_parse_bool,
DHCPv4.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
DHCPv4.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast)
DHCPv4.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0
DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
DHCPv4.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class)
DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid)

View File

@ -640,6 +640,7 @@ static Network *network_free(Network *network) {
free(network->description);
free(network->dhcp_vendor_class_identifier);
free(network->dhcp_mudurl);
strv_free(network->dhcp_user_class);
free(network->dhcp_hostname);
set_free(network->dhcp_black_listed_ip);

View File

@ -91,6 +91,7 @@ struct Network {
AddressFamily dhcp;
DHCPClientIdentifier dhcp_client_identifier;
char *dhcp_vendor_class_identifier;
char *dhcp_mudurl;
char **dhcp_user_class;
char *dhcp_hostname;
uint64_t dhcp_max_attempts;

View File

@ -8,6 +8,7 @@
#include "acl-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "missing_magic.h"
#include "nspawn-def.h"
@ -335,12 +336,11 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
donate_fd = true;
}
d = fdopendir(fd);
d = take_fdopendir(&fd);
if (!d) {
r = -errno;
goto finish;
}
fd = -1;
FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
struct stat fst;

View File

@ -118,10 +118,9 @@ int change_uid_gid(const char *user, char **_home) {
if (fd < 0)
return fd;
f = fdopen(fd, "r");
f = take_fdopen(&fd, "r");
if (!f)
return log_oom();
fd = -1;
r = read_line(f, LONG_LINE_MAX, &line);
if (r == 0)
@ -191,10 +190,9 @@ int change_uid_gid(const char *user, char **_home) {
if (fd < 0)
return fd;
f = fdopen(fd, "r");
f = take_fdopen(&fd, "r");
if (!f)
return log_oom();
fd = -1;
r = read_line(f, LONG_LINE_MAX, &line);
if (r == 0)

View File

@ -1092,10 +1092,9 @@ static int test_chroot_dropin(
return log_debug_errno(errno, "Failed to open %s/%s: %m", where, p);
}
r = fdopen_unlocked(fd, "r", &f);
r = take_fdopen_unlocked(&fd, "r", &f);
if (r < 0)
return log_debug_errno(r, "Failed to convert file handle: %m");
TAKE_FD(fd);
r = read_line(f, LONG_LINE_MAX, &line);
if (r < 0)

View File

@ -79,12 +79,10 @@ static int append_fd(sd_bus_message *m, PortableMetadata *d) {
assert(d);
assert(d->fd >= 0);
f = fdopen(d->fd, "r");
f = take_fdopen(&d->fd, "r");
if (!f)
return -errno;
d->fd = -1;
r = read_full_stream(f, &buf, &n);
if (r < 0)
return r;

View File

@ -791,14 +791,12 @@ int ask_password_agent(
(void) fchmod(fd, 0644);
f = fdopen(fd, "w");
f = take_fdopen(&fd, "w");
if (!f) {
r = -errno;
goto finish;
}
fd = -1;
signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (signal_fd < 0) {
r = -errno;

View File

@ -1541,14 +1541,12 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
fds[2*k+1] = safe_close(fds[2*k+1]);
f = fdopen(fds[2*k], "r");
f = take_fdopen(&fds[2*k], "r");
if (!f) {
r = -errno;
goto finish;
}
fds[2*k] = -1;
switch (k) {
case META_HOSTNAME:

View File

@ -1280,10 +1280,9 @@ static int unit_file_load(
if (r < 0)
return r;
f = fdopen(fd, "r");
f = take_fdopen(&fd, "r");
if (!f)
return -errno;
fd = -1;
/* c is only needed if we actually load the file (it's referenced from items[] btw, in case you wonder.) */
assert(c);

View File

@ -3,6 +3,7 @@
#include "alloc-util.h"
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "macro.h"
#include "os-util.h"
@ -76,10 +77,9 @@ int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) {
if (r < 0)
return r;
f = fdopen(fd, "r");
f = take_fdopen(&fd, "r");
if (!f)
return -errno;
fd = -1;
*ret_file = f;

View File

@ -92,6 +92,7 @@ enum {
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_MUD_URL = 161,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,
@ -171,6 +172,9 @@ int sd_dhcp_client_set_hostname(
int sd_dhcp_client_set_vendor_class_identifier(
sd_dhcp_client *client,
const char *vci);
int sd_dhcp_client_set_mud_url(
sd_dhcp_client *client,
const char *mudurl);
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const *user_class);

View File

@ -102,6 +102,7 @@ IPServiceType=
SendOption=
SendVendorOption=
SendDecline=
MUDURL=
RouteMTUBytes=
[DHCPv6]
UseNTP=