systemd: merge branch systemd into master
This commit is contained in:
3
src/systemd/sd-adapt/glob-util.h
Normal file
3
src/systemd/sd-adapt/glob-util.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* dummy header */
|
@@ -43,6 +43,14 @@ static inline void *mfree(void *memory) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define free_and_replace(a, b) \
|
||||||
|
({ \
|
||||||
|
free(a); \
|
||||||
|
(a) = (b); \
|
||||||
|
(b) = NULL; \
|
||||||
|
0; \
|
||||||
|
})
|
||||||
|
|
||||||
void* memdup(const void *p, size_t l) _alloc_(2);
|
void* memdup(const void *p, size_t l) _alloc_(2);
|
||||||
|
|
||||||
static inline void freep(void *p) {
|
static inline void freep(void *p) {
|
||||||
|
@@ -335,7 +335,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
|
|||||||
assert(remaining > 0);
|
assert(remaining > 0);
|
||||||
|
|
||||||
if (*f != '\\') {
|
if (*f != '\\') {
|
||||||
/* A literal literal, copy verbatim */
|
/* A literal, copy verbatim */
|
||||||
*(t++) = *f;
|
*(t++) = *f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -604,4 +604,187 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int chase_symlinks(const char *path, const char *_root, char **ret) {
|
||||||
|
_cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
|
||||||
|
_cleanup_close_ int fd = -1;
|
||||||
|
unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
|
||||||
|
char *todo;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
|
||||||
|
/* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
|
||||||
|
* symlinks relative to a root directory, instead of the root of the host.
|
||||||
|
*
|
||||||
|
* Note that "root" matters only if we encounter an absolute symlink, it's unused otherwise. Most importantly
|
||||||
|
* this means the path parameter passed in is not prefixed by it.
|
||||||
|
*
|
||||||
|
* Algorithmically this operates on two path buffers: "done" are the components of the path we already
|
||||||
|
* processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
|
||||||
|
* process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
|
||||||
|
* each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
|
||||||
|
* slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
|
||||||
|
* at a minimum. */
|
||||||
|
|
||||||
|
r = path_make_absolute_cwd(path, &buffer);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (_root) {
|
||||||
|
r = path_make_absolute_cwd(_root, &root);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
todo = buffer;
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *first = NULL;
|
||||||
|
_cleanup_close_ int child = -1;
|
||||||
|
struct stat st;
|
||||||
|
size_t n, m;
|
||||||
|
|
||||||
|
/* Determine length of first component in the path */
|
||||||
|
n = strspn(todo, "/"); /* The slashes */
|
||||||
|
m = n + strcspn(todo + n, "/"); /* The entire length of the component */
|
||||||
|
|
||||||
|
/* Extract the first component. */
|
||||||
|
first = strndup(todo, m);
|
||||||
|
if (!first)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
todo += m;
|
||||||
|
|
||||||
|
/* Just a single slash? Then we reached the end. */
|
||||||
|
if (isempty(first) || path_equal(first, "/"))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Just a dot? Then let's eat this up. */
|
||||||
|
if (path_equal(first, "/."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Two dots? Then chop off the last bit of what we already found out. */
|
||||||
|
if (path_equal(first, "/..")) {
|
||||||
|
_cleanup_free_ char *parent = NULL;
|
||||||
|
int fd_parent = -1;
|
||||||
|
|
||||||
|
if (isempty(done) || path_equal(done, "/"))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
parent = dirname_malloc(done);
|
||||||
|
if (!parent)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Don't allow this to leave the root dir */
|
||||||
|
if (root &&
|
||||||
|
path_startswith(done, root) &&
|
||||||
|
!path_startswith(parent, root))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
free_and_replace(done, parent);
|
||||||
|
|
||||||
|
fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH);
|
||||||
|
if (fd_parent < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
safe_close(fd);
|
||||||
|
fd = fd_parent;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise let's see what this is. */
|
||||||
|
child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH);
|
||||||
|
if (child < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (fstat(child, &st) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (S_ISLNK(st.st_mode)) {
|
||||||
|
_cleanup_free_ char *destination = NULL;
|
||||||
|
|
||||||
|
/* This is a symlink, in this case read the destination. But let's make sure we don't follow
|
||||||
|
* symlinks without bounds. */
|
||||||
|
if (--max_follow <= 0)
|
||||||
|
return -ELOOP;
|
||||||
|
|
||||||
|
r = readlinkat_malloc(fd, first + n, &destination);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (isempty(destination))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (path_is_absolute(destination)) {
|
||||||
|
|
||||||
|
/* An absolute destination. Start the loop from the beginning, but use the root
|
||||||
|
* directory as base. */
|
||||||
|
|
||||||
|
safe_close(fd);
|
||||||
|
fd = open(root ?: "/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
free_and_replace(buffer, destination);
|
||||||
|
|
||||||
|
todo = buffer;
|
||||||
|
free(done);
|
||||||
|
|
||||||
|
/* Note that we do not revalidate the root, we take it as is. */
|
||||||
|
if (isempty(root))
|
||||||
|
done = NULL;
|
||||||
|
else {
|
||||||
|
done = strdup(root);
|
||||||
|
if (!done)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
char *joined;
|
||||||
|
|
||||||
|
/* A relative destination. If so, this is what we'll prefix what's left to do with what
|
||||||
|
* we just read, and start the loop again, but remain in the current directory. */
|
||||||
|
|
||||||
|
joined = strjoin("/", destination, todo, NULL);
|
||||||
|
if (!joined)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
todo = buffer = joined;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is not a symlink, then let's just add the name we read to what we already verified. */
|
||||||
|
if (!done) {
|
||||||
|
done = first;
|
||||||
|
first = NULL;
|
||||||
|
} else {
|
||||||
|
if (!strextend(&done, first, NULL))
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And iterate again, but go one directory further down. */
|
||||||
|
safe_close(fd);
|
||||||
|
fd = child;
|
||||||
|
child = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
/* Special case, turn the empty string into "/", to indicate the root directory. */
|
||||||
|
done = strdup("/");
|
||||||
|
if (!done)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = done;
|
||||||
|
done = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
@@ -77,3 +77,5 @@ union inotify_event_buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
||||||
|
|
||||||
|
int chase_symlinks(const char *path, const char *_root, char **ret);
|
||||||
|
@@ -142,6 +142,8 @@
|
|||||||
} else { \
|
} else { \
|
||||||
if ((_b->name##_prev = _a->name##_prev)) \
|
if ((_b->name##_prev = _a->name##_prev)) \
|
||||||
_b->name##_prev->name##_next = _b; \
|
_b->name##_prev->name##_next = _b; \
|
||||||
|
else \
|
||||||
|
*_head = _b; \
|
||||||
_b->name##_next = _a; \
|
_b->name##_next = _a; \
|
||||||
_a->name##_prev = _b; \
|
_a->name##_prev = _b; \
|
||||||
} \
|
} \
|
||||||
|
@@ -101,18 +101,22 @@ int log_object_internal(
|
|||||||
const char *func,
|
const char *func,
|
||||||
const char *object_field,
|
const char *object_field,
|
||||||
const char *object,
|
const char *object,
|
||||||
const char *format, ...) _printf_(8,9);
|
const char *extra_field,
|
||||||
|
const char *extra,
|
||||||
|
const char *format, ...) _printf_(10,11);
|
||||||
|
|
||||||
int log_object_internalv(
|
int log_object_internalv(
|
||||||
int level,
|
int level,
|
||||||
int error,
|
int error,
|
||||||
const char*file,
|
const char *file,
|
||||||
int line,
|
int line,
|
||||||
const char *func,
|
const char *func,
|
||||||
const char *object_field,
|
const char *object_field,
|
||||||
const char *object,
|
const char *object,
|
||||||
|
const char *extra_field,
|
||||||
|
const char *extra,
|
||||||
const char *format,
|
const char *format,
|
||||||
va_list ap) _printf_(8,0);
|
va_list ap) _printf_(9,0);
|
||||||
|
|
||||||
int log_struct_internal(
|
int log_struct_internal(
|
||||||
int level,
|
int level,
|
||||||
|
@@ -36,9 +36,11 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "extract-word.h"
|
#include "extract-word.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
|
#include "glob-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
@@ -289,9 +291,7 @@ char **path_strv_resolve(char **l, const char *prefix) {
|
|||||||
} else {
|
} else {
|
||||||
/* canonicalized path goes outside of
|
/* canonicalized path goes outside of
|
||||||
* prefix, keep the original path instead */
|
* prefix, keep the original path instead */
|
||||||
free(u);
|
free_and_replace(u, orig);
|
||||||
u = orig;
|
|
||||||
orig = NULL;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
free(t);
|
free(t);
|
||||||
@@ -817,8 +817,79 @@ bool is_device_path(const char *path) {
|
|||||||
/* Returns true on paths that refer to a device, either in
|
/* Returns true on paths that refer to a device, either in
|
||||||
* sysfs or in /dev */
|
* sysfs or in /dev */
|
||||||
|
|
||||||
return
|
return path_startswith(path, "/dev/") ||
|
||||||
path_startswith(path, "/dev/") ||
|
path_startswith(path, "/sys/");
|
||||||
path_startswith(path, "/sys/");
|
}
|
||||||
|
|
||||||
|
bool is_deviceallow_pattern(const char *path) {
|
||||||
|
return path_startswith(path, "/dev/") ||
|
||||||
|
startswith(path, "block-") ||
|
||||||
|
startswith(path, "char-");
|
||||||
|
}
|
||||||
|
|
||||||
|
int systemd_installation_has_version(const char *root, unsigned minimal_version) {
|
||||||
|
const char *pattern;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Try to guess if systemd installation is later than the specified version. This
|
||||||
|
* is hacky and likely to yield false negatives, particularly if the installation
|
||||||
|
* is non-standard. False positives should be relatively rare.
|
||||||
|
*/
|
||||||
|
|
||||||
|
NULSTR_FOREACH(pattern,
|
||||||
|
/* /lib works for systems without usr-merge, and for systems with a sane
|
||||||
|
* usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary
|
||||||
|
* for Gentoo which does a merge without making /lib a symlink.
|
||||||
|
*/
|
||||||
|
"lib/systemd/libsystemd-shared-*.so\0"
|
||||||
|
"usr/lib/systemd/libsystemd-shared-*.so\0") {
|
||||||
|
|
||||||
|
_cleanup_strv_free_ char **names = NULL;
|
||||||
|
_cleanup_free_ char *path = NULL;
|
||||||
|
char *c, **name;
|
||||||
|
|
||||||
|
path = prefix_root(root, pattern);
|
||||||
|
if (!path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = glob_extend(&names, path);
|
||||||
|
if (r == -ENOENT)
|
||||||
|
continue;
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
assert_se((c = endswith(path, "*.so")));
|
||||||
|
*c = '\0'; /* truncate the glob part */
|
||||||
|
|
||||||
|
STRV_FOREACH(name, names) {
|
||||||
|
/* This is most likely to run only once, hence let's not optimize anything. */
|
||||||
|
char *t, *t2;
|
||||||
|
unsigned version;
|
||||||
|
|
||||||
|
t = startswith(*name, path);
|
||||||
|
if (!t)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
t2 = endswith(t, ".so");
|
||||||
|
if (!t2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
t2[0] = '\0'; /* truncate the suffix */
|
||||||
|
|
||||||
|
r = safe_atou(t, &version);
|
||||||
|
if (r < 0) {
|
||||||
|
log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).",
|
||||||
|
*name, version,
|
||||||
|
version >= minimal_version ? "OK" : "too old");
|
||||||
|
if (version >= minimal_version)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
@@ -125,3 +125,6 @@ char *file_in_same_dir(const char *path, const char *filename);
|
|||||||
bool hidden_or_backup_file(const char *filename) _pure_;
|
bool hidden_or_backup_file(const char *filename) _pure_;
|
||||||
|
|
||||||
bool is_device_path(const char *path);
|
bool is_device_path(const char *path);
|
||||||
|
bool is_deviceallow_pattern(const char *path);
|
||||||
|
|
||||||
|
int systemd_installation_has_version(const char *root, unsigned minimal_version);
|
||||||
|
@@ -64,9 +64,7 @@ Prioq* prioq_free(Prioq *q) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
free(q->items);
|
free(q->items);
|
||||||
free(q);
|
return mfree(q);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) {
|
int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) {
|
||||||
|
@@ -444,7 +444,7 @@ const char* socket_address_get_path(const SocketAddress *a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool socket_ipv6_is_supported(void) {
|
bool socket_ipv6_is_supported(void) {
|
||||||
if (access("/proc/net/sockstat6", F_OK) != 0)
|
if (access("/proc/net/if_inet6", F_OK) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1064,3 +1064,20 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int socket_ioctl_fd(void) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
|
||||||
|
* that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
|
||||||
|
* available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
|
||||||
|
* generic AF_NETLINK. */
|
||||||
|
|
||||||
|
fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
@@ -154,3 +154,5 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
|
|||||||
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
|
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
|
||||||
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
|
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
int socket_ioctl_fd(void);
|
||||||
|
@@ -614,8 +614,7 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
oom:
|
oom:
|
||||||
free(r);
|
return mfree(r);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
||||||
@@ -686,8 +685,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) {
|
|||||||
|
|
||||||
if (ferror(f)) {
|
if (ferror(f)) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(obuf);
|
return mfree(obuf);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
@@ -89,8 +89,7 @@ void strv_clear(char **l) {
|
|||||||
|
|
||||||
char **strv_free(char **l) {
|
char **strv_free(char **l) {
|
||||||
strv_clear(l);
|
strv_clear(l);
|
||||||
free(l);
|
return mfree(l);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char **strv_free_erase(char **l) {
|
char **strv_free_erase(char **l) {
|
||||||
@@ -430,8 +429,7 @@ char *strv_join_quoted(char **l) {
|
|||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
oom:
|
oom:
|
||||||
free(buf);
|
return mfree(buf);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int strv_push(char ***l, char *value) {
|
int strv_push(char ***l, char *value) {
|
||||||
@@ -873,8 +871,7 @@ char ***strv_free_free(char ***l) {
|
|||||||
for (i = l; *i; i++)
|
for (i = l; *i; i++)
|
||||||
strv_free(*i);
|
strv_free(*i);
|
||||||
|
|
||||||
free(l);
|
return mfree(l);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char **strv_skip(char **l, size_t n) {
|
char **strv_skip(char **l, size_t n) {
|
||||||
|
@@ -96,10 +96,13 @@ bool strv_overlap(char **a, char **b) _pure_;
|
|||||||
#define STRV_FOREACH(s, l) \
|
#define STRV_FOREACH(s, l) \
|
||||||
for ((s) = (l); (s) && *(s); (s)++)
|
for ((s) = (l); (s) && *(s); (s)++)
|
||||||
|
|
||||||
#define STRV_FOREACH_BACKWARDS(s, l) \
|
#define STRV_FOREACH_BACKWARDS(s, l) \
|
||||||
STRV_FOREACH(s, l) \
|
for (s = ({ \
|
||||||
; \
|
char **_l = l; \
|
||||||
for ((s)--; (l) && ((s) >= (l)); (s)--)
|
_l ? _l + strv_length(_l) - 1U : NULL; \
|
||||||
|
}); \
|
||||||
|
(l) && ((s) >= (l)); \
|
||||||
|
(s)--)
|
||||||
|
|
||||||
#define STRV_FOREACH_PAIR(x, y, l) \
|
#define STRV_FOREACH_PAIR(x, y, l) \
|
||||||
for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1))
|
for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1))
|
||||||
@@ -141,6 +144,11 @@ void strv_print(char **l);
|
|||||||
})
|
})
|
||||||
|
|
||||||
#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
|
#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
|
||||||
|
#define STRPTR_IN_SET(x, ...) \
|
||||||
|
({ \
|
||||||
|
const char* _x = (x); \
|
||||||
|
_x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \
|
||||||
|
})
|
||||||
|
|
||||||
#define FOREACH_STRING(x, ...) \
|
#define FOREACH_STRING(x, ...) \
|
||||||
for (char **_l = ({ \
|
for (char **_l = ({ \
|
||||||
|
@@ -472,7 +472,7 @@ bool in_initrd(void) {
|
|||||||
* 2. the root file system must be a memory file system
|
* 2. the root file system must be a memory file system
|
||||||
*
|
*
|
||||||
* The second check is extra paranoia, since misdetecting an
|
* The second check is extra paranoia, since misdetecting an
|
||||||
* initrd can have bad bad consequences due the initrd
|
* initrd can have bad consequences due the initrd
|
||||||
* emptying when transititioning to the main systemd.
|
* emptying when transititioning to the main systemd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -1877,9 +1877,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
|
|||||||
free(client->req_opts);
|
free(client->req_opts);
|
||||||
free(client->hostname);
|
free(client->hostname);
|
||||||
free(client->vendor_class_identifier);
|
free(client->vendor_class_identifier);
|
||||||
free(client);
|
return mfree(client);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_new(sd_dhcp_client **ret) {
|
int sd_dhcp_client_new(sd_dhcp_client **ret) {
|
||||||
|
@@ -284,9 +284,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
|
|||||||
free(lease->static_route);
|
free(lease->static_route);
|
||||||
free(lease->client_id);
|
free(lease->client_id);
|
||||||
free(lease->vendor_specific);
|
free(lease->vendor_specific);
|
||||||
free(lease);
|
return mfree(lease);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
|
static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
|
||||||
|
@@ -1304,9 +1304,7 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
|
|||||||
sd_dhcp6_client_detach_event(client);
|
sd_dhcp6_client_detach_event(client);
|
||||||
|
|
||||||
free(client->req_opts);
|
free(client->req_opts);
|
||||||
free(client);
|
return mfree(client);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
|
int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
|
||||||
|
@@ -391,9 +391,7 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
|
|||||||
free(lease->ntp);
|
free(lease->ntp);
|
||||||
|
|
||||||
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
|
lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
|
||||||
free(lease);
|
return mfree(lease);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_lease_new(sd_dhcp6_lease **ret) {
|
int dhcp6_lease_new(sd_dhcp6_lease **ret) {
|
||||||
|
@@ -137,9 +137,7 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) {
|
|||||||
ipv4acd_reset(acd);
|
ipv4acd_reset(acd);
|
||||||
sd_ipv4acd_detach_event(acd);
|
sd_ipv4acd_detach_event(acd);
|
||||||
|
|
||||||
free(acd);
|
return mfree(acd);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_ipv4acd_new(sd_ipv4acd **ret) {
|
int sd_ipv4acd_new(sd_ipv4acd **ret) {
|
||||||
|
@@ -92,9 +92,7 @@ sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sd_ipv4acd_unref(ll->acd);
|
sd_ipv4acd_unref(ll->acd);
|
||||||
free(ll);
|
return mfree(ll);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_ipv4ll_new(sd_ipv4ll **ret) {
|
int sd_ipv4ll_new(sd_ipv4ll **ret) {
|
||||||
|
@@ -376,9 +376,7 @@ _public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) {
|
|||||||
|
|
||||||
hashmap_free(lldp->neighbor_by_id);
|
hashmap_free(lldp->neighbor_by_id);
|
||||||
prioq_free(lldp->neighbor_by_expiry);
|
prioq_free(lldp->neighbor_by_expiry);
|
||||||
free(lldp);
|
return mfree(lldp);
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_lldp_new(sd_lldp **ret) {
|
_public_ int sd_lldp_new(sd_lldp **ret) {
|
||||||
|
@@ -197,4 +197,17 @@ int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {
|
|||||||
|
|
||||||
return id128_write_fd(fd, f, id, do_sync);
|
return id128_write_fd(fd, f, id, do_sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void id128_hash_func(const void *p, struct siphash *state) {
|
||||||
|
siphash24_compress(p, 16, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int id128_compare_func(const void *a, const void *b) {
|
||||||
|
return memcmp(a, b, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct hash_ops id128_hash_ops = {
|
||||||
|
.hash = id128_hash_func,
|
||||||
|
.compare = id128_compare_func,
|
||||||
|
};
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
@@ -22,6 +22,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
#include "hash-funcs.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
|
||||||
char *id128_to_uuid_string(sd_id128_t id, char s[37]);
|
char *id128_to_uuid_string(sd_id128_t id, char s[37]);
|
||||||
@@ -43,3 +45,7 @@ int id128_read(const char *p, Id128Format f, sd_id128_t *ret);
|
|||||||
|
|
||||||
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync);
|
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync);
|
||||||
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
|
int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
|
||||||
|
|
||||||
|
void id128_hash_func(const void *p, struct siphash *state);
|
||||||
|
int id128_compare_func(const void *a, const void *b) _pure_;
|
||||||
|
extern const struct hash_ops id128_hash_ops;
|
||||||
|
@@ -134,6 +134,28 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
|
_public_ int sd_id128_get_invocation(sd_id128_t *ret) {
|
||||||
|
static thread_local sd_id128_t saved_invocation_id = {};
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
|
if (sd_id128_is_null(saved_invocation_id)) {
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
e = secure_getenv("INVOCATION_ID");
|
||||||
|
if (!e)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
r = sd_id128_from_string(e, &saved_invocation_id);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = saved_invocation_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static sd_id128_t make_v4_uuid(sd_id128_t id) {
|
static sd_id128_t make_v4_uuid(sd_id128_t id) {
|
||||||
/* Stolen from generate_random_uuid() of drivers/char/random.c
|
/* Stolen from generate_random_uuid() of drivers/char/random.c
|
||||||
* in the kernel sources */
|
* in the kernel sources */
|
||||||
|
@@ -45,8 +45,8 @@ int sd_id128_from_string(const char *s, sd_id128_t *ret);
|
|||||||
int sd_id128_randomize(sd_id128_t *ret);
|
int sd_id128_randomize(sd_id128_t *ret);
|
||||||
|
|
||||||
int sd_id128_get_machine(sd_id128_t *ret);
|
int sd_id128_get_machine(sd_id128_t *ret);
|
||||||
|
|
||||||
int sd_id128_get_boot(sd_id128_t *ret);
|
int sd_id128_get_boot(sd_id128_t *ret);
|
||||||
|
int sd_id128_get_invocation(sd_id128_t *ret);
|
||||||
|
|
||||||
#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
|
#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
|
||||||
((const sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
|
((const sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
|
||||||
|
Reference in New Issue
Block a user