mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 12:34:55 +00:00
systemd: update code from upstream (2020-04-08)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=8ff8ce62845e708186077d11eba83adae7b02e61 ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/systemd/src/ \ :/shared/systemd/src/ \ :/shared/nm-std-aux/unaligned.h | \ xargs -0 rm -f nm_copy_sd_shared() { mkdir -p "./shared/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1" } nm_copy_sd_core() { mkdir -p "./src/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/systemd/$1" } nm_copy_sd_stdaux() { mkdir -p "./shared/nm-std-aux/" cp "$SYSTEMD_DIR/$1" "./shared/nm-std-aux/${1##*/}" } nm_copy_sd_core "src/libsystemd-network/arp-util.c" nm_copy_sd_core "src/libsystemd-network/arp-util.h" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c" nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd_core "src/libsystemd-network/lldp-internal.h" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h" nm_copy_sd_core "src/libsystemd-network/lldp-network.c" nm_copy_sd_core "src/libsystemd-network/lldp-network.h" nm_copy_sd_core "src/libsystemd-network/network-internal.c" nm_copy_sd_core "src/libsystemd-network/network-internal.h" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c" nm_copy_sd_core "src/libsystemd-network/sd-lldp.c" nm_copy_sd_core "src/libsystemd/sd-event/event-source.h" nm_copy_sd_core "src/libsystemd/sd-event/event-util.c" nm_copy_sd_core "src/libsystemd/sd-event/event-util.h" nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd_core "src/systemd/_sd-common.h" nm_copy_sd_core "src/systemd/sd-dhcp-client.h" nm_copy_sd_core "src/systemd/sd-dhcp-lease.h" nm_copy_sd_core "src/systemd/sd-dhcp-option.h" nm_copy_sd_core "src/systemd/sd-dhcp6-client.h" nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h" nm_copy_sd_core "src/systemd/sd-event.h" nm_copy_sd_core "src/systemd/sd-id128.h" nm_copy_sd_core "src/systemd/sd-ipv4acd.h" nm_copy_sd_core "src/systemd/sd-ipv4ll.h" nm_copy_sd_core "src/systemd/sd-lldp.h" nm_copy_sd_core "src/systemd/sd-ndisc.h" nm_copy_sd_shared "src/basic/alloc-util.c" nm_copy_sd_shared "src/basic/alloc-util.h" nm_copy_sd_shared "src/basic/async.h" nm_copy_sd_shared "src/basic/cgroup-util.h" nm_copy_sd_shared "src/basic/env-file.c" nm_copy_sd_shared "src/basic/env-file.h" nm_copy_sd_shared "src/basic/env-util.c" nm_copy_sd_shared "src/basic/env-util.h" nm_copy_sd_shared "src/basic/errno-util.h" nm_copy_sd_shared "src/basic/escape.c" nm_copy_sd_shared "src/basic/escape.h" nm_copy_sd_shared "src/basic/ether-addr-util.c" nm_copy_sd_shared "src/basic/ether-addr-util.h" nm_copy_sd_shared "src/basic/extract-word.c" nm_copy_sd_shared "src/basic/extract-word.h" nm_copy_sd_shared "src/basic/fd-util.c" nm_copy_sd_shared "src/basic/fd-util.h" nm_copy_sd_shared "src/basic/fileio.c" nm_copy_sd_shared "src/basic/fileio.h" nm_copy_sd_shared "src/basic/format-util.c" nm_copy_sd_shared "src/basic/format-util.h" nm_copy_sd_shared "src/basic/fs-util.c" nm_copy_sd_shared "src/basic/fs-util.h" nm_copy_sd_shared "src/basic/hash-funcs.c" nm_copy_sd_shared "src/basic/hash-funcs.h" nm_copy_sd_shared "src/basic/hashmap.c" nm_copy_sd_shared "src/basic/hashmap.h" nm_copy_sd_shared "src/basic/hexdecoct.c" nm_copy_sd_shared "src/basic/hexdecoct.h" nm_copy_sd_shared "src/basic/hostname-util.c" nm_copy_sd_shared "src/basic/hostname-util.h" nm_copy_sd_shared "src/basic/in-addr-util.c" nm_copy_sd_shared "src/basic/in-addr-util.h" nm_copy_sd_shared "src/basic/io-util.c" nm_copy_sd_shared "src/basic/io-util.h" nm_copy_sd_shared "src/basic/list.h" nm_copy_sd_shared "src/basic/log.h" nm_copy_sd_shared "src/basic/macro.h" nm_copy_sd_shared "src/basic/memory-util.c" nm_copy_sd_shared "src/basic/memory-util.h" nm_copy_sd_shared "src/basic/mempool.c" nm_copy_sd_shared "src/basic/mempool.h" nm_copy_sd_shared "src/basic/missing_fcntl.h" nm_copy_sd_shared "src/basic/missing_random.h" nm_copy_sd_shared "src/basic/missing_socket.h" nm_copy_sd_shared "src/basic/missing_stat.h" nm_copy_sd_shared "src/basic/missing_syscall.h" nm_copy_sd_shared "src/basic/missing_type.h" nm_copy_sd_shared "src/basic/parse-util.c" nm_copy_sd_shared "src/basic/parse-util.h" nm_copy_sd_shared "src/basic/path-util.c" nm_copy_sd_shared "src/basic/path-util.h" nm_copy_sd_shared "src/basic/prioq.c" nm_copy_sd_shared "src/basic/prioq.h" nm_copy_sd_shared "src/basic/process-util.c" nm_copy_sd_shared "src/basic/process-util.h" nm_copy_sd_shared "src/basic/random-util.c" nm_copy_sd_shared "src/basic/random-util.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.c" nm_copy_sd_shared "src/basic/signal-util.h" nm_copy_sd_shared "src/basic/siphash24.h" nm_copy_sd_shared "src/basic/socket-util.c" nm_copy_sd_shared "src/basic/socket-util.h" nm_copy_sd_shared "src/basic/sort-util.h" nm_copy_sd_shared "src/basic/sparse-endian.h" nm_copy_sd_shared "src/basic/stat-util.c" nm_copy_sd_shared "src/basic/stat-util.h" nm_copy_sd_shared "src/basic/stdio-util.h" nm_copy_sd_shared "src/basic/string-table.c" nm_copy_sd_shared "src/basic/string-table.h" nm_copy_sd_shared "src/basic/string-util.c" nm_copy_sd_shared "src/basic/string-util.h" nm_copy_sd_shared "src/basic/strv.c" nm_copy_sd_shared "src/basic/strv.h" nm_copy_sd_shared "src/basic/strxcpyx.c" nm_copy_sd_shared "src/basic/strxcpyx.h" nm_copy_sd_shared "src/basic/time-util.c" nm_copy_sd_shared "src/basic/time-util.h" nm_copy_sd_shared "src/basic/tmpfile-util.c" nm_copy_sd_shared "src/basic/tmpfile-util.h" nm_copy_sd_shared "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/user-util.h" nm_copy_sd_shared "src/basic/utf8.c" nm_copy_sd_shared "src/basic/utf8.h" nm_copy_sd_shared "src/basic/util.c" nm_copy_sd_shared "src/basic/util.h" nm_copy_sd_shared "src/shared/dns-domain.c" nm_copy_sd_shared "src/shared/dns-domain.h" nm_copy_sd_shared "src/shared/web-util.c" nm_copy_sd_shared "src/shared/web-util.h" nm_copy_sd_stdaux "src/basic/unaligned.h"
This commit is contained in:
parent
46a1816034
commit
c5189cffc1
|
@ -184,10 +184,13 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri
|
|||
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
|
||||
int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char **keys, char **values);
|
||||
|
||||
int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
|
||||
|
||||
int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
|
||||
|
||||
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
|
||||
int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size);
|
||||
int cg_get_xattr_malloc(const char *controller, const char *path, const char *name, char **ret);
|
||||
int cg_remove_xattr(const char *controller, const char *path, const char *name);
|
||||
|
||||
int cg_install_release_agent(const char *controller, const char *agent);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -59,9 +59,12 @@ void log_show_color(bool b);
|
|||
bool log_get_show_color(void) _pure_;
|
||||
void log_show_location(bool b);
|
||||
bool log_get_show_location(void) _pure_;
|
||||
void log_show_time(bool b);
|
||||
bool log_get_show_time(void) _pure_;
|
||||
|
||||
int log_show_color_from_string(const char *e);
|
||||
int log_show_location_from_string(const char *e);
|
||||
int log_show_time_from_string(const char *e);
|
||||
|
||||
LogTarget log_get_target(void) _pure_;
|
||||
int log_get_max_level_realm(LogRealm realm) _pure_;
|
||||
|
@ -74,7 +77,7 @@ int log_get_max_level_realm(LogRealm realm) _pure_;
|
|||
*/
|
||||
|
||||
assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1);
|
||||
#define PROJECT_FILE (__FILE__ + STRLEN(RELATIVE_SOURCE_PATH) + 1)
|
||||
#define PROJECT_FILE (&__FILE__[STRLEN(RELATIVE_SOURCE_PATH) + 1])
|
||||
|
||||
int log_open(void);
|
||||
void log_close(void);
|
||||
|
|
|
@ -1178,6 +1178,11 @@ int must_be_root(void) {
|
|||
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
|
||||
}
|
||||
|
||||
static void restore_sigsetp(sigset_t **ssp) {
|
||||
if (*ssp)
|
||||
(void) sigprocmask(SIG_SETMASK, *ssp, NULL);
|
||||
}
|
||||
|
||||
int safe_fork_full(
|
||||
const char *name,
|
||||
const int except_fds[],
|
||||
|
@ -1187,7 +1192,8 @@ int safe_fork_full(
|
|||
|
||||
pid_t original_pid, pid;
|
||||
sigset_t saved_ss, ss;
|
||||
bool block_signals = false;
|
||||
_cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
|
||||
bool block_signals = false, block_all = false;
|
||||
int prio, r;
|
||||
|
||||
/* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
|
||||
|
@ -1202,7 +1208,7 @@ int safe_fork_full(
|
|||
* be sure that SIGTERMs are not lost we might send to the child. */
|
||||
|
||||
assert_se(sigfillset(&ss) >= 0);
|
||||
block_signals = true;
|
||||
block_signals = block_all = true;
|
||||
|
||||
} else if (flags & FORK_WAIT) {
|
||||
/* Let's block SIGCHLD at least, so that we can safely watch for the child process */
|
||||
|
@ -1212,28 +1218,31 @@ int safe_fork_full(
|
|||
block_signals = true;
|
||||
}
|
||||
|
||||
if (block_signals)
|
||||
if (block_signals) {
|
||||
if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0)
|
||||
return log_full_errno(prio, errno, "Failed to set signal mask: %m");
|
||||
saved_ssp = &saved_ss;
|
||||
}
|
||||
|
||||
if (flags & FORK_NEW_MOUNTNS)
|
||||
pid = raw_clone(SIGCHLD|CLONE_NEWNS);
|
||||
else
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
r = -errno;
|
||||
|
||||
if (block_signals) /* undo what we did above */
|
||||
(void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
|
||||
|
||||
return log_full_errno(prio, r, "Failed to fork: %m");
|
||||
}
|
||||
if (pid < 0)
|
||||
return log_full_errno(prio, errno, "Failed to fork: %m");
|
||||
if (pid > 0) {
|
||||
/* We are in the parent process */
|
||||
|
||||
log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
|
||||
|
||||
if (flags & FORK_WAIT) {
|
||||
if (block_all) {
|
||||
/* undo everything except SIGCHLD */
|
||||
ss = saved_ss;
|
||||
assert_se(sigaddset(&ss, SIGCHLD) >= 0);
|
||||
(void) sigprocmask(SIG_SETMASK, &ss, NULL);
|
||||
}
|
||||
|
||||
r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1241,9 +1250,6 @@ int safe_fork_full(
|
|||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (block_signals) /* undo what we did above */
|
||||
(void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
|
||||
|
||||
if (ret_pid)
|
||||
*ret_pid = pid;
|
||||
|
||||
|
@ -1252,6 +1258,9 @@ int safe_fork_full(
|
|||
|
||||
/* We are in the child process */
|
||||
|
||||
/* Restore signal mask manually */
|
||||
saved_ssp = NULL;
|
||||
|
||||
if (flags & FORK_REOPEN_LOG) {
|
||||
/* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
|
||||
log_close();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -113,7 +113,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
|
|||
bool escaped = false;
|
||||
int n;
|
||||
|
||||
for (n=0; s[n]; n++) {
|
||||
for (n = 0; s[n] != '\0'; n++) {
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else if (s[n] == '\\')
|
||||
|
@ -122,50 +122,62 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* if s ends in \, return index of previous char */
|
||||
return n - escaped;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Split a string into words. */
|
||||
const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags) {
|
||||
const char* split(
|
||||
const char **state,
|
||||
size_t *l,
|
||||
const char *separator,
|
||||
SplitFlags flags) {
|
||||
|
||||
const char *current;
|
||||
|
||||
assert(state);
|
||||
assert(l);
|
||||
|
||||
if (!separator)
|
||||
separator = WHITESPACE;
|
||||
|
||||
current = *state;
|
||||
|
||||
if (!*current) {
|
||||
assert(**state == '\0');
|
||||
if (*current == '\0') /* already at the end? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
current += strspn(current, separator);
|
||||
if (!*current) {
|
||||
current += strspn(current, separator); /* skip leading separators */
|
||||
if (*current == '\0') { /* at the end now? */
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & SPLIT_QUOTES && strchr("\'\"", *current)) {
|
||||
char quotechars[2] = {*current, '\0'};
|
||||
if (FLAGS_SET(flags, SPLIT_QUOTES)) {
|
||||
|
||||
*l = strcspn_escaped(current + 1, quotechars);
|
||||
if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
|
||||
(current[*l + 2] && !strchr(separator, current[*l + 2]))) {
|
||||
/* right quote missing or garbage at the end */
|
||||
if (flags & SPLIT_RELAX) {
|
||||
*state = current + *l + 1 + (current[*l + 1] != '\0');
|
||||
return current + 1;
|
||||
if (strchr(QUOTES, *current)) {
|
||||
/* We are looking at a quote */
|
||||
*l = strcspn_escaped(current + 1, CHAR_TO_STR(*current));
|
||||
if (current[*l + 1] != *current ||
|
||||
(current[*l + 2] != 0 && !strchr(separator, current[*l + 2]))) {
|
||||
/* right quote missing or garbage at the end */
|
||||
if (FLAGS_SET(flags, SPLIT_RELAX)) {
|
||||
*state = current + *l + 1 + (current[*l + 1] != '\0');
|
||||
return current + 1;
|
||||
}
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
*state = current;
|
||||
return NULL;
|
||||
*state = current++ + *l + 2;
|
||||
|
||||
} else {
|
||||
/* We are looking at a something that is not a quote */
|
||||
*l = strcspn_escaped(current, separator);
|
||||
if (current[*l] && !strchr(separator, current[*l]) && !FLAGS_SET(flags, SPLIT_RELAX)) {
|
||||
/* unfinished escape */
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
*state = current + *l;
|
||||
}
|
||||
*state = current++ + *l + 2;
|
||||
} else if (flags & SPLIT_QUOTES) {
|
||||
*l = strcspn_escaped(current, separator);
|
||||
if (current[*l] && !strchr(separator, current[*l]) && !(flags & SPLIT_RELAX)) {
|
||||
/* unfinished escape */
|
||||
*state = current;
|
||||
return NULL;
|
||||
}
|
||||
*state = current + *l;
|
||||
} else {
|
||||
*l = strcspn(current, separator);
|
||||
*state = current + *l;
|
||||
|
|
|
@ -112,8 +112,10 @@ typedef enum SplitFlags {
|
|||
SPLIT_RELAX = 0x01 << 1,
|
||||
} SplitFlags;
|
||||
|
||||
/* Smelly. Do not use this anymore. Use extract_first_word() instead! */
|
||||
const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags);
|
||||
|
||||
/* Similar, don't use this anymore */
|
||||
#define FOREACH_WORD(word, length, s, state) \
|
||||
_FOREACH_WORD(word, length, s, WHITESPACE, 0, state)
|
||||
|
||||
|
|
|
@ -87,6 +87,16 @@ char **strv_parse_nulstr(const char *s, size_t l);
|
|||
char **strv_split_nulstr(const char *s);
|
||||
int strv_make_nulstr(char * const *l, char **p, size_t *n);
|
||||
|
||||
static inline int strv_from_nulstr(char ***a, const char *nulstr) {
|
||||
char **t;
|
||||
|
||||
t = strv_split_nulstr(nulstr);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
*a = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool strv_overlap(char * const *a, char * const *b) _pure_;
|
||||
|
||||
#define STRV_FOREACH(s, l) \
|
||||
|
|
|
@ -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;
|
||||
|
|
53
shared/systemd/src/shared/web-util.c
Normal file
53
shared/systemd/src/shared/web-util.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
#include "web-util.h"
|
||||
|
||||
bool http_etag_is_valid(const char *etag) {
|
||||
if (isempty(etag))
|
||||
return false;
|
||||
|
||||
if (!endswith(etag, "\""))
|
||||
return false;
|
||||
|
||||
if (!STARTSWITH_SET(etag, "\"", "W/\""))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_url_is_valid(const char *url) {
|
||||
const char *p;
|
||||
|
||||
if (isempty(url))
|
||||
return false;
|
||||
|
||||
p = STARTSWITH_SET(url, "http://", "https://");
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
||||
return ascii_is_valid(p);
|
||||
}
|
||||
|
||||
bool documentation_url_is_valid(const char *url) {
|
||||
const char *p;
|
||||
|
||||
if (isempty(url))
|
||||
return false;
|
||||
|
||||
if (http_url_is_valid(url))
|
||||
return true;
|
||||
|
||||
p = STARTSWITH_SET(url, "file:/", "info:", "man:");
|
||||
if (isempty(p))
|
||||
return false;
|
||||
|
||||
return ascii_is_valid(p);
|
||||
}
|
12
shared/systemd/src/shared/web-util.h
Normal file
12
shared/systemd/src/shared/web-util.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
bool http_url_is_valid(const char *url) _pure_;
|
||||
|
||||
bool documentation_url_is_valid(const char *url) _pure_;
|
||||
|
||||
bool http_etag_is_valid(const char *etag);
|
|
@ -61,6 +61,12 @@ struct sd_dhcp_lease {
|
|||
struct in_addr *sip;
|
||||
size_t sip_size;
|
||||
|
||||
struct in_addr *pop3_server;
|
||||
size_t pop3_server_size;
|
||||
|
||||
struct in_addr *smtp_server;
|
||||
size_t smtp_server_size;
|
||||
|
||||
struct sd_dhcp_route *static_route;
|
||||
size_t static_route_size, static_route_allocated;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "sd-dhcp-lease.h"
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "def.h"
|
||||
#include "set.h"
|
||||
#include "strv.h"
|
||||
|
||||
|
@ -66,5 +65,3 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
|
|||
|
||||
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
|
||||
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
|
||||
|
||||
#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -129,6 +129,28 @@ int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
|||
return (int) lease->sip_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
if (lease->pop3_server_size <= 0)
|
||||
return -ENODATA;
|
||||
|
||||
*addr = lease->pop3_server;
|
||||
return (int) lease->pop3_server_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
if (lease->smtp_server_size <= 0)
|
||||
return -ENODATA;
|
||||
|
||||
*addr = lease->smtp_server;
|
||||
return (int) lease->smtp_server_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(domainname, -EINVAL);
|
||||
|
@ -279,6 +301,8 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
|
|||
free(lease->dns);
|
||||
free(lease->ntp);
|
||||
free(lease->sip);
|
||||
free(lease->pop3_server);
|
||||
free(lease->smtp_server);
|
||||
free(lease->static_route);
|
||||
free(lease->client_id);
|
||||
free(lease->vendor_specific);
|
||||
|
@ -601,6 +625,18 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
|
|||
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_POP3_SERVER:
|
||||
r = lease_parse_in_addrs(option, len, &lease->pop3_server, &lease->pop3_server_size);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_SMTP_SERVER:
|
||||
r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
|
||||
break;
|
||||
|
||||
case SD_DHCP_OPTION_STATIC_ROUTE:
|
||||
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
|
||||
if (r < 0)
|
||||
|
@ -1037,6 +1073,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||
*dns = NULL,
|
||||
*ntp = NULL,
|
||||
*sip = NULL,
|
||||
*pop3_server = NULL,
|
||||
*smtp_server = NULL,
|
||||
*mtu = NULL,
|
||||
*routes = NULL,
|
||||
*domains = NULL,
|
||||
|
@ -1066,6 +1104,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||
"DNS", &dns,
|
||||
"NTP", &ntp,
|
||||
"SIP", &sip,
|
||||
"POP3_SERVERS", &pop3_server,
|
||||
"SMTP_SERVERS", &smtp_server,
|
||||
"MTU", &mtu,
|
||||
"DOMAINNAME", &lease->domainname,
|
||||
"HOSTNAME", &lease->hostname,
|
||||
|
@ -1175,7 +1215,23 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
|
|||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
|
||||
else
|
||||
lease->ntp_size = r;
|
||||
lease->sip_size = r;
|
||||
}
|
||||
|
||||
if (pop3_server) {
|
||||
r = deserialize_in_addrs(&lease->pop3_server, pop3_server);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3_server);
|
||||
else
|
||||
lease->pop3_server_size = r;
|
||||
}
|
||||
|
||||
if (smtp_server) {
|
||||
r = deserialize_in_addrs(&lease->smtp_server, smtp_server);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server);
|
||||
else
|
||||
lease->smtp_server_size = r;
|
||||
}
|
||||
|
||||
if (mtu) {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "util.h"
|
||||
#include "web-util.h"
|
||||
|
||||
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
|
||||
|
||||
|
@ -65,6 +66,7 @@ struct sd_dhcp6_client {
|
|||
size_t req_opts_allocated;
|
||||
size_t req_opts_len;
|
||||
char *fqdn;
|
||||
char *mudurl;
|
||||
sd_event_source *receive_message;
|
||||
usec_t retransmit_time;
|
||||
uint8_t retransmit_count;
|
||||
|
@ -363,6 +365,17 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, char *mudurl) {
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
|
||||
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_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
|
||||
assert_return(client, -EINVAL);
|
||||
assert_return(delegation, -EINVAL);
|
||||
|
@ -484,6 +497,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
case DHCP6_STATE_INFORMATION_REQUEST:
|
||||
message->type = DHCP6_INFORMATION_REQUEST;
|
||||
|
||||
if (client->mudurl) {
|
||||
r = dhcp6_option_append(&opt, &optlen,
|
||||
SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
|
||||
client->mudurl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DHCP6_STATE_SOLICITATION:
|
||||
|
@ -507,6 +528,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
return r;
|
||||
}
|
||||
|
||||
if (client->mudurl) {
|
||||
r = dhcp6_option_append(&opt, &optlen,
|
||||
SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
|
||||
client->mudurl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
||||
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
|
||||
if (r < 0)
|
||||
|
@ -545,6 +574,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
return r;
|
||||
}
|
||||
|
||||
if (client->mudurl) {
|
||||
r = dhcp6_option_append(&opt, &optlen,
|
||||
SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
|
||||
client->mudurl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
||||
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
|
||||
if (r < 0)
|
||||
|
@ -571,6 +608,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
|
|||
return r;
|
||||
}
|
||||
|
||||
if (client->mudurl) {
|
||||
r = dhcp6_option_append(&opt, &optlen,
|
||||
SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
|
||||
client->mudurl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
|
||||
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
|
||||
if (r < 0)
|
||||
|
@ -1521,6 +1566,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
|||
|
||||
free(client->req_opts);
|
||||
free(client->fqdn);
|
||||
free(client->mudurl);
|
||||
return mfree(client);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ enum {
|
|||
SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
|
||||
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
|
||||
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
|
||||
SD_DHCP_OPTION_SMTP_SERVER = 69,
|
||||
SD_DHCP_OPTION_POP3_SERVER = 70,
|
||||
SD_DHCP_OPTION_USER_CLASS = 77,
|
||||
SD_DHCP_OPTION_FQDN = 81,
|
||||
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
|
||||
|
@ -90,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,
|
||||
|
@ -169,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);
|
||||
|
|
|
@ -45,6 +45,8 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad
|
|||
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
||||
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||
|
|
|
@ -73,6 +73,7 @@ enum {
|
|||
SD_DHCP6_OPTION_FQDN = 39, /* RFC 4704 */
|
||||
|
||||
SD_DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
|
||||
SD_DHCP6_OPTION_MUD_URL = 112, /* RFC 8250 */
|
||||
|
||||
/* option codes 89-142 are unassigned */
|
||||
/* option codes 144-65535 are unassigned */
|
||||
|
@ -120,6 +121,9 @@ int sd_dhcp6_client_get_information_request(
|
|||
int sd_dhcp6_client_set_request_option(
|
||||
sd_dhcp6_client *client,
|
||||
uint16_t option);
|
||||
int sd_dhcp6_client_set_request_mud_url(
|
||||
sd_dhcp6_client *client,
|
||||
char *mudurl);
|
||||
int sd_dhcp6_client_set_prefix_delegation_hint(
|
||||
sd_dhcp6_client *client,
|
||||
uint8_t prefixlen,
|
||||
|
|
Loading…
Reference in a new issue