mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 12:34:55 +00:00
systemd: merge branch systemd into master
Systemd instroduces a macro _fallthrough_, see https://github.com/systemd/systemd/pull/7389. However, it does not yet seem conclusive how to handle this properly in ever situation. While shared/nm-utils/siphash24.c makes use of the new macro, don't do that in our fork. siphash24.h does not include all systemd headers, hence _fallthrough_ is not defined. We could re-implement it as _nm_fallthrough, but given the open questions, that doesn't seem the
This commit is contained in:
commit
8c0dfd7188
|
@ -1204,14 +1204,17 @@ src_libsystemd_nm_la_SOURCES = \
|
|||
src/systemd/sd-adapt/condition.h \
|
||||
src/systemd/sd-adapt/conf-parser.h \
|
||||
src/systemd/sd-adapt/def.h \
|
||||
src/systemd/sd-adapt/device-nodes.h \
|
||||
src/systemd/sd-adapt/dirent-util.h \
|
||||
src/systemd/sd-adapt/env-util.h \
|
||||
src/systemd/sd-adapt/errno-list.h \
|
||||
src/systemd/sd-adapt/format-util.h \
|
||||
src/systemd/sd-adapt/glob-util.h \
|
||||
src/systemd/sd-adapt/gunicode.h \
|
||||
src/systemd/sd-adapt/ioprio.h \
|
||||
src/systemd/sd-adapt/khash.h \
|
||||
src/systemd/sd-adapt/libudev.h \
|
||||
src/systemd/sd-adapt/memfd-util.h \
|
||||
src/systemd/sd-adapt/missing.h \
|
||||
src/systemd/sd-adapt/mkdir.h \
|
||||
src/systemd/sd-adapt/raw-clone.h \
|
||||
|
@ -1221,7 +1224,6 @@ src_libsystemd_nm_la_SOURCES = \
|
|||
src/systemd/sd-adapt/udev.h \
|
||||
src/systemd/sd-adapt/user-util.h \
|
||||
src/systemd/sd-adapt/virt.h \
|
||||
src/systemd/sd-adapt/glob-util.h \
|
||||
src/systemd/src/basic/alloc-util.c \
|
||||
src/systemd/src/basic/alloc-util.h \
|
||||
src/systemd/src/basic/async.h \
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#define assert(cond) nm_assert (cond)
|
||||
#define assert(cond) nm_assert (cond)
|
||||
#define _fallthrough_ _nm_fallthrough
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -130,25 +131,25 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
|
|||
switch (left) {
|
||||
case 7:
|
||||
state->padding |= ((uint64_t) in[6]) << 48;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 6:
|
||||
state->padding |= ((uint64_t) in[5]) << 40;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 5:
|
||||
state->padding |= ((uint64_t) in[4]) << 32;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 4:
|
||||
state->padding |= ((uint64_t) in[3]) << 24;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 3:
|
||||
state->padding |= ((uint64_t) in[2]) << 16;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 2:
|
||||
state->padding |= ((uint64_t) in[1]) << 8;
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 1:
|
||||
state->padding |= ((uint64_t) in[0]);
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -85,7 +85,7 @@ test_arping_common (test_fixture *fixture, TestInfo *info)
|
|||
loop = g_main_loop_new (NULL, FALSE);
|
||||
g_signal_connect (manager, NM_ARPING_MANAGER_PROBE_TERMINATED,
|
||||
G_CALLBACK (arping_manager_probe_terminated), loop);
|
||||
g_assert (nm_arping_manager_start_probe (manager, 250, NULL));
|
||||
g_assert (nm_arping_manager_start_probe (manager, 100, NULL));
|
||||
g_assert (nmtst_main_loop_run (loop, 2000));
|
||||
|
||||
for (i = 0; info->addresses[i]; i++) {
|
||||
|
|
3
src/systemd/sd-adapt/device-nodes.h
Normal file
3
src/systemd/sd-adapt/device-nodes.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
3
src/systemd/sd-adapt/memfd-util.h
Normal file
3
src/systemd/sd-adapt/memfd-util.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
/* dummy header */
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -39,7 +40,7 @@ void* memdup(const void *p, size_t l) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void* memdup_suffix0(const void*p, size_t l) {
|
||||
void* memdup_suffix0(const void *p, size_t l) {
|
||||
void *ret;
|
||||
|
||||
assert(l == 0 || p);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -54,7 +55,7 @@ static inline void *mfree(void *memory) {
|
|||
})
|
||||
|
||||
void* memdup(const void *p, size_t l) _alloc_(2);
|
||||
void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
|
||||
void* memdup_suffix0(const void *p, size_t l) _alloc_(2);
|
||||
|
||||
static inline void freep(void *p) {
|
||||
free(*(void**) p);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -72,7 +73,7 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
|
|||
if (s[pos] == '\0') \
|
||||
break; \
|
||||
hexoff = strchr(hex, s[pos]); \
|
||||
if (hexoff == NULL) \
|
||||
if (!hexoff) \
|
||||
break; \
|
||||
assert(hexoff >= hex); \
|
||||
x = hexoff - hex; \
|
||||
|
@ -100,7 +101,7 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
|
|||
sep = s[strspn(s, hex)];
|
||||
if (sep == '\n')
|
||||
return -EINVAL;
|
||||
if (strchr(":.-", sep) == NULL)
|
||||
if (!strchr(":.-", sep))
|
||||
return -EINVAL;
|
||||
|
||||
if (sep == '.') {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -28,8 +29,10 @@
|
|||
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "macro.h"
|
||||
#include "memfd-util.h"
|
||||
#include "missing.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
|
@ -381,3 +384,204 @@ int fd_get_path(int fd, char **ret) {
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int move_fd(int from, int to, int cloexec) {
|
||||
int r;
|
||||
|
||||
/* Move fd 'from' to 'to', make sure FD_CLOEXEC remains equal if requested, and release the old fd. If
|
||||
* 'cloexec' is passed as -1, the original FD_CLOEXEC is inherited for the new fd. If it is 0, it is turned
|
||||
* off, if it is > 0 it is turned on. */
|
||||
|
||||
if (from < 0)
|
||||
return -EBADF;
|
||||
if (to < 0)
|
||||
return -EBADF;
|
||||
|
||||
if (from == to) {
|
||||
|
||||
if (cloexec >= 0) {
|
||||
r = fd_cloexec(to, cloexec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
if (cloexec < 0) {
|
||||
int fl;
|
||||
|
||||
fl = fcntl(from, F_GETFD, 0);
|
||||
if (fl < 0)
|
||||
return -errno;
|
||||
|
||||
cloexec = !!(fl & FD_CLOEXEC);
|
||||
}
|
||||
|
||||
r = dup3(from, to, cloexec ? O_CLOEXEC : 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
assert(r == to);
|
||||
|
||||
safe_close(from);
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
int acquire_data_fd(const void *data, size_t size, unsigned flags) {
|
||||
|
||||
char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
||||
_cleanup_close_pair_ int pipefds[2] = { -1, -1 };
|
||||
char pattern[] = "/dev/shm/data-fd-XXXXXX";
|
||||
_cleanup_close_ int fd = -1;
|
||||
int isz = 0, r;
|
||||
ssize_t n;
|
||||
off_t f;
|
||||
|
||||
assert(data || size == 0);
|
||||
|
||||
/* Acquire a read-only file descriptor that when read from returns the specified data. This is much more
|
||||
* complex than I wish it was. But here's why:
|
||||
*
|
||||
* a) First we try to use memfds. They are the best option, as we can seal them nicely to make them
|
||||
* read-only. Unfortunately they require kernel 3.17, and – at the time of writing – we still support 3.14.
|
||||
*
|
||||
* b) Then, we try classic pipes. They are the second best options, as we can close the writing side, retaining
|
||||
* a nicely read-only fd in the reading side. However, they are by default quite small, and unprivileged
|
||||
* clients can only bump their size to a system-wide limit, which might be quite low.
|
||||
*
|
||||
* c) Then, we try an O_TMPFILE file in /dev/shm (that dir is the only suitable one known to exist from
|
||||
* earliest boot on). To make it read-only we open the fd a second time with O_RDONLY via
|
||||
* /proc/self/<fd>. Unfortunately O_TMPFILE is not available on older kernels on tmpfs.
|
||||
*
|
||||
* d) Finally, we try creating a regular file in /dev/shm, which we then delete.
|
||||
*
|
||||
* It sucks a bit that depending on the situation we return very different objects here, but that's Linux I
|
||||
* figure. */
|
||||
|
||||
if (size == 0 && ((flags & ACQUIRE_NO_DEV_NULL) == 0)) {
|
||||
/* As a special case, return /dev/null if we have been called for an empty data block */
|
||||
r = open("/dev/null", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((flags & ACQUIRE_NO_MEMFD) == 0) {
|
||||
fd = memfd_new("data-fd");
|
||||
if (fd < 0)
|
||||
goto try_pipe;
|
||||
|
||||
n = write(fd, data, size);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if ((size_t) n != size)
|
||||
return -EIO;
|
||||
|
||||
f = lseek(fd, 0, SEEK_SET);
|
||||
if (f != 0)
|
||||
return -errno;
|
||||
|
||||
r = memfd_set_sealed(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = fd;
|
||||
fd = -1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
try_pipe:
|
||||
if ((flags & ACQUIRE_NO_PIPE) == 0) {
|
||||
if (pipe2(pipefds, O_CLOEXEC|O_NONBLOCK) < 0)
|
||||
return -errno;
|
||||
|
||||
isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
|
||||
if (isz < 0)
|
||||
return -errno;
|
||||
|
||||
if ((size_t) isz < size) {
|
||||
isz = (int) size;
|
||||
if (isz < 0 || (size_t) isz != size)
|
||||
return -E2BIG;
|
||||
|
||||
/* Try to bump the pipe size */
|
||||
(void) fcntl(pipefds[1], F_SETPIPE_SZ, isz);
|
||||
|
||||
/* See if that worked */
|
||||
isz = fcntl(pipefds[1], F_GETPIPE_SZ, 0);
|
||||
if (isz < 0)
|
||||
return -errno;
|
||||
|
||||
if ((size_t) isz < size)
|
||||
goto try_dev_shm;
|
||||
}
|
||||
|
||||
n = write(pipefds[1], data, size);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if ((size_t) n != size)
|
||||
return -EIO;
|
||||
|
||||
(void) fd_nonblock(pipefds[0], false);
|
||||
|
||||
r = pipefds[0];
|
||||
pipefds[0] = -1;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
try_dev_shm:
|
||||
if ((flags & ACQUIRE_NO_TMPFILE) == 0) {
|
||||
fd = open("/dev/shm", O_RDWR|O_TMPFILE|O_CLOEXEC, 0500);
|
||||
if (fd < 0)
|
||||
goto try_dev_shm_without_o_tmpfile;
|
||||
|
||||
n = write(fd, data, size);
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
if ((size_t) n != size)
|
||||
return -EIO;
|
||||
|
||||
/* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
|
||||
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
|
||||
r = open(procfs_path, O_RDONLY|O_CLOEXEC);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
try_dev_shm_without_o_tmpfile:
|
||||
if ((flags & ACQUIRE_NO_REGULAR) == 0) {
|
||||
fd = mkostemp_safe(pattern);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
n = write(fd, data, size);
|
||||
if (n < 0) {
|
||||
r = -errno;
|
||||
goto unlink_and_return;
|
||||
}
|
||||
if ((size_t) n != size) {
|
||||
r = -EIO;
|
||||
goto unlink_and_return;
|
||||
}
|
||||
|
||||
/* Let's reopen the thing, in order to get an O_RDONLY fd for the original O_RDWR one */
|
||||
r = open(pattern, O_RDONLY|O_CLOEXEC);
|
||||
if (r < 0)
|
||||
r = -errno;
|
||||
|
||||
unlink_and_return:
|
||||
(void) unlink(pattern);
|
||||
return r;
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -75,6 +76,18 @@ bool fdname_is_valid(const char *s);
|
|||
|
||||
int fd_get_path(int fd, char **ret);
|
||||
|
||||
int move_fd(int from, int to, int cloexec);
|
||||
|
||||
enum {
|
||||
ACQUIRE_NO_DEV_NULL = 1 << 0,
|
||||
ACQUIRE_NO_MEMFD = 1 << 1,
|
||||
ACQUIRE_NO_PIPE = 1 << 2,
|
||||
ACQUIRE_NO_TMPFILE = 1 << 3,
|
||||
ACQUIRE_NO_REGULAR = 1 << 4,
|
||||
};
|
||||
|
||||
int acquire_data_fd(const void *data, size_t size, unsigned flags);
|
||||
|
||||
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
|
||||
#define ERRNO_IS_DISCONNECT(r) \
|
||||
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
@ -141,7 +143,7 @@ int write_string_file_ts(
|
|||
|
||||
return r;
|
||||
} else
|
||||
assert(ts == NULL);
|
||||
assert(!ts);
|
||||
|
||||
if (flags & WRITE_STRING_FILE_CREATE) {
|
||||
f = fopen(fn, "we");
|
||||
|
@ -1197,7 +1199,7 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
|
|||
if (!filename_is_valid(fn))
|
||||
return -EINVAL;
|
||||
|
||||
if (extra == NULL)
|
||||
if (!extra)
|
||||
extra = "";
|
||||
|
||||
t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -29,11 +30,16 @@
|
|||
#include "time-util.h"
|
||||
|
||||
typedef enum {
|
||||
WRITE_STRING_FILE_CREATE = 1<<0,
|
||||
WRITE_STRING_FILE_ATOMIC = 1<<1,
|
||||
WRITE_STRING_FILE_AVOID_NEWLINE = 1<<2,
|
||||
WRITE_STRING_FILE_CREATE = 1<<0,
|
||||
WRITE_STRING_FILE_ATOMIC = 1<<1,
|
||||
WRITE_STRING_FILE_AVOID_NEWLINE = 1<<2,
|
||||
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1<<3,
|
||||
WRITE_STRING_FILE_SYNC = 1<<4,
|
||||
WRITE_STRING_FILE_SYNC = 1<<4,
|
||||
|
||||
/* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one
|
||||
more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file()
|
||||
and friends. */
|
||||
|
||||
} WriteStringFileFlags;
|
||||
|
||||
int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, struct timespec *ts);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -107,7 +108,6 @@ int rmdir_parents(const char *path, const char *stop) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
@ -516,7 +516,7 @@ static int getenv_tmp_dir(const char **ret_path) {
|
|||
r = -ENOTDIR;
|
||||
goto next;
|
||||
}
|
||||
if (!path_is_safe(e)) {
|
||||
if (!path_is_normalized(e)) {
|
||||
r = -EPERM;
|
||||
goto next;
|
||||
}
|
||||
|
@ -628,10 +628,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
* Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
|
||||
* as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
|
||||
* function what to do when encountering a symlink with an absolute path as directory: prefix it by the
|
||||
* specified path.
|
||||
*
|
||||
* Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
|
||||
* passed root. */
|
||||
* specified path. */
|
||||
|
||||
if (original_root) {
|
||||
r = path_make_absolute_cwd(original_root, &root);
|
||||
|
@ -668,10 +665,19 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
|
||||
todo += m;
|
||||
|
||||
/* Just a single slash? Then we reached the end. */
|
||||
if (isempty(first) || path_equal(first, "/"))
|
||||
/* Empty? Then we reached the end. */
|
||||
if (isempty(first))
|
||||
break;
|
||||
|
||||
/* Just a single slash? Then we reached the end. */
|
||||
if (path_equal(first, "/")) {
|
||||
/* Preserve the trailing slash */
|
||||
if (!strextend(&done, "/", NULL))
|
||||
return -ENOMEM;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Just a dot? Then let's eat this up. */
|
||||
if (path_equal(first, "/."))
|
||||
continue;
|
||||
|
@ -714,12 +720,16 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
|
||||
if (errno == ENOENT &&
|
||||
(flags & CHASE_NONEXISTENT) &&
|
||||
(isempty(todo) || path_is_safe(todo))) {
|
||||
(isempty(todo) || path_is_normalized(todo))) {
|
||||
|
||||
/* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
|
||||
* what we got so far. But don't allow this if the remaining path contains "../ or "./"
|
||||
* or something else weird. */
|
||||
|
||||
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
|
||||
if (streq_ptr(done, "/"))
|
||||
*done = '\0';
|
||||
|
||||
if (!strextend(&done, first, todo, NULL))
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -733,7 +743,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
if (fstat(child, &st) < 0)
|
||||
return -errno;
|
||||
if ((flags & CHASE_NO_AUTOFS) &&
|
||||
fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
|
||||
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
|
||||
return -EREMOTE;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
|
@ -792,6 +802,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
done = first;
|
||||
first = NULL;
|
||||
} else {
|
||||
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
|
||||
if (streq(done, "/"))
|
||||
*done = '\0';
|
||||
|
||||
if (!strextend(&done, first, NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -816,4 +830,19 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||
|
||||
return exists;
|
||||
}
|
||||
|
||||
int access_fd(int fd, int mode) {
|
||||
char p[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
|
||||
int r;
|
||||
|
||||
/* Like access() but operates on an already open fd */
|
||||
|
||||
xsprintf(p, "/proc/self/fd/%i", fd);
|
||||
|
||||
r = access(p, mode);
|
||||
if (r < 0)
|
||||
r = -errno;
|
||||
|
||||
return r;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -98,3 +99,5 @@ static inline void unlink_and_free(char *p) {
|
|||
free(p);
|
||||
}
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||
|
||||
int access_fd(int fd, int mode);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -328,6 +329,29 @@ static inline void *ordered_hashmap_first(OrderedHashmap *h) {
|
|||
return internal_hashmap_first(HASHMAP_BASE(h));
|
||||
}
|
||||
|
||||
#define hashmap_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
void *_item; \
|
||||
while ((_item = hashmap_steal_first(_s))) \
|
||||
_f(_item); \
|
||||
})
|
||||
#define hashmap_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
hashmap_clear_with_destructor(_s, _f); \
|
||||
hashmap_free(_s); \
|
||||
})
|
||||
#define ordered_hashmap_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
void *_item; \
|
||||
while ((_item = ordered_hashmap_steal_first(_s))) \
|
||||
_f(_item); \
|
||||
})
|
||||
#define ordered_hashmap_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
ordered_hashmap_clear_with_destructor(_s, _f); \
|
||||
ordered_hashmap_free(_s); \
|
||||
})
|
||||
|
||||
/* no hashmap_next */
|
||||
void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -98,7 +99,10 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
|
|||
|
||||
assert(mem);
|
||||
assert(len);
|
||||
assert(p);
|
||||
assert(p || l == 0);
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
if (l % 2 != 0)
|
||||
return -EINVAL;
|
||||
|
@ -130,6 +134,7 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
/* https://tools.ietf.org/html/rfc4648#section-6
|
||||
* Notice that base32hex differs from base32 in the alphabet it uses.
|
||||
* The distinction is that the base32hex representation preserves the
|
||||
|
@ -162,6 +167,8 @@ char *base32hexmem(const void *p, size_t l, bool padding) {
|
|||
const uint8_t *x;
|
||||
size_t len;
|
||||
|
||||
assert(p || l == 0);
|
||||
|
||||
if (padding)
|
||||
/* five input bytes makes eight output bytes, padding is added so we must round up */
|
||||
len = 8 * (l + 4) / 5;
|
||||
|
@ -271,7 +278,12 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
|
|||
size_t len;
|
||||
unsigned pad = 0;
|
||||
|
||||
assert(p);
|
||||
assert(p || l == 0);
|
||||
assert(mem);
|
||||
assert(_len);
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
/* padding ensures any base32hex input has input divisible by 8 */
|
||||
if (padding && l % 8 != 0)
|
||||
|
@ -521,6 +533,9 @@ ssize_t base64mem(const void *p, size_t l, char **out) {
|
|||
char *r, *z;
|
||||
const uint8_t *x;
|
||||
|
||||
assert(p || l == 0);
|
||||
assert(out);
|
||||
|
||||
/* three input bytes makes four output bytes, padding is added so we must round up */
|
||||
z = r = malloc(4 * (l + 2) / 3 + 1);
|
||||
if (!r)
|
||||
|
@ -556,10 +571,11 @@ ssize_t base64mem(const void *p, size_t l, char **out) {
|
|||
return z - r;
|
||||
}
|
||||
|
||||
static int base64_append_width(char **prefix, int plen,
|
||||
const char *sep, int indent,
|
||||
const void *p, size_t l,
|
||||
int width) {
|
||||
static int base64_append_width(
|
||||
char **prefix, int plen,
|
||||
const char *sep, int indent,
|
||||
const void *p, size_t l,
|
||||
int width) {
|
||||
|
||||
_cleanup_free_ char *x = NULL;
|
||||
char *t, *s;
|
||||
|
@ -598,118 +614,148 @@ static int base64_append_width(char **prefix, int plen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int base64_append(char **prefix, int plen,
|
||||
const void *p, size_t l,
|
||||
int indent, int width) {
|
||||
int base64_append(
|
||||
char **prefix, int plen,
|
||||
const void *p, size_t l,
|
||||
int indent, int width) {
|
||||
|
||||
if (plen > width / 2 || plen + indent > width)
|
||||
/* leave indent on the left, keep last column free */
|
||||
return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1);
|
||||
else
|
||||
/* leave plen on the left, keep last column free */
|
||||
return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
|
||||
_cleanup_free_ uint8_t *r = NULL;
|
||||
int a, b, c, d;
|
||||
uint8_t *z;
|
||||
const char *x;
|
||||
size_t len;
|
||||
static int unbase64_next(const char **p, size_t *l) {
|
||||
int ret;
|
||||
|
||||
assert(p);
|
||||
assert(l);
|
||||
|
||||
/* padding ensures any base63 input has input divisible by 4 */
|
||||
if (l % 4 != 0)
|
||||
return -EINVAL;
|
||||
/* Find the next non-whitespace character, and decode it. If we find padding, we return it as INT_MAX. We
|
||||
* greedily skip all preceeding and all following whitespace. */
|
||||
|
||||
/* strip the padding */
|
||||
if (l > 0 && p[l - 1] == '=')
|
||||
l--;
|
||||
if (l > 0 && p[l - 1] == '=')
|
||||
l--;
|
||||
for (;;) {
|
||||
if (*l == 0)
|
||||
return -EPIPE;
|
||||
|
||||
/* a group of four input bytes needs three output bytes, in case of
|
||||
padding we need to add two or three extra bytes */
|
||||
len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
|
||||
if (!strchr(WHITESPACE, **p))
|
||||
break;
|
||||
|
||||
z = r = malloc(len + 1);
|
||||
if (!r)
|
||||
/* Skip leading whitespace */
|
||||
(*p)++, (*l)--;
|
||||
}
|
||||
|
||||
if (**p == '=')
|
||||
ret = INT_MAX; /* return padding as INT_MAX */
|
||||
else {
|
||||
ret = unbase64char(**p);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
(*p)++, (*l)--;
|
||||
|
||||
if (*l == 0)
|
||||
break;
|
||||
if (!strchr(WHITESPACE, **p))
|
||||
break;
|
||||
|
||||
/* Skip following whitespace */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
|
||||
_cleanup_free_ uint8_t *buf = NULL;
|
||||
const char *x;
|
||||
uint8_t *z;
|
||||
size_t len;
|
||||
|
||||
assert(p || l == 0);
|
||||
assert(ret);
|
||||
assert(ret_size);
|
||||
|
||||
if (l == (size_t) -1)
|
||||
l = strlen(p);
|
||||
|
||||
/* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
|
||||
bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
|
||||
len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
|
||||
|
||||
buf = malloc(len + 1);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
for (x = p; x < p + (l / 4) * 4; x += 4) {
|
||||
/* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
|
||||
a = unbase64char(x[0]);
|
||||
for (x = p, z = buf;;) {
|
||||
int a, b, c, d; /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
|
||||
|
||||
a = unbase64_next(&x, &l);
|
||||
if (a == -EPIPE) /* End of string */
|
||||
break;
|
||||
if (a < 0)
|
||||
return a;
|
||||
if (a == INT_MAX) /* Padding is not allowed at the beginning of a 4ch block */
|
||||
return -EINVAL;
|
||||
|
||||
b = unbase64char(x[1]);
|
||||
b = unbase64_next(&x, &l);
|
||||
if (b < 0)
|
||||
return b;
|
||||
if (b == INT_MAX) /* Padding is not allowed at the second character of a 4ch block either */
|
||||
return -EINVAL;
|
||||
|
||||
c = unbase64char(x[2]);
|
||||
c = unbase64_next(&x, &l);
|
||||
if (c < 0)
|
||||
return -EINVAL;
|
||||
return c;
|
||||
|
||||
d = unbase64char(x[3]);
|
||||
d = unbase64_next(&x, &l);
|
||||
if (d < 0)
|
||||
return -EINVAL;
|
||||
return d;
|
||||
|
||||
if (c == INT_MAX) { /* Padding at the third character */
|
||||
|
||||
if (d != INT_MAX) /* If the third character is padding, the fourth must be too */
|
||||
return -EINVAL;
|
||||
|
||||
/* b == 00YY0000 */
|
||||
if (b & 15)
|
||||
return -EINVAL;
|
||||
|
||||
if (l > 0) /* Trailing rubbish? */
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
||||
break;
|
||||
}
|
||||
|
||||
if (d == INT_MAX) {
|
||||
/* c == 00ZZZZ00 */
|
||||
if (c & 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (l > 0) /* Trailing rubbish? */
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
break;
|
||||
}
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
*(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
|
||||
}
|
||||
|
||||
switch (l % 4) {
|
||||
case 3:
|
||||
a = unbase64char(x[0]);
|
||||
if (a < 0)
|
||||
return -EINVAL;
|
||||
|
||||
b = unbase64char(x[1]);
|
||||
if (b < 0)
|
||||
return -EINVAL;
|
||||
|
||||
c = unbase64char(x[2]);
|
||||
if (c < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* c == 00ZZZZ00 */
|
||||
if (c & 3)
|
||||
return -EINVAL;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
|
||||
*(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
|
||||
|
||||
break;
|
||||
case 2:
|
||||
a = unbase64char(x[0]);
|
||||
if (a < 0)
|
||||
return -EINVAL;
|
||||
|
||||
b = unbase64char(x[1]);
|
||||
if (b < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* b == 00YY0000 */
|
||||
if (b & 15)
|
||||
return -EINVAL;
|
||||
|
||||
*(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
|
||||
|
||||
break;
|
||||
case 0:
|
||||
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*z = 0;
|
||||
|
||||
*mem = r;
|
||||
r = NULL;
|
||||
*_len = len;
|
||||
if (ret_size)
|
||||
*ret_size = (size_t) (z - buf);
|
||||
|
||||
*ret = buf;
|
||||
buf = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -718,7 +764,10 @@ void hexdump(FILE *f, const void *p, size_t s) {
|
|||
const uint8_t *b = p;
|
||||
unsigned n = 0;
|
||||
|
||||
assert(s == 0 || b);
|
||||
assert(b || s == 0);
|
||||
|
||||
if (!f)
|
||||
f = stdout;
|
||||
|
||||
while (s > 0) {
|
||||
size_t i;
|
||||
|
@ -756,3 +805,4 @@ void hexdump(FILE *f, const void *p, size_t s) {
|
|||
s -= 16;
|
||||
}
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -26,12 +27,15 @@
|
|||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "def.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hostname-util.h"
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
bool hostname_is_set(void) {
|
||||
struct utsname u;
|
||||
|
||||
|
@ -47,7 +51,6 @@ bool hostname_is_set(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
char* gethostname_malloc(void) {
|
||||
struct utsname u;
|
||||
|
||||
|
@ -223,36 +226,56 @@ int sethostname_idempotent(const char *s) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int read_hostname_config(const char *path, char **hostname) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
char l[LINE_MAX];
|
||||
char *name = NULL;
|
||||
int read_etc_hostname_stream(FILE *f, char **ret) {
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(hostname);
|
||||
assert(f);
|
||||
assert(ret);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
char *p;
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) /* EOF without any hostname? the file is empty, let's treat that exactly like no file at all: ENOENT */
|
||||
return -ENOENT;
|
||||
|
||||
p = strstrip(line);
|
||||
|
||||
/* File may have empty lines or comments, ignore them */
|
||||
if (!IN_SET(*p, '\0', '#')) {
|
||||
char *copy;
|
||||
|
||||
hostname_cleanup(p); /* normalize the hostname */
|
||||
|
||||
if (!hostname_is_valid(p, true)) /* check that the hostname we return is valid */
|
||||
return -EBADMSG;
|
||||
|
||||
copy = strdup(p);
|
||||
if (!copy)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = copy;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int read_etc_hostname(const char *path, char **ret) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!path)
|
||||
path = "/etc/hostname";
|
||||
|
||||
f = fopen(path, "re");
|
||||
if (!f)
|
||||
return -errno;
|
||||
|
||||
/* may have comments, ignore them */
|
||||
FOREACH_LINE(l, f, return -errno) {
|
||||
truncate_nl(l);
|
||||
if (!IN_SET(l[0], '\0', '#')) {
|
||||
/* found line with value */
|
||||
name = hostname_cleanup(l);
|
||||
name = strdup(name);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return read_etc_hostname_stream(f, ret);
|
||||
|
||||
if (!name)
|
||||
/* no non-empty line found */
|
||||
return -ENOENT;
|
||||
|
||||
*hostname = name;
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -38,4 +39,5 @@ bool is_gateway_hostname(const char *hostname);
|
|||
|
||||
int sethostname_idempotent(const char *s);
|
||||
|
||||
int read_hostname_config(const char *path, char **hostname);
|
||||
int read_etc_hostname_stream(FILE *f, char **ret);
|
||||
int read_etc_hostname(const char *path, char **ret);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -201,7 +202,6 @@ int fd_wait_for_event(int fd, int event, usec_t t) {
|
|||
r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -182,3 +183,6 @@
|
|||
for ((i) = (p)->name##_next ? (p)->name##_next : (head); \
|
||||
(i) != (p); \
|
||||
(i) = (i)->name##_next ? (i)->name##_next : (head))
|
||||
|
||||
#define LIST_IS_EMPTY(head) \
|
||||
(!(head))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -185,8 +186,8 @@ int log_oom_internal(
|
|||
|
||||
int log_format_iovec(
|
||||
struct iovec *iovec,
|
||||
unsigned iovec_len,
|
||||
unsigned *n,
|
||||
size_t iovec_len,
|
||||
size_t *n,
|
||||
bool newline_separator,
|
||||
int error,
|
||||
const char *format,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -47,6 +48,11 @@
|
|||
#define _weakref_(x) __attribute__((weakref(#x)))
|
||||
#define _alignas_(x) __attribute__((aligned(__alignof(x))))
|
||||
#define _cleanup_(x) __attribute__((cleanup(x)))
|
||||
#if __GNUC__ >= 7
|
||||
#define _fallthrough_ __attribute__((fallthrough))
|
||||
#else
|
||||
#define _fallthrough_
|
||||
#endif
|
||||
|
||||
#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined (__clang__)
|
||||
/* Temporarily disable some warnings */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -225,8 +226,8 @@ int path_strv_make_absolute_cwd(char **l) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
free(*s);
|
||||
*s = t;
|
||||
path_kill_slashes(t);
|
||||
free_and_replace(*s, t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -542,7 +543,7 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
|
|||
|
||||
assert(timestamp);
|
||||
|
||||
if (paths == NULL)
|
||||
if (!paths)
|
||||
return false;
|
||||
|
||||
STRV_FOREACH(i, paths) {
|
||||
|
@ -706,6 +707,37 @@ char* dirname_malloc(const char *path) {
|
|||
|
||||
return dir2;
|
||||
}
|
||||
|
||||
const char *last_path_component(const char *path) {
|
||||
/* Finds the last component of the path, preserving the
|
||||
* optional trailing slash that signifies a directory.
|
||||
* a/b/c → c
|
||||
* a/b/c/ → c/
|
||||
* / → /
|
||||
* // → /
|
||||
* /foo/a → a
|
||||
* /foo/a/ → a/
|
||||
* This is different than basename, which returns "" when
|
||||
* a trailing slash is present.
|
||||
*/
|
||||
|
||||
unsigned l, k;
|
||||
|
||||
l = k = strlen(path);
|
||||
if (l == 0) /* special case — an empty string */
|
||||
return path;
|
||||
|
||||
while (k > 0 && path[k-1] == '/')
|
||||
k--;
|
||||
|
||||
if (k == 0) /* the root directory */
|
||||
return path + l - 1;
|
||||
|
||||
while (k > 0 && path[k-1] != '/')
|
||||
k--;
|
||||
|
||||
return path + k;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
bool filename_is_valid(const char *p) {
|
||||
|
@ -728,7 +760,7 @@ bool filename_is_valid(const char *p) {
|
|||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
bool path_is_safe(const char *p) {
|
||||
bool path_is_normalized(const char *p) {
|
||||
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
@ -742,7 +774,6 @@ bool path_is_safe(const char *p) {
|
|||
if (strlen(p)+1 > PATH_MAX)
|
||||
return false;
|
||||
|
||||
/* The following two checks are not really dangerous, but hey, they still are confusing */
|
||||
if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
|
||||
return false;
|
||||
|
||||
|
@ -858,7 +889,9 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
|
|||
* for Gentoo which does a merge without making /lib a symlink.
|
||||
*/
|
||||
"lib/systemd/libsystemd-shared-*.so\0"
|
||||
"usr/lib/systemd/libsystemd-shared-*.so\0") {
|
||||
"lib64/systemd/libsystemd-shared-*.so\0"
|
||||
"usr/lib/systemd/libsystemd-shared-*.so\0"
|
||||
"usr/lib64/systemd/libsystemd-shared-*.so\0") {
|
||||
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
_cleanup_free_ char *path = NULL;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -131,9 +132,10 @@ char *prefix_root(const char *root, const char *path);
|
|||
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg);
|
||||
|
||||
char* dirname_malloc(const char *path);
|
||||
const char *last_path_component(const char *path);
|
||||
|
||||
bool filename_is_valid(const char *p) _pure_;
|
||||
bool path_is_safe(const char *p) _pure_;
|
||||
bool path_is_normalized(const char *p) _pure_;
|
||||
|
||||
char *file_in_same_dir(const char *path, const char *filename);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -139,3 +140,5 @@ static inline bool pid_is_valid(pid_t p) {
|
|||
int ioprio_parse_priority(const char *s, int *ret);
|
||||
|
||||
pid_t getpid_cached(void);
|
||||
|
||||
int must_be_root(void);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -107,6 +108,18 @@ static inline void *set_steal_first(Set *s) {
|
|||
return internal_hashmap_steal_first(HASHMAP_BASE(s));
|
||||
}
|
||||
|
||||
#define set_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
void *_item; \
|
||||
while ((_item = set_steal_first(_s))) \
|
||||
_f(_item); \
|
||||
})
|
||||
#define set_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
set_clear_with_destructor(_s, _f); \
|
||||
set_free(_s); \
|
||||
})
|
||||
|
||||
/* no set_steal_first_key */
|
||||
/* no set_first_key */
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -44,11 +45,11 @@ static inline void block_signals_reset(sigset_t *ss) {
|
|||
assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0);
|
||||
}
|
||||
|
||||
#define BLOCK_SIGNALS(...) \
|
||||
_cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
|
||||
sigset_t t; \
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \
|
||||
t; \
|
||||
#define BLOCK_SIGNALS(...) \
|
||||
_cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
|
||||
sigset_t _t; \
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__, -1) >= 0); \
|
||||
_t; \
|
||||
})
|
||||
|
||||
static inline bool SIGNAL_VALID(int signo) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/* Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
|
||||
/* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -608,26 +609,26 @@ char* strshorten(char *s, size_t l) {
|
|||
}
|
||||
|
||||
char *strreplace(const char *text, const char *old_string, const char *new_string) {
|
||||
size_t l, old_len, new_len, allocated = 0;
|
||||
char *t, *ret = NULL;
|
||||
const char *f;
|
||||
char *t, *r;
|
||||
size_t l, old_len, new_len;
|
||||
|
||||
assert(text);
|
||||
assert(old_string);
|
||||
assert(new_string);
|
||||
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
old_len = strlen(old_string);
|
||||
new_len = strlen(new_string);
|
||||
|
||||
l = strlen(text);
|
||||
r = new(char, l+1);
|
||||
if (!r)
|
||||
if (!GREEDY_REALLOC(ret, allocated, l+1))
|
||||
return NULL;
|
||||
|
||||
f = text;
|
||||
t = r;
|
||||
t = ret;
|
||||
while (*f) {
|
||||
char *a;
|
||||
size_t d, nl;
|
||||
|
||||
if (!startswith(f, old_string)) {
|
||||
|
@ -635,25 +636,21 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
|||
continue;
|
||||
}
|
||||
|
||||
d = t - r;
|
||||
d = t - ret;
|
||||
nl = l - old_len + new_len;
|
||||
a = realloc(r, nl + 1);
|
||||
if (!a)
|
||||
goto oom;
|
||||
|
||||
if (!GREEDY_REALLOC(ret, allocated, nl + 1))
|
||||
return mfree(ret);
|
||||
|
||||
l = nl;
|
||||
r = a;
|
||||
t = r + d;
|
||||
t = ret + d;
|
||||
|
||||
t = stpcpy(t, new_string);
|
||||
f += old_len;
|
||||
}
|
||||
|
||||
*t = 0;
|
||||
return r;
|
||||
|
||||
oom:
|
||||
return mfree(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
||||
|
@ -743,16 +740,21 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
|||
return obuf;
|
||||
}
|
||||
|
||||
char *strextend(char **x, ...) {
|
||||
va_list ap;
|
||||
size_t f, l;
|
||||
#if 0 /* NM_IGNORED */
|
||||
char *strextend_with_separator(char **x, const char *separator, ...) {
|
||||
bool need_separator;
|
||||
size_t f, l, l_separator;
|
||||
char *r, *p;
|
||||
va_list ap;
|
||||
|
||||
assert(x);
|
||||
|
||||
l = f = strlen_ptr(*x);
|
||||
|
||||
va_start(ap, x);
|
||||
need_separator = !isempty(*x);
|
||||
l_separator = strlen_ptr(separator);
|
||||
|
||||
va_start(ap, separator);
|
||||
for (;;) {
|
||||
const char *t;
|
||||
size_t n;
|
||||
|
@ -762,22 +764,29 @@ char *strextend(char **x, ...) {
|
|||
break;
|
||||
|
||||
n = strlen(t);
|
||||
|
||||
if (need_separator)
|
||||
n += l_separator;
|
||||
|
||||
if (n > ((size_t) -1) - l) {
|
||||
va_end(ap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l += n;
|
||||
need_separator = true;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
need_separator = !isempty(*x);
|
||||
|
||||
r = realloc(*x, l+1);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
p = r + f;
|
||||
|
||||
va_start(ap, x);
|
||||
va_start(ap, separator);
|
||||
for (;;) {
|
||||
const char *t;
|
||||
|
||||
|
@ -785,15 +794,23 @@ char *strextend(char **x, ...) {
|
|||
if (!t)
|
||||
break;
|
||||
|
||||
if (need_separator && separator)
|
||||
p = stpcpy(p, separator);
|
||||
|
||||
p = stpcpy(p, t);
|
||||
|
||||
need_separator = true;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
assert(p == r + l);
|
||||
|
||||
*p = 0;
|
||||
*x = r;
|
||||
|
||||
return r + l;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
char *strrep(const char *s, unsigned n) {
|
||||
size_t l;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -178,7 +179,9 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
|||
|
||||
char *strip_tab_ansi(char **p, size_t *l);
|
||||
|
||||
char *strextend(char **x, ...) _sentinel_;
|
||||
char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_;
|
||||
|
||||
#define strextend(x, ...) strextend_with_separator(x, NULL, __VA_ARGS__)
|
||||
|
||||
char *strrep(const char *s, unsigned n);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -180,3 +181,11 @@ char **strv_skip(char **l, size_t n);
|
|||
int strv_extend_n(char ***l, const char *value, size_t n);
|
||||
|
||||
int fputstrv(FILE *f, char **l, const char *separator, bool *space);
|
||||
|
||||
#define strv_free_and_replace(a, b) \
|
||||
({ \
|
||||
strv_free(a); \
|
||||
(a) = (b); \
|
||||
(b) = NULL; \
|
||||
0; \
|
||||
})
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -897,7 +898,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
|
|||
if (last_space != NULL && timezone_is_valid(last_space + 1))
|
||||
tz = last_space + 1;
|
||||
|
||||
if (tz == NULL || endswith_no_case(t, " UTC"))
|
||||
if (!tz || endswith_no_case(t, " UTC"))
|
||||
return parse_timestamp_impl(t, usec, false);
|
||||
|
||||
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||
|
@ -1387,8 +1388,7 @@ bool clock_supported(clockid_t clock) {
|
|||
if (!clock_boottime_supported())
|
||||
return false;
|
||||
|
||||
/* fall through */
|
||||
|
||||
_fallthrough_;
|
||||
default:
|
||||
/* For everything else, check properly */
|
||||
return clock_gettime(clock, &ts) >= 0;
|
||||
|
@ -1463,4 +1463,10 @@ usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
|
|||
/* x lies in the past */
|
||||
return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
|
||||
}
|
||||
|
||||
bool in_utc_timezone(void) {
|
||||
tzset();
|
||||
|
||||
return timezone == 0 && daylight == 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -155,6 +156,8 @@ struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
|
|||
|
||||
unsigned long usec_to_jiffies(usec_t usec);
|
||||
|
||||
bool in_utc_timezone(void);
|
||||
|
||||
static inline usec_t usec_add(usec_t a, usec_t b) {
|
||||
usec_t c;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -40,6 +41,7 @@
|
|||
#include "build.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "def.h"
|
||||
#include "device-nodes.h"
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
|
@ -122,63 +124,42 @@ int socket_from_display(const char *display, char **path) {
|
|||
}
|
||||
|
||||
int block_get_whole_disk(dev_t d, dev_t *ret) {
|
||||
char *p, *s;
|
||||
char p[SYS_BLOCK_PATH_MAX("/partition")];
|
||||
_cleanup_free_ char *s = NULL;
|
||||
int r;
|
||||
unsigned n, m;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* If it has a queue this is good enough for us */
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = access(p, F_OK);
|
||||
free(p);
|
||||
|
||||
if (r >= 0) {
|
||||
xsprintf_sys_block_path(p, "/queue", d);
|
||||
if (access(p, F_OK) >= 0) {
|
||||
*ret = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If it is a partition find the originating device */
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = access(p, F_OK);
|
||||
free(p);
|
||||
|
||||
if (r < 0)
|
||||
xsprintf_sys_block_path(p, "/partition", d);
|
||||
if (access(p, F_OK) < 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* Get parent dev_t */
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
xsprintf_sys_block_path(p, "/../dev", d);
|
||||
r = read_one_line_file(p, &s);
|
||||
free(p);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sscanf(s, "%u:%u", &m, &n);
|
||||
free(s);
|
||||
|
||||
if (r != 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only return this if it is really good enough for us. */
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
|
||||
return -ENOMEM;
|
||||
xsprintf_sys_block_path(p, "/queue", makedev(m, n));
|
||||
if (access(p, F_OK) < 0)
|
||||
return -ENOENT;
|
||||
|
||||
r = access(p, F_OK);
|
||||
free(p);
|
||||
|
||||
if (r >= 0) {
|
||||
*ret = makedev(m, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
*ret = makedev(m, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool kexec_loaded(void) {
|
||||
|
@ -753,7 +734,8 @@ int get_block_device(const char *path, dev_t *dev) {
|
|||
|
||||
int get_block_device_harder(const char *path, dev_t *dev) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
_cleanup_free_ char *p = NULL, *t = NULL;
|
||||
_cleanup_free_ char *t = NULL;
|
||||
char p[SYS_BLOCK_PATH_MAX("/slaves")];
|
||||
struct dirent *de, *found = NULL;
|
||||
const char *q;
|
||||
unsigned maj, min;
|
||||
|
@ -771,9 +753,7 @@ int get_block_device_harder(const char *path, dev_t *dev) {
|
|||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (asprintf(&p, "/sys/dev/block/%u:%u/slaves", major(dt), minor(dt)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
xsprintf_sys_block_path(p, "/slaves", dt);
|
||||
d = opendir(p);
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -192,9 +193,7 @@ static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overlo
|
|||
if (!ascii_is_valid(string))
|
||||
return -EINVAL;
|
||||
|
||||
free(*error_message);
|
||||
*error_message = string;
|
||||
string = NULL;
|
||||
free_and_replace(*error_message, string);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -61,6 +62,7 @@ typedef struct DHCP6IA DHCP6IA;
|
|||
int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
|
||||
size_t optlen, const void *optval);
|
||||
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia);
|
||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
|
||||
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||
size_t *optlen, uint8_t **optvalue);
|
||||
int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -138,6 +139,33 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
|
||||
uint8_t buffer[1 + DNS_WIRE_FOMAT_HOSTNAME_MAX];
|
||||
int r;
|
||||
|
||||
assert_return(buf && *buf && buflen && fqdn, -EINVAL);
|
||||
|
||||
buffer[0] = DHCP6_FQDN_FLAG_S; /* Request server to perform AAAA RR DNS updates */
|
||||
|
||||
/* Store domain name after flags field */
|
||||
r = dns_name_to_wire_format(fqdn, buffer + 1, sizeof(buffer) - 1, false);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/*
|
||||
* According to RFC 4704, chapter 4.2 only add terminating zero-length
|
||||
* label in case a FQDN is provided. Since dns_name_to_wire_format
|
||||
* always adds terminating zero-length label remove if only a hostname
|
||||
* is provided.
|
||||
*/
|
||||
if (dns_name_is_single_label(fqdn))
|
||||
r--;
|
||||
|
||||
r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_FQDN, 1 + r, buffer);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
|
||||
DHCP6Option *option = (DHCP6Option*) *buf;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
@ -104,3 +105,9 @@ enum {
|
|||
DHCP6_STATUS_USE_MULTICAST = 5,
|
||||
_DHCP6_STATUS_MAX = 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
DHCP6_FQDN_FLAG_S = (1 << 0),
|
||||
DHCP6_FQDN_FLAG_O = (1 << 1),
|
||||
DHCP6_FQDN_FLAG_N = (1 << 2),
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -419,9 +420,9 @@ int sd_dhcp_client_set_hostname(
|
|||
|
||||
assert_return(client, -EINVAL);
|
||||
|
||||
/* Refuse hostnames that neither qualify as DNS nor as Linux hosntames */
|
||||
/* Make sure hostnames qualify as DNS and as Linux hostnames */
|
||||
if (hostname &&
|
||||
!(hostname_is_valid(hostname, false) || dns_name_is_valid(hostname) > 0))
|
||||
!(hostname_is_valid(hostname, false) && dns_name_is_valid(hostname) > 0))
|
||||
return -EINVAL;
|
||||
|
||||
return free_and_strdup(&client->hostname, hostname);
|
||||
|
@ -832,7 +833,6 @@ static int client_send_request(sd_dhcp_client *client) {
|
|||
client’s IP address.
|
||||
*/
|
||||
|
||||
/* fall through */
|
||||
case DHCP_STATE_REBINDING:
|
||||
/* ’server identifier’ MUST NOT be filled in, ’requested IP address’
|
||||
option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -394,9 +395,7 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
|
|||
if (dns_name_is_root(normalized))
|
||||
return -EINVAL;
|
||||
|
||||
free(*ret);
|
||||
*ret = normalized;
|
||||
normalized = NULL;
|
||||
free_and_replace(*ret, normalized);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -685,9 +684,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
|||
return 0;
|
||||
}
|
||||
|
||||
free(lease->timezone);
|
||||
lease->timezone = tz;
|
||||
tz = NULL;
|
||||
free_and_replace(lease->timezone, tz);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -31,7 +32,9 @@
|
|||
#include "dhcp6-internal.h"
|
||||
#include "dhcp6-lease-internal.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
#include "dns-domain.h"
|
||||
#include "fd-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "network-internal.h"
|
||||
#include "random-util.h"
|
||||
|
@ -61,6 +64,7 @@ struct sd_dhcp6_client {
|
|||
be16_t *req_opts;
|
||||
size_t req_opts_allocated;
|
||||
size_t req_opts_len;
|
||||
char *fqdn;
|
||||
sd_event_source *receive_message;
|
||||
usec_t retransmit_time;
|
||||
uint8_t retransmit_count;
|
||||
|
@ -235,6 +239,20 @@ int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
|
|||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
int sd_dhcp6_client_set_fqdn(
|
||||
sd_dhcp6_client *client,
|
||||
const char *fqdn) {
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
|
||||
/* Make sure FQDN qualifies as DNS and as Linux hostname */
|
||||
if (fqdn &&
|
||||
!(hostname_is_valid(fqdn, false) && dns_name_is_valid(fqdn) > 0))
|
||||
return -EINVAL;
|
||||
|
||||
return free_and_strdup(&client->fqdn, fqdn);
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled) {
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
||||
|
@ -393,6 +411,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (client->fqdn) {
|
||||
r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REQUEST:
|
||||
|
@ -413,6 +437,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (client->fqdn) {
|
||||
r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_REBIND:
|
||||
|
@ -422,6 +452,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (client->fqdn) {
|
||||
r = dhcp6_option_append_fqdn(&opt, &optlen, client->fqdn);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_STOPPED:
|
||||
|
@ -1003,7 +1039,7 @@ static int client_receive_message(
|
|||
break;
|
||||
}
|
||||
|
||||
/* fall through */ /* for Soliciation Rapid Commit option check */
|
||||
_fallthrough_; /* for Soliciation Rapid Commit option check */
|
||||
case DHCP6_STATE_REQUEST:
|
||||
case DHCP6_STATE_RENEW:
|
||||
case DHCP6_STATE_REBIND:
|
||||
|
@ -1068,7 +1104,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case DHCP6_STATE_SOLICITATION:
|
||||
client->state = DHCP6_STATE_SOLICITATION;
|
||||
|
||||
|
@ -1304,6 +1340,7 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
|
|||
sd_dhcp6_client_detach_event(client);
|
||||
|
||||
free(client->req_opts);
|
||||
free(client->fqdn);
|
||||
return mfree(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -289,8 +290,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
|
|||
break;
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
|
||||
_fallthrough_;
|
||||
case IPV4ACD_STATE_WAITING_ANNOUNCE:
|
||||
/* Send announcement packet */
|
||||
r = arp_send_announcement(acd->fd, acd->ifindex, acd->address, &acd->mac_addr);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
|
@ -120,7 +121,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
|||
if (buffer[32] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 32: /* plain UUID without trailing newline */
|
||||
if (f == ID128_UUID)
|
||||
return -EINVAL;
|
||||
|
@ -132,7 +133,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
|||
if (buffer[36] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
/* fall through */
|
||||
_fallthrough_;
|
||||
case 36: /* RFC UUID without trailing newline */
|
||||
if (f == ID128_PLAIN)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue