systemd: merge branch systemd into master
https://github.com/NetworkManager/NetworkManager/pull/186
This commit is contained in:
@@ -1374,14 +1374,12 @@ src_libsystemd_nm_la_SOURCES = \
|
|||||||
src/systemd/sd-adapt/def.h \
|
src/systemd/sd-adapt/def.h \
|
||||||
src/systemd/sd-adapt/device-nodes.h \
|
src/systemd/sd-adapt/device-nodes.h \
|
||||||
src/systemd/sd-adapt/dirent-util.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/errno-list.h \
|
||||||
src/systemd/sd-adapt/format-util.h \
|
src/systemd/sd-adapt/format-util.h \
|
||||||
src/systemd/sd-adapt/glob-util.h \
|
src/systemd/sd-adapt/glob-util.h \
|
||||||
src/systemd/sd-adapt/gunicode.h \
|
src/systemd/sd-adapt/gunicode.h \
|
||||||
src/systemd/sd-adapt/ioprio.h \
|
src/systemd/sd-adapt/ioprio.h \
|
||||||
src/systemd/sd-adapt/khash.h \
|
src/systemd/sd-adapt/khash.h \
|
||||||
src/systemd/sd-adapt/libudev.h \
|
|
||||||
src/systemd/sd-adapt/locale-util.h \
|
src/systemd/sd-adapt/locale-util.h \
|
||||||
src/systemd/sd-adapt/memfd-util.h \
|
src/systemd/sd-adapt/memfd-util.h \
|
||||||
src/systemd/sd-adapt/missing.h \
|
src/systemd/sd-adapt/missing.h \
|
||||||
@@ -1389,16 +1387,17 @@ src_libsystemd_nm_la_SOURCES = \
|
|||||||
src/systemd/sd-adapt/procfs-util.h \
|
src/systemd/sd-adapt/procfs-util.h \
|
||||||
src/systemd/sd-adapt/raw-clone.h \
|
src/systemd/sd-adapt/raw-clone.h \
|
||||||
src/systemd/sd-adapt/sd-daemon.h \
|
src/systemd/sd-adapt/sd-daemon.h \
|
||||||
|
src/systemd/sd-adapt/sd-device.h \
|
||||||
src/systemd/sd-adapt/stat-util.h \
|
src/systemd/sd-adapt/stat-util.h \
|
||||||
src/systemd/sd-adapt/terminal-util.h \
|
src/systemd/sd-adapt/terminal-util.h \
|
||||||
src/systemd/sd-adapt/udev-util.h \
|
|
||||||
src/systemd/sd-adapt/udev.h \
|
|
||||||
src/systemd/sd-adapt/unaligned.h \
|
src/systemd/sd-adapt/unaligned.h \
|
||||||
src/systemd/sd-adapt/user-util.h \
|
src/systemd/sd-adapt/user-util.h \
|
||||||
src/systemd/sd-adapt/virt.h \
|
src/systemd/sd-adapt/virt.h \
|
||||||
src/systemd/src/basic/alloc-util.c \
|
src/systemd/src/basic/alloc-util.c \
|
||||||
src/systemd/src/basic/alloc-util.h \
|
src/systemd/src/basic/alloc-util.h \
|
||||||
src/systemd/src/basic/async.h \
|
src/systemd/src/basic/async.h \
|
||||||
|
src/systemd/src/basic/env-util.c \
|
||||||
|
src/systemd/src/basic/env-util.h \
|
||||||
src/systemd/src/basic/escape.c \
|
src/systemd/src/basic/escape.c \
|
||||||
src/systemd/src/basic/escape.h \
|
src/systemd/src/basic/escape.h \
|
||||||
src/systemd/src/basic/ether-addr-util.c \
|
src/systemd/src/basic/ether-addr-util.c \
|
||||||
|
@@ -1,10 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@ sources = files(
|
|||||||
'sd-adapt/nm-sd-adapt.c',
|
'sd-adapt/nm-sd-adapt.c',
|
||||||
'src/basic/alloc-util.c',
|
'src/basic/alloc-util.c',
|
||||||
'src/basic/escape.c',
|
'src/basic/escape.c',
|
||||||
|
'src/basic/env-util.c',
|
||||||
'src/basic/ether-addr-util.c',
|
'src/basic/ether-addr-util.c',
|
||||||
'src/basic/extract-word.c',
|
'src/basic/extract-word.c',
|
||||||
'src/basic/fd-util.c',
|
'src/basic/fd-util.c',
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/* dummy header */
|
|
||||||
|
|
||||||
struct udev_device;
|
|
@@ -1,3 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/* dummy header */
|
|
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
/* dummy header */
|
|
||||||
|
|
||||||
#include "libudev.h"
|
|
||||||
#include "strv.h"
|
|
791
src/systemd/src/basic/env-util.c
Normal file
791
src/systemd/src/basic/env-util.c
Normal file
@@ -0,0 +1,791 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "env-util.h"
|
||||||
|
#include "escape.h"
|
||||||
|
#include "extract-word.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
|
#define VALID_CHARS_ENV_NAME \
|
||||||
|
DIGITS LETTERS \
|
||||||
|
"_"
|
||||||
|
|
||||||
|
#ifndef ARG_MAX
|
||||||
|
#define ARG_MAX ((size_t) sysconf(_SC_ARG_MAX))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool env_name_is_valid_n(const char *e, size_t n) {
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
if (!e)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (n <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (e[0] >= '0' && e[0] <= '9')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* POSIX says the overall size of the environment block cannot
|
||||||
|
* be > ARG_MAX, an individual assignment hence cannot be
|
||||||
|
* either. Discounting the equal sign and trailing NUL this
|
||||||
|
* hence leaves ARG_MAX-2 as longest possible variable
|
||||||
|
* name. */
|
||||||
|
if (n > ARG_MAX - 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (p = e; p < e + n; p++)
|
||||||
|
if (!strchr(VALID_CHARS_ENV_NAME, *p))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool env_name_is_valid(const char *e) {
|
||||||
|
if (!e)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return env_name_is_valid_n(e, strlen(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool env_value_is_valid(const char *e) {
|
||||||
|
if (!e)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!utf8_is_valid(e))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* bash allows tabs and newlines in environment variables, and so
|
||||||
|
* should we */
|
||||||
|
if (string_has_cc(e, "\t\n"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* POSIX says the overall size of the environment block cannot
|
||||||
|
* be > ARG_MAX, an individual assignment hence cannot be
|
||||||
|
* either. Discounting the shortest possible variable name of
|
||||||
|
* length 1, the equal sign and trailing NUL this hence leaves
|
||||||
|
* ARG_MAX-3 as longest possible variable value. */
|
||||||
|
if (strlen(e) > ARG_MAX - 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool env_assignment_is_valid(const char *e) {
|
||||||
|
const char *eq;
|
||||||
|
|
||||||
|
eq = strchr(e, '=');
|
||||||
|
if (!eq)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!env_name_is_valid_n(e, eq - e))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!env_value_is_valid(eq + 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* POSIX says the overall size of the environment block cannot
|
||||||
|
* be > ARG_MAX, hence the individual variable assignments
|
||||||
|
* cannot be either, but let's leave room for one trailing NUL
|
||||||
|
* byte. */
|
||||||
|
if (strlen(e) > ARG_MAX - 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strv_env_is_valid(char **e) {
|
||||||
|
char **p, **q;
|
||||||
|
|
||||||
|
STRV_FOREACH(p, e) {
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
if (!env_assignment_is_valid(*p))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Check if there are duplicate assginments */
|
||||||
|
k = strcspn(*p, "=");
|
||||||
|
STRV_FOREACH(q, p + 1)
|
||||||
|
if (strneq(*p, *q, k) && (*q)[k] == '=')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strv_env_name_is_valid(char **l) {
|
||||||
|
char **p, **q;
|
||||||
|
|
||||||
|
STRV_FOREACH(p, l) {
|
||||||
|
if (!env_name_is_valid(*p))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
STRV_FOREACH(q, p + 1)
|
||||||
|
if (streq(*p, *q))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strv_env_name_or_assignment_is_valid(char **l) {
|
||||||
|
char **p, **q;
|
||||||
|
|
||||||
|
STRV_FOREACH(p, l) {
|
||||||
|
if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
STRV_FOREACH(q, p + 1)
|
||||||
|
if (streq(*p, *q))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int env_append(char **r, char ***k, char **a) {
|
||||||
|
assert(r);
|
||||||
|
assert(k);
|
||||||
|
|
||||||
|
if (!a)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Add the entries of a to *k unless they already exist in *r
|
||||||
|
* in which case they are overridden instead. This assumes
|
||||||
|
* there is enough space in the r array. */
|
||||||
|
|
||||||
|
for (; *a; a++) {
|
||||||
|
char **j;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
n = strcspn(*a, "=");
|
||||||
|
|
||||||
|
if ((*a)[n] == '=')
|
||||||
|
n++;
|
||||||
|
|
||||||
|
for (j = r; j < *k; j++)
|
||||||
|
if (strneq(*j, *a, n))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (j >= *k)
|
||||||
|
(*k)++;
|
||||||
|
else
|
||||||
|
free(*j);
|
||||||
|
|
||||||
|
*j = strdup(*a);
|
||||||
|
if (!*j)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_merge(size_t n_lists, ...) {
|
||||||
|
size_t n = 0;
|
||||||
|
char **l, **k, **r;
|
||||||
|
va_list ap;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Merges an arbitrary number of environment sets */
|
||||||
|
|
||||||
|
va_start(ap, n_lists);
|
||||||
|
for (i = 0; i < n_lists; i++) {
|
||||||
|
l = va_arg(ap, char**);
|
||||||
|
n += strv_length(l);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
r = new(char*, n+1);
|
||||||
|
if (!r)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
k = r;
|
||||||
|
|
||||||
|
va_start(ap, n_lists);
|
||||||
|
for (i = 0; i < n_lists; i++) {
|
||||||
|
l = va_arg(ap, char**);
|
||||||
|
if (env_append(r, &k, l) < 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
*k = NULL;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
va_end(ap);
|
||||||
|
strv_free(r);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool env_match(const char *t, const char *pattern) {
|
||||||
|
assert(t);
|
||||||
|
assert(pattern);
|
||||||
|
|
||||||
|
/* pattern a matches string a
|
||||||
|
* a matches a=
|
||||||
|
* a matches a=b
|
||||||
|
* a= matches a=
|
||||||
|
* a=b matches a=b
|
||||||
|
* a= does not match a
|
||||||
|
* a=b does not match a=
|
||||||
|
* a=b does not match a
|
||||||
|
* a=b does not match a=c */
|
||||||
|
|
||||||
|
if (streq(t, pattern))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!strchr(pattern, '=')) {
|
||||||
|
size_t l = strlen(pattern);
|
||||||
|
|
||||||
|
return strneq(t, pattern, l) && t[l] == '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool env_entry_has_name(const char *entry, const char *name) {
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
assert(entry);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
t = startswith(entry, name);
|
||||||
|
if (!t)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return *t == '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_delete(char **x, size_t n_lists, ...) {
|
||||||
|
size_t n, i = 0;
|
||||||
|
char **k, **r;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
/* Deletes every entry from x that is mentioned in the other
|
||||||
|
* string lists */
|
||||||
|
|
||||||
|
n = strv_length(x);
|
||||||
|
|
||||||
|
r = new(char*, n+1);
|
||||||
|
if (!r)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
STRV_FOREACH(k, x) {
|
||||||
|
size_t v;
|
||||||
|
|
||||||
|
va_start(ap, n_lists);
|
||||||
|
for (v = 0; v < n_lists; v++) {
|
||||||
|
char **l, **j;
|
||||||
|
|
||||||
|
l = va_arg(ap, char**);
|
||||||
|
STRV_FOREACH(j, l)
|
||||||
|
if (env_match(*k, *j))
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
r[i] = strdup(*k);
|
||||||
|
if (!r[i]) {
|
||||||
|
strv_free(r);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skip:
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
r[i] = NULL;
|
||||||
|
|
||||||
|
assert(i <= n);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_unset(char **l, const char *p) {
|
||||||
|
|
||||||
|
char **f, **t;
|
||||||
|
|
||||||
|
if (!l)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
/* Drops every occurrence of the env var setting p in the
|
||||||
|
* string list. Edits in-place. */
|
||||||
|
|
||||||
|
for (f = t = l; *f; f++) {
|
||||||
|
|
||||||
|
if (env_match(*f, p)) {
|
||||||
|
free(*f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(t++) = *f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = NULL;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_unset_many(char **l, ...) {
|
||||||
|
|
||||||
|
char **f, **t;
|
||||||
|
|
||||||
|
if (!l)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Like strv_env_unset() but applies many at once. Edits in-place. */
|
||||||
|
|
||||||
|
for (f = t = l; *f; f++) {
|
||||||
|
bool found = false;
|
||||||
|
const char *p;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, l);
|
||||||
|
|
||||||
|
while ((p = va_arg(ap, const char*))) {
|
||||||
|
if (env_match(*f, p)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
free(*f);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(t++) = *f;
|
||||||
|
}
|
||||||
|
|
||||||
|
*t = NULL;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strv_env_replace(char ***l, char *p) {
|
||||||
|
char **f;
|
||||||
|
const char *t, *name;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
/* Replace first occurrence of the env var or add a new one in the
|
||||||
|
* string list. Drop other occurences. Edits in-place. Does not copy p.
|
||||||
|
* p must be a valid key=value assignment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
t = strchr(p, '=');
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
name = strndupa(p, t - p);
|
||||||
|
|
||||||
|
for (f = *l; f && *f; f++)
|
||||||
|
if (env_entry_has_name(*f, name)) {
|
||||||
|
free_and_replace(*f, p);
|
||||||
|
strv_env_unset(f + 1, *f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We didn't find a match, we need to append p or create a new strv */
|
||||||
|
if (strv_push(l, p) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_set(char **x, const char *p) {
|
||||||
|
|
||||||
|
char **k;
|
||||||
|
_cleanup_strv_free_ char **r = NULL;
|
||||||
|
char* m[2] = { (char*) p, NULL };
|
||||||
|
|
||||||
|
/* Overrides the env var setting of p, returns a new copy */
|
||||||
|
|
||||||
|
r = new(char*, strv_length(x)+2);
|
||||||
|
if (!r)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
k = r;
|
||||||
|
if (env_append(r, &k, x) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (env_append(r, &k, m) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*k = NULL;
|
||||||
|
|
||||||
|
return TAKE_PTR(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
|
||||||
|
char **i;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
if (k <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
STRV_FOREACH_BACKWARDS(i, l)
|
||||||
|
if (strneq(*i, name, k) &&
|
||||||
|
(*i)[k] == '=')
|
||||||
|
return *i + k + 1;
|
||||||
|
|
||||||
|
if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
t = strndupa(name, k);
|
||||||
|
return getenv(t);
|
||||||
|
};
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strv_env_get(char **l, const char *name) {
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
return strv_env_get_n(l, name, strlen(name), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) {
|
||||||
|
char **p, **q;
|
||||||
|
int k = 0;
|
||||||
|
|
||||||
|
STRV_FOREACH(p, e) {
|
||||||
|
size_t n;
|
||||||
|
bool duplicate = false;
|
||||||
|
|
||||||
|
if (!env_assignment_is_valid(*p)) {
|
||||||
|
if (invalid_callback)
|
||||||
|
invalid_callback(*p, userdata);
|
||||||
|
free(*p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = strcspn(*p, "=");
|
||||||
|
STRV_FOREACH(q, p + 1)
|
||||||
|
if (strneq(*p, *q, n) && (*q)[n] == '=') {
|
||||||
|
duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (duplicate) {
|
||||||
|
free(*p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
e[k++] = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e)
|
||||||
|
e[k] = NULL;
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
|
||||||
|
enum {
|
||||||
|
WORD,
|
||||||
|
CURLY,
|
||||||
|
VARIABLE,
|
||||||
|
VARIABLE_RAW,
|
||||||
|
TEST,
|
||||||
|
DEFAULT_VALUE,
|
||||||
|
ALTERNATE_VALUE,
|
||||||
|
} state = WORD;
|
||||||
|
|
||||||
|
const char *e, *word = format, *test_value;
|
||||||
|
char *k;
|
||||||
|
_cleanup_free_ char *r = NULL;
|
||||||
|
size_t i, len;
|
||||||
|
int nest = 0;
|
||||||
|
|
||||||
|
assert(format);
|
||||||
|
|
||||||
|
for (e = format, i = 0; *e && i < n; e ++, i ++)
|
||||||
|
switch (state) {
|
||||||
|
|
||||||
|
case WORD:
|
||||||
|
if (*e == '$')
|
||||||
|
state = CURLY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURLY:
|
||||||
|
if (*e == '{') {
|
||||||
|
k = strnappend(r, word, e-word-1);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e-1;
|
||||||
|
state = VARIABLE;
|
||||||
|
nest++;
|
||||||
|
} else if (*e == '$') {
|
||||||
|
k = strnappend(r, word, e-word);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e+1;
|
||||||
|
state = WORD;
|
||||||
|
|
||||||
|
} else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
|
||||||
|
k = strnappend(r, word, e-word-1);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e-1;
|
||||||
|
state = VARIABLE_RAW;
|
||||||
|
|
||||||
|
} else
|
||||||
|
state = WORD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VARIABLE:
|
||||||
|
if (*e == '}') {
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
t = strv_env_get_n(env, word+2, e-word-2, flags);
|
||||||
|
|
||||||
|
k = strappend(r, t);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e+1;
|
||||||
|
state = WORD;
|
||||||
|
} else if (*e == ':') {
|
||||||
|
if (!(flags & REPLACE_ENV_ALLOW_EXTENDED))
|
||||||
|
/* Treat this as unsupported syntax, i.e. do no replacement */
|
||||||
|
state = WORD;
|
||||||
|
else {
|
||||||
|
len = e-word-2;
|
||||||
|
state = TEST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEST:
|
||||||
|
if (*e == '-')
|
||||||
|
state = DEFAULT_VALUE;
|
||||||
|
else if (*e == '+')
|
||||||
|
state = ALTERNATE_VALUE;
|
||||||
|
else {
|
||||||
|
state = WORD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_value = e+1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEFAULT_VALUE: /* fall through */
|
||||||
|
case ALTERNATE_VALUE:
|
||||||
|
assert(flags & REPLACE_ENV_ALLOW_EXTENDED);
|
||||||
|
|
||||||
|
if (*e == '{') {
|
||||||
|
nest++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*e != '}')
|
||||||
|
break;
|
||||||
|
|
||||||
|
nest--;
|
||||||
|
if (nest == 0) {
|
||||||
|
const char *t;
|
||||||
|
_cleanup_free_ char *v = NULL;
|
||||||
|
|
||||||
|
t = strv_env_get_n(env, word+2, len, flags);
|
||||||
|
|
||||||
|
if (t && state == ALTERNATE_VALUE)
|
||||||
|
t = v = replace_env_n(test_value, e-test_value, env, flags);
|
||||||
|
else if (!t && state == DEFAULT_VALUE)
|
||||||
|
t = v = replace_env_n(test_value, e-test_value, env, flags);
|
||||||
|
|
||||||
|
k = strappend(r, t);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e+1;
|
||||||
|
state = WORD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VARIABLE_RAW:
|
||||||
|
assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
|
||||||
|
|
||||||
|
if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
t = strv_env_get_n(env, word+1, e-word-1, flags);
|
||||||
|
|
||||||
|
k = strappend(r, t);
|
||||||
|
if (!k)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
free_and_replace(r, k);
|
||||||
|
|
||||||
|
word = e--;
|
||||||
|
i--;
|
||||||
|
state = WORD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == VARIABLE_RAW) {
|
||||||
|
const char *t;
|
||||||
|
|
||||||
|
assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
|
||||||
|
|
||||||
|
t = strv_env_get_n(env, word+1, e-word-1, flags);
|
||||||
|
return strappend(r, t);
|
||||||
|
} else
|
||||||
|
return strnappend(r, word, e-word);
|
||||||
|
}
|
||||||
|
|
||||||
|
char **replace_env_argv(char **argv, char **env) {
|
||||||
|
char **ret, **i;
|
||||||
|
size_t k = 0, l = 0;
|
||||||
|
|
||||||
|
l = strv_length(argv);
|
||||||
|
|
||||||
|
ret = new(char*, l+1);
|
||||||
|
if (!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
STRV_FOREACH(i, argv) {
|
||||||
|
|
||||||
|
/* If $FOO appears as single word, replace it by the split up variable */
|
||||||
|
if ((*i)[0] == '$' && !IN_SET((*i)[1], '{', '$')) {
|
||||||
|
char *e;
|
||||||
|
char **w, **m = NULL;
|
||||||
|
size_t q;
|
||||||
|
|
||||||
|
e = strv_env_get(env, *i+1);
|
||||||
|
if (e) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES);
|
||||||
|
if (r < 0) {
|
||||||
|
ret[k] = NULL;
|
||||||
|
strv_free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
m = NULL;
|
||||||
|
|
||||||
|
q = strv_length(m);
|
||||||
|
l = l + q - 1;
|
||||||
|
|
||||||
|
w = reallocarray(ret, l + 1, sizeof(char *));
|
||||||
|
if (!w) {
|
||||||
|
ret[k] = NULL;
|
||||||
|
strv_free(ret);
|
||||||
|
strv_free(m);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = w;
|
||||||
|
if (m) {
|
||||||
|
memcpy(ret + k, m, q * sizeof(char*));
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
k += q;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If ${FOO} appears as part of a word, replace it by the variable as-is */
|
||||||
|
ret[k] = replace_env(*i, env, 0);
|
||||||
|
if (!ret[k]) {
|
||||||
|
strv_free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[k] = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
|
int getenv_bool(const char *p) {
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
e = getenv(p);
|
||||||
|
if (!e)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
return parse_boolean(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
|
int getenv_bool_secure(const char *p) {
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
e = secure_getenv(p);
|
||||||
|
if (!e)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
return parse_boolean(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serialize_environment(FILE *f, char **environment) {
|
||||||
|
char **e;
|
||||||
|
|
||||||
|
STRV_FOREACH(e, environment) {
|
||||||
|
_cleanup_free_ char *ce;
|
||||||
|
|
||||||
|
ce = cescape(*e);
|
||||||
|
if (!ce)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
fprintf(f, "env=%s\n", ce);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* caller should call ferror() */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int deserialize_environment(char ***environment, const char *line) {
|
||||||
|
char *uce;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(line);
|
||||||
|
assert(environment);
|
||||||
|
|
||||||
|
assert(startswith(line, "env="));
|
||||||
|
r = cunescape(line + 4, 0, &uce);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return strv_env_replace(environment, uce);
|
||||||
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
50
src/systemd/src/basic/env-util.h
Normal file
50
src/systemd/src/basic/env-util.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
bool env_name_is_valid(const char *e);
|
||||||
|
bool env_value_is_valid(const char *e);
|
||||||
|
bool env_assignment_is_valid(const char *e);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
REPLACE_ENV_USE_ENVIRONMENT = 1u,
|
||||||
|
REPLACE_ENV_ALLOW_BRACELESS = 2u,
|
||||||
|
REPLACE_ENV_ALLOW_EXTENDED = 4u,
|
||||||
|
};
|
||||||
|
|
||||||
|
char *replace_env_n(const char *format, size_t n, char **env, unsigned flags);
|
||||||
|
char **replace_env_argv(char **argv, char **env);
|
||||||
|
|
||||||
|
static inline char *replace_env(const char *format, char **env, unsigned flags) {
|
||||||
|
return replace_env_n(format, strlen(format), env, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool strv_env_is_valid(char **e);
|
||||||
|
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
|
||||||
|
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
|
||||||
|
|
||||||
|
bool strv_env_name_is_valid(char **l);
|
||||||
|
bool strv_env_name_or_assignment_is_valid(char **l);
|
||||||
|
|
||||||
|
char **strv_env_merge(size_t n_lists, ...);
|
||||||
|
char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */
|
||||||
|
|
||||||
|
char **strv_env_set(char **x, const char *p); /* New copy ... */
|
||||||
|
char **strv_env_unset(char **l, const char *p); /* In place ... */
|
||||||
|
char **strv_env_unset_many(char **l, ...) _sentinel_;
|
||||||
|
int strv_env_replace(char ***l, char *p); /* In place ... */
|
||||||
|
|
||||||
|
char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
|
||||||
|
char *strv_env_get(char **x, const char *n) _pure_;
|
||||||
|
|
||||||
|
int getenv_bool(const char *p);
|
||||||
|
int getenv_bool_secure(const char *p);
|
||||||
|
|
||||||
|
int serialize_environment(FILE *f, char **environment);
|
||||||
|
int deserialize_environment(char ***environment, const char *line);
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,10 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
@@ -78,8 +78,12 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags);
|
|||||||
int fd_duplicate_data_fd(int fd);
|
int fd_duplicate_data_fd(int fd);
|
||||||
|
|
||||||
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
|
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
|
||||||
|
/* The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.
|
||||||
|
* See the icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */
|
||||||
#define ERRNO_IS_DISCONNECT(r) \
|
#define ERRNO_IS_DISCONNECT(r) \
|
||||||
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
|
IN_SET(r, \
|
||||||
|
ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \
|
||||||
|
ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, ENONET)
|
||||||
|
|
||||||
/* Resource exhaustion, could be our fault or general system trouble */
|
/* Resource exhaustion, could be our fault or general system trouble */
|
||||||
#define ERRNO_IS_RESOURCE(r) \
|
#define ERRNO_IS_RESOURCE(r) \
|
||||||
|
@@ -1235,9 +1235,13 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
|
|||||||
const char *fn;
|
const char *fn;
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
assert(p);
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
|
if (isempty(p))
|
||||||
|
return -EINVAL;
|
||||||
|
if (path_equal(p, "/"))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Turns this:
|
* Turns this:
|
||||||
* /foo/bar/waldo
|
* /foo/bar/waldo
|
||||||
@@ -1269,9 +1273,13 @@ int tempfn_random(const char *p, const char *extra, char **ret) {
|
|||||||
uint64_t u;
|
uint64_t u;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
assert(p);
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
|
if (isempty(p))
|
||||||
|
return -EINVAL;
|
||||||
|
if (path_equal(p, "/"))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Turns this:
|
* Turns this:
|
||||||
* /foo/bar/waldo
|
* /foo/bar/waldo
|
||||||
@@ -1330,6 +1338,9 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) {
|
|||||||
if (!t)
|
if (!t)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (isempty(p))
|
||||||
|
x = stpcpy(stpcpy(t, ".#"), extra);
|
||||||
|
else
|
||||||
x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
|
x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
|
||||||
|
|
||||||
u = random_u64();
|
u = random_u64();
|
||||||
@@ -1417,7 +1428,8 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
|
|||||||
r = tmp_dir(&directory);
|
r = tmp_dir(&directory);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
} else if (isempty(directory))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */
|
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */
|
||||||
|
|
||||||
@@ -1452,21 +1464,13 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
|
|||||||
* which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
|
* which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
|
||||||
* "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
|
* "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
|
||||||
|
|
||||||
{
|
fd = open_parent(target, O_TMPFILE|flags, 0640);
|
||||||
_cleanup_free_ char *dn = NULL;
|
|
||||||
|
|
||||||
dn = dirname_malloc(target);
|
|
||||||
if (!dn)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
fd = open(dn, O_TMPFILE|flags, 0640);
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
*ret_path = NULL;
|
*ret_path = NULL;
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
|
log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target);
|
||||||
}
|
|
||||||
|
|
||||||
r = tempfn_random(target, NULL, &tmp);
|
r = tempfn_random(target, NULL, &tmp);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@@ -442,6 +442,31 @@ int mkfifo_atomic(const char *path, mode_t mode) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) {
|
||||||
|
_cleanup_free_ char *t = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(path);
|
||||||
|
|
||||||
|
if (path_is_absolute(path))
|
||||||
|
return mkfifo_atomic(path, mode);
|
||||||
|
|
||||||
|
/* We're only interested in the (random) filename. */
|
||||||
|
r = tempfn_random_child("", NULL, &t);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (mkfifoat(dirfd, t, mode) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (renameat(dirfd, t, dirfd, path) < 0) {
|
||||||
|
unlink_noerrno(t);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int get_files_in_directory(const char *path, char ***list) {
|
int get_files_in_directory(const char *path, char ***list) {
|
||||||
_cleanup_closedir_ DIR *d = NULL;
|
_cleanup_closedir_ DIR *d = NULL;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@@ -679,7 +704,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) {
|
if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) {
|
||||||
/* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set
|
/* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set
|
||||||
* and doesn't care about any of the other special features we provide either. */
|
* and doesn't care about any of the other special features we provide either. */
|
||||||
r = open(path, O_PATH|O_CLOEXEC);
|
r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@@ -834,7 +859,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|||||||
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
|
fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
|
||||||
return -EREMOTE;
|
return -EREMOTE;
|
||||||
|
|
||||||
if (S_ISLNK(st.st_mode)) {
|
if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) {
|
||||||
char *joined;
|
char *joined;
|
||||||
|
|
||||||
_cleanup_free_ char *destination = NULL;
|
_cleanup_free_ char *destination = NULL;
|
||||||
@@ -1165,7 +1190,7 @@ int unlinkat_deallocate(int fd, const char *name, int flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int fsync_directory_of_file(int fd) {
|
int fsync_directory_of_file(int fd) {
|
||||||
_cleanup_free_ char *path = NULL, *dn = NULL;
|
_cleanup_free_ char *path = NULL;
|
||||||
_cleanup_close_ int dfd = -1;
|
_cleanup_close_ int dfd = -1;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -1191,17 +1216,41 @@ int fsync_directory_of_file(int fd) {
|
|||||||
if (!path_is_absolute(path))
|
if (!path_is_absolute(path))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dn = dirname_malloc(path);
|
dfd = open_parent(path, O_CLOEXEC, 0);
|
||||||
if (!dn)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
|
|
||||||
if (dfd < 0)
|
if (dfd < 0)
|
||||||
return -errno;
|
return dfd;
|
||||||
|
|
||||||
if (fsync(dfd) < 0)
|
if (fsync(dfd) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int open_parent(const char *path, int flags, mode_t mode) {
|
||||||
|
_cleanup_free_ char *parent = NULL;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (isempty(path))
|
||||||
|
return -EINVAL;
|
||||||
|
if (path_equal(path, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
parent = dirname_malloc(path);
|
||||||
|
if (!parent)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an
|
||||||
|
* O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */
|
||||||
|
|
||||||
|
if ((flags & O_PATH) == O_PATH)
|
||||||
|
flags |= O_DIRECTORY;
|
||||||
|
else if ((flags & O_TMPFILE) != O_TMPFILE)
|
||||||
|
flags |= O_DIRECTORY|O_RDONLY;
|
||||||
|
|
||||||
|
fd = open(parent, flags, mode);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
@@ -42,6 +42,7 @@ int symlink_idempotent(const char *from, const char *to);
|
|||||||
int symlink_atomic(const char *from, const char *to);
|
int symlink_atomic(const char *from, const char *to);
|
||||||
int mknod_atomic(const char *path, mode_t mode, dev_t dev);
|
int mknod_atomic(const char *path, mode_t mode, dev_t dev);
|
||||||
int mkfifo_atomic(const char *path, mode_t mode);
|
int mkfifo_atomic(const char *path, mode_t mode);
|
||||||
|
int mkfifoat_atomic(int dir_fd, const char *path, mode_t mode);
|
||||||
|
|
||||||
int get_files_in_directory(const char *path, char ***list);
|
int get_files_in_directory(const char *path, char ***list);
|
||||||
|
|
||||||
@@ -72,6 +73,7 @@ enum {
|
|||||||
CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */
|
CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */
|
||||||
CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
|
CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */
|
||||||
CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */
|
CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */
|
||||||
|
CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* How many iterations to execute before returning -ELOOP */
|
/* How many iterations to execute before returning -ELOOP */
|
||||||
@@ -103,3 +105,5 @@ void unlink_tempfilep(char (*p)[]);
|
|||||||
int unlinkat_deallocate(int fd, const char *name, int flags);
|
int unlinkat_deallocate(int fd, const char *name, int flags);
|
||||||
|
|
||||||
int fsync_directory_of_file(int fd);
|
int fsync_directory_of_file(int fd);
|
||||||
|
|
||||||
|
int open_parent(const char *path, int flags, mode_t mode);
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
@@ -78,7 +75,7 @@ void trivial_hash_func(const void *p, struct siphash *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int trivial_compare_func(const void *a, const void *b) {
|
int trivial_compare_func(const void *a, const void *b) {
|
||||||
return a < b ? -1 : (a > b ? 1 : 0);
|
return CMP(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct hash_ops trivial_hash_ops = {
|
const struct hash_ops trivial_hash_ops = {
|
||||||
@@ -94,7 +91,7 @@ int uint64_compare_func(const void *_a, const void *_b) {
|
|||||||
uint64_t a, b;
|
uint64_t a, b;
|
||||||
a = *(const uint64_t*) _a;
|
a = *(const uint64_t*) _a;
|
||||||
b = *(const uint64_t*) _b;
|
b = *(const uint64_t*) _b;
|
||||||
return a < b ? -1 : (a > b ? 1 : 0);
|
return CMP(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct hash_ops uint64_hash_ops = {
|
const struct hash_ops uint64_hash_ops = {
|
||||||
@@ -112,7 +109,7 @@ int devt_compare_func(const void *_a, const void *_b) {
|
|||||||
dev_t a, b;
|
dev_t a, b;
|
||||||
a = *(const dev_t*) _a;
|
a = *(const dev_t*) _a;
|
||||||
b = *(const dev_t*) _b;
|
b = *(const dev_t*) _b;
|
||||||
return a < b ? -1 : (a > b ? 1 : 0);
|
return CMP(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct hash_ops devt_hash_ops = {
|
const struct hash_ops devt_hash_ops = {
|
||||||
|
@@ -1,10 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
|
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
@@ -11,8 +8,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "hashmap.h"
|
#include "env-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "mempool.h"
|
#include "mempool.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
@@ -771,20 +769,31 @@ static void reset_direct_storage(HashmapBase *h) {
|
|||||||
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
|
memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool use_pool(void) {
|
||||||
|
static int b = -1;
|
||||||
|
|
||||||
|
if (!is_main_thread())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (b < 0)
|
||||||
|
b = getenv_bool("SYSTEMD_MEMPOOL") != 0;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
|
static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) {
|
||||||
HashmapBase *h;
|
HashmapBase *h;
|
||||||
const struct hashmap_type_info *hi = &hashmap_type_info[type];
|
const struct hashmap_type_info *hi = &hashmap_type_info[type];
|
||||||
bool use_pool;
|
bool up;
|
||||||
|
|
||||||
use_pool = is_main_thread();
|
up = use_pool();
|
||||||
|
|
||||||
h = use_pool ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
|
|
||||||
|
|
||||||
|
h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size);
|
||||||
if (!h)
|
if (!h)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
h->type = type;
|
h->type = type;
|
||||||
h->from_pool = use_pool;
|
h->from_pool = up;
|
||||||
h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;
|
h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;
|
||||||
|
|
||||||
if (type == HASHMAP_TYPE_ORDERED) {
|
if (type == HASHMAP_TYPE_ORDERED) {
|
||||||
@@ -862,9 +871,11 @@ static void hashmap_free_no_clear(HashmapBase *h) {
|
|||||||
assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
|
assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (h->from_pool)
|
if (h->from_pool) {
|
||||||
|
/* Ensure that the object didn't get migrated between threads. */
|
||||||
|
assert_se(is_main_thread());
|
||||||
mempool_free_tile(hashmap_type_info[h->type].mempool, h);
|
mempool_free_tile(hashmap_type_info[h->type].mempool, h);
|
||||||
else
|
} else
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,10 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@@ -576,4 +576,27 @@ int in_addr_prefix_from_string_auto(
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void in_addr_data_hash_func(const void *p, struct siphash *state) {
|
||||||
|
const struct in_addr_data *a = p;
|
||||||
|
|
||||||
|
siphash24_compress(&a->family, sizeof(a->family), state);
|
||||||
|
siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
int in_addr_data_compare_func(const void *a, const void *b) {
|
||||||
|
const struct in_addr_data *x = a, *y = b;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = CMP(x->family, y->family);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct hash_ops in_addr_data_hash_ops = {
|
||||||
|
.hash = in_addr_data_hash_func,
|
||||||
|
.compare = in_addr_data_compare_func,
|
||||||
|
};
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "hash-funcs.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@@ -53,3 +54,7 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define IN_ADDR_NULL ((union in_addr_union) {})
|
#define IN_ADDR_NULL ((union in_addr_union) {})
|
||||||
|
|
||||||
|
void in_addr_data_hash_func(const void *p, struct siphash *state);
|
||||||
|
int in_addr_data_compare_func(const void *a, const void *b);
|
||||||
|
extern const struct hash_ops in_addr_data_hash_ops;
|
||||||
|
@@ -156,7 +156,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ELEMENTSOF(x) \
|
#define ELEMENTSOF(x) \
|
||||||
__extension__ (__builtin_choose_expr( \
|
(__builtin_choose_expr( \
|
||||||
!__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
|
!__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
|
||||||
sizeof(x)/sizeof((x)[0]), \
|
sizeof(x)/sizeof((x)[0]), \
|
||||||
VOID_0))
|
VOID_0))
|
||||||
@@ -176,7 +176,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
*/
|
*/
|
||||||
#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
|
#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
|
||||||
#define __container_of(uniq, ptr, type, member) \
|
#define __container_of(uniq, ptr, type, member) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
|
const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
|
||||||
(type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \
|
(type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \
|
||||||
})
|
})
|
||||||
@@ -184,7 +184,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
#undef MAX
|
#undef MAX
|
||||||
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
|
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
|
||||||
#define __MAX(aq, a, bq, b) \
|
#define __MAX(aq, a, bq, b) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(a) UNIQ_T(A, aq) = (a); \
|
const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||||
const typeof(b) UNIQ_T(B, bq) = (b); \
|
const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||||
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
|
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
|
||||||
@@ -192,7 +192,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
|
|
||||||
/* evaluates to (void) if _A or _B are not constant or of different types */
|
/* evaluates to (void) if _A or _B are not constant or of different types */
|
||||||
#define CONST_MAX(_A, _B) \
|
#define CONST_MAX(_A, _B) \
|
||||||
__extension__ (__builtin_choose_expr( \
|
(__builtin_choose_expr( \
|
||||||
__builtin_constant_p(_A) && \
|
__builtin_constant_p(_A) && \
|
||||||
__builtin_constant_p(_B) && \
|
__builtin_constant_p(_B) && \
|
||||||
__builtin_types_compatible_p(typeof(_A), typeof(_B)), \
|
__builtin_types_compatible_p(typeof(_A), typeof(_B)), \
|
||||||
@@ -203,7 +203,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
|
#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
|
||||||
|
|
||||||
#define MAX3(x, y, z) \
|
#define MAX3(x, y, z) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(x) _c = MAX(x, y); \
|
const typeof(x) _c = MAX(x, y); \
|
||||||
MAX(_c, z); \
|
MAX(_c, z); \
|
||||||
})
|
})
|
||||||
@@ -211,30 +211,39 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
#undef MIN
|
#undef MIN
|
||||||
#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
|
#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
|
||||||
#define __MIN(aq, a, bq, b) \
|
#define __MIN(aq, a, bq, b) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(a) UNIQ_T(A, aq) = (a); \
|
const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||||
const typeof(b) UNIQ_T(B, bq) = (b); \
|
const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||||
UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
|
UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define MIN3(x, y, z) \
|
#define MIN3(x, y, z) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(x) _c = MIN(x, y); \
|
const typeof(x) _c = MIN(x, y); \
|
||||||
MIN(_c, z); \
|
MIN(_c, z); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
|
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
|
||||||
#define __LESS_BY(aq, a, bq, b) \
|
#define __LESS_BY(aq, a, bq, b) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(a) UNIQ_T(A, aq) = (a); \
|
const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||||
const typeof(b) UNIQ_T(B, bq) = (b); \
|
const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||||
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \
|
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b))
|
||||||
|
#define __CMP(aq, a, bq, b) \
|
||||||
|
({ \
|
||||||
|
const typeof(a) UNIQ_T(A, aq) = (a); \
|
||||||
|
const typeof(b) UNIQ_T(B, bq) = (b); \
|
||||||
|
UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 : \
|
||||||
|
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0; \
|
||||||
|
})
|
||||||
|
|
||||||
#undef CLAMP
|
#undef CLAMP
|
||||||
#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
|
#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
|
||||||
#define __CLAMP(xq, x, lowq, low, highq, high) \
|
#define __CLAMP(xq, x, lowq, low, highq, high) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(x) UNIQ_T(X, xq) = (x); \
|
const typeof(x) UNIQ_T(X, xq) = (x); \
|
||||||
const typeof(low) UNIQ_T(LOW, lowq) = (low); \
|
const typeof(low) UNIQ_T(LOW, lowq) = (low); \
|
||||||
const typeof(high) UNIQ_T(HIGH, highq) = (high); \
|
const typeof(high) UNIQ_T(HIGH, highq) = (high); \
|
||||||
@@ -250,18 +259,54 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
* [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
|
* [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
|
||||||
* quotient and the remainder, so both should be equally fast. */
|
* quotient and the remainder, so both should be equally fast. */
|
||||||
#define DIV_ROUND_UP(_x, _y) \
|
#define DIV_ROUND_UP(_x, _y) \
|
||||||
__extension__ ({ \
|
({ \
|
||||||
const typeof(_x) __x = (_x); \
|
const typeof(_x) __x = (_x); \
|
||||||
const typeof(_y) __y = (_y); \
|
const typeof(_y) __y = (_y); \
|
||||||
(__x / __y + !!(__x % __y)); \
|
(__x / __y + !!(__x % __y)); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#ifdef __COVERITY__
|
||||||
|
|
||||||
|
/* Use special definitions of assertion macros in order to prevent
|
||||||
|
* false positives of ASSERT_SIDE_EFFECT on Coverity static analyzer
|
||||||
|
* for uses of assert_se() and assert_return().
|
||||||
|
*
|
||||||
|
* These definitions make expression go through a (trivial) function
|
||||||
|
* call to ensure they are not discarded. Also use ! or !! to ensure
|
||||||
|
* the boolean expressions are seen as such.
|
||||||
|
*
|
||||||
|
* This technique has been described and recommended in:
|
||||||
|
* https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void __coverity_panic__(void);
|
||||||
|
|
||||||
|
static inline int __coverity_check__(int condition) {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define assert_message_se(expr, message) \
|
||||||
|
do { \
|
||||||
|
if (__coverity_check__(!(expr))) \
|
||||||
|
__coverity_panic__(); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#define assert_log(expr, message) __coverity_check__(!!(expr))
|
||||||
|
|
||||||
|
#else /* ! __COVERITY__ */
|
||||||
|
|
||||||
#define assert_message_se(expr, message) \
|
#define assert_message_se(expr, message) \
|
||||||
do { \
|
do { \
|
||||||
if (_unlikely_(!(expr))) \
|
if (_unlikely_(!(expr))) \
|
||||||
log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
#define assert_log(expr, message) ((_likely_(expr)) \
|
||||||
|
? (true) \
|
||||||
|
: (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
|
||||||
|
|
||||||
|
#endif /* __COVERITY__ */
|
||||||
|
|
||||||
#define assert_se(expr) assert_message_se(expr, #expr)
|
#define assert_se(expr) assert_message_se(expr, #expr)
|
||||||
|
|
||||||
/* We override the glibc assert() here. */
|
/* We override the glibc assert() here. */
|
||||||
@@ -294,10 +339,6 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
|
|||||||
REENABLE_WARNING
|
REENABLE_WARNING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define assert_log(expr, message) ((_likely_(expr)) \
|
|
||||||
? (true) \
|
|
||||||
: (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false))
|
|
||||||
|
|
||||||
#define assert_return(expr, r) \
|
#define assert_return(expr, r) \
|
||||||
do { \
|
do { \
|
||||||
if (!assert_log(expr, #expr)) \
|
if (!assert_log(expr, #expr)) \
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,10 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Michal Schmidt
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct pool;
|
struct pool;
|
||||||
|
@@ -642,6 +642,8 @@ int parse_permille_unbounded(const char *p) {
|
|||||||
r = safe_atoi(n, &v);
|
r = safe_atoi(n, &v);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
if (v < 0)
|
||||||
|
return -ERANGE;
|
||||||
} else {
|
} else {
|
||||||
pc = endswith(p, "%");
|
pc = endswith(p, "%");
|
||||||
if (!pc)
|
if (!pc)
|
||||||
@@ -662,15 +664,14 @@ int parse_permille_unbounded(const char *p) {
|
|||||||
r = safe_atoi(n, &v);
|
r = safe_atoi(n, &v);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
if (v < 0)
|
||||||
|
return -ERANGE;
|
||||||
if (v > (INT_MAX - q) / 10)
|
if (v > (INT_MAX - q) / 10)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
v = v * 10 + q;
|
v = v * 10 + q;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v < 0)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -113,10 +113,7 @@ int path_make_absolute_cwd(const char *p, char **ret) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (endswith(cwd, "/"))
|
c = path_join(NULL, cwd, p);
|
||||||
c = strjoin(cwd, p);
|
|
||||||
else
|
|
||||||
c = strjoin(cwd, "/", p);
|
|
||||||
}
|
}
|
||||||
if (!c)
|
if (!c)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -426,6 +423,7 @@ char* path_startswith(const char *path, const char *prefix) {
|
|||||||
prefix += b;
|
prefix += b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
int path_compare(const char *a, const char *b) {
|
int path_compare(const char *a, const char *b) {
|
||||||
int d;
|
int d;
|
||||||
@@ -477,6 +475,7 @@ bool path_equal(const char *a, const char *b) {
|
|||||||
return path_compare(a, b) == 0;
|
return path_compare(a, b) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
bool path_equal_or_files_same(const char *a, const char *b, int flags) {
|
bool path_equal_or_files_same(const char *a, const char *b, int flags) {
|
||||||
return path_equal(a, b) || files_same(a, b, flags) > 0;
|
return path_equal(a, b) || files_same(a, b, flags) > 0;
|
||||||
}
|
}
|
||||||
|
@@ -60,10 +60,10 @@ static inline bool path_equal_ptr(const char *a, const char *b) {
|
|||||||
/* Note: the search terminates on the first NULL item. */
|
/* Note: the search terminates on the first NULL item. */
|
||||||
#define PATH_IN_SET(p, ...) \
|
#define PATH_IN_SET(p, ...) \
|
||||||
({ \
|
({ \
|
||||||
char **s; \
|
char **_s; \
|
||||||
bool _found = false; \
|
bool _found = false; \
|
||||||
STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \
|
STRV_FOREACH(_s, STRV_MAKE(__VA_ARGS__)) \
|
||||||
if (path_equal(p, *s)) { \
|
if (path_equal(p, *_s)) { \
|
||||||
_found = true; \
|
_found = true; \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
|
@@ -1115,12 +1115,7 @@ int pid_compare_func(const void *a, const void *b) {
|
|||||||
const pid_t *p = a, *q = b;
|
const pid_t *p = a, *q = b;
|
||||||
|
|
||||||
/* Suitable for usage in qsort() */
|
/* Suitable for usage in qsort() */
|
||||||
|
return CMP(*p, *q);
|
||||||
if (*p < *q)
|
|
||||||
return -1;
|
|
||||||
if (*p > *q)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ioprio_parse_priority(const char *s, int *ret) {
|
int ioprio_parse_priority(const char *s, int *ret) {
|
||||||
@@ -1161,7 +1156,7 @@ void reset_cached_pid(void) {
|
|||||||
/* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc
|
/* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc
|
||||||
* headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against
|
* headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against
|
||||||
* libpthread, as it is part of glibc anyway. */
|
* libpthread, as it is part of glibc anyway. */
|
||||||
extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void * __dso_handle);
|
extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle);
|
||||||
extern void* __dso_handle __attribute__ ((__weak__));
|
extern void* __dso_handle __attribute__ ((__weak__));
|
||||||
|
|
||||||
pid_t getpid_cached(void) {
|
pid_t getpid_cached(void) {
|
||||||
|
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#include <cpuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <elf.h>
|
#include <elf.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@@ -28,6 +32,41 @@
|
|||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
|
|
||||||
|
int rdrand64(uint64_t *ret) {
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
static int have_rdrand = -1;
|
||||||
|
unsigned char err;
|
||||||
|
|
||||||
|
if (have_rdrand < 0) {
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
|
||||||
|
/* Check if RDRAND is supported by the CPU */
|
||||||
|
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) {
|
||||||
|
have_rdrand = false;
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
have_rdrand = !!(ecx & (1U << 30));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_rdrand == 0)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
asm volatile("rdrand %0;"
|
||||||
|
"setc %1"
|
||||||
|
: "=r" (*ret),
|
||||||
|
"=qm" (err));
|
||||||
|
if (!err)
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
|
int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
|
||||||
static int have_syscall = -1;
|
static int have_syscall = -1;
|
||||||
|
|
||||||
@@ -77,8 +116,26 @@ int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
|
|||||||
* a best-effort basis. */
|
* a best-effort basis. */
|
||||||
have_syscall = true;
|
have_syscall = true;
|
||||||
|
|
||||||
if (!high_quality_required)
|
if (!high_quality_required) {
|
||||||
|
uint64_t u;
|
||||||
|
size_t k;
|
||||||
|
|
||||||
|
/* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality
|
||||||
|
* randomness is not required, as we don't trust it (who does?). Note that we only do a
|
||||||
|
* single iteration of RDRAND here, even though the Intel docs suggest calling this in
|
||||||
|
* a tight loop of 10 invocatins or so. That's because we don't really care about the
|
||||||
|
* quality here. */
|
||||||
|
|
||||||
|
if (rdrand64(&u) < 0)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
|
k = MIN(n, sizeof(u));
|
||||||
|
memcpy(p, &u, k);
|
||||||
|
|
||||||
|
/* We only get 64bit out of RDRAND, the rest let's fill up with pseudo-random crap. */
|
||||||
|
pseudorandom_bytes((uint8_t*) p + k, n - k);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
@@ -21,3 +21,5 @@ static inline uint32_t random_u32(void) {
|
|||||||
random_bytes(&u, sizeof(u));
|
random_bytes(&u, sizeof(u));
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rdrand64(uint64_t *ret);
|
||||||
|
@@ -53,7 +53,8 @@ static const char* const socket_address_type_table[] = {
|
|||||||
DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
|
DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
|
||||||
|
|
||||||
int socket_address_parse(SocketAddress *a, const char *s) {
|
int socket_address_parse(SocketAddress *a, const char *s) {
|
||||||
char *e, *n;
|
_cleanup_free_ char *n = NULL;
|
||||||
|
char *e;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(a);
|
assert(a);
|
||||||
@@ -71,7 +72,9 @@ int socket_address_parse(SocketAddress *a, const char *s) {
|
|||||||
if (!e)
|
if (!e)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
n = strndupa(s+1, e-s-1);
|
n = strndup(s+1, e-s-1);
|
||||||
|
if (!n)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
|
if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
|
||||||
@@ -128,7 +131,10 @@ int socket_address_parse(SocketAddress *a, const char *s) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
n = strndupa(cid_start, e - cid_start);
|
n = strndup(cid_start, e - cid_start);
|
||||||
|
if (!n)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!isempty(n)) {
|
if (!isempty(n)) {
|
||||||
r = safe_atou(n, &a->sockaddr.vm.svm_cid);
|
r = safe_atou(n, &a->sockaddr.vm.svm_cid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -149,7 +155,9 @@ int socket_address_parse(SocketAddress *a, const char *s) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
n = strndupa(s, e-s);
|
n = strndup(s, e-s);
|
||||||
|
if (!n)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* IPv4 in w.x.y.z:p notation? */
|
/* IPv4 in w.x.y.z:p notation? */
|
||||||
r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
|
r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
|
||||||
@@ -1006,9 +1014,10 @@ int getpeergroups(int fd, gid_t **ret) {
|
|||||||
return (int) n;
|
return (int) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_one_fd_sa(
|
ssize_t send_one_fd_iov_sa(
|
||||||
int transport_fd,
|
int transport_fd,
|
||||||
int fd,
|
int fd,
|
||||||
|
struct iovec *iov, size_t iovlen,
|
||||||
const struct sockaddr *sa, socklen_t len,
|
const struct sockaddr *sa, socklen_t len,
|
||||||
int flags) {
|
int flags) {
|
||||||
|
|
||||||
@@ -1019,13 +1028,25 @@ int send_one_fd_sa(
|
|||||||
struct msghdr mh = {
|
struct msghdr mh = {
|
||||||
.msg_name = (struct sockaddr*) sa,
|
.msg_name = (struct sockaddr*) sa,
|
||||||
.msg_namelen = len,
|
.msg_namelen = len,
|
||||||
.msg_control = &control,
|
.msg_iov = iov,
|
||||||
.msg_controllen = sizeof(control),
|
.msg_iovlen = iovlen,
|
||||||
};
|
};
|
||||||
struct cmsghdr *cmsg;
|
ssize_t k;
|
||||||
|
|
||||||
assert(transport_fd >= 0);
|
assert(transport_fd >= 0);
|
||||||
assert(fd >= 0);
|
|
||||||
|
/*
|
||||||
|
* We need either an FD or data to send.
|
||||||
|
* If there's nothing, return an error.
|
||||||
|
*/
|
||||||
|
if (fd < 0 && !iov)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
|
||||||
|
mh.msg_control = &control;
|
||||||
|
mh.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
cmsg = CMSG_FIRSTHDR(&mh);
|
cmsg = CMSG_FIRSTHDR(&mh);
|
||||||
cmsg->cmsg_level = SOL_SOCKET;
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
@@ -1034,13 +1055,31 @@ int send_one_fd_sa(
|
|||||||
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
|
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
|
||||||
|
|
||||||
mh.msg_controllen = CMSG_SPACE(sizeof(int));
|
mh.msg_controllen = CMSG_SPACE(sizeof(int));
|
||||||
if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
|
}
|
||||||
return -errno;
|
k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags);
|
||||||
|
if (k < 0)
|
||||||
|
return (ssize_t) -errno;
|
||||||
|
|
||||||
return 0;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
int receive_one_fd(int transport_fd, int flags) {
|
int send_one_fd_sa(
|
||||||
|
int transport_fd,
|
||||||
|
int fd,
|
||||||
|
const struct sockaddr *sa, socklen_t len,
|
||||||
|
int flags) {
|
||||||
|
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
return (int) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, sa, len, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t receive_one_fd_iov(
|
||||||
|
int transport_fd,
|
||||||
|
struct iovec *iov, size_t iovlen,
|
||||||
|
int flags,
|
||||||
|
int *ret_fd) {
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct cmsghdr cmsghdr;
|
struct cmsghdr cmsghdr;
|
||||||
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||||
@@ -1048,10 +1087,14 @@ int receive_one_fd(int transport_fd, int flags) {
|
|||||||
struct msghdr mh = {
|
struct msghdr mh = {
|
||||||
.msg_control = &control,
|
.msg_control = &control,
|
||||||
.msg_controllen = sizeof(control),
|
.msg_controllen = sizeof(control),
|
||||||
|
.msg_iov = iov,
|
||||||
|
.msg_iovlen = iovlen,
|
||||||
};
|
};
|
||||||
struct cmsghdr *cmsg, *found = NULL;
|
struct cmsghdr *cmsg, *found = NULL;
|
||||||
|
ssize_t k;
|
||||||
|
|
||||||
assert(transport_fd >= 0);
|
assert(transport_fd >= 0);
|
||||||
|
assert(ret_fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive a single FD via @transport_fd. We don't care for
|
* Receive a single FD via @transport_fd. We don't care for
|
||||||
@@ -1061,8 +1104,9 @@ int receive_one_fd(int transport_fd, int flags) {
|
|||||||
* combination with send_one_fd().
|
* combination with send_one_fd().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
|
k = recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags);
|
||||||
return -errno;
|
if (k < 0)
|
||||||
|
return (ssize_t) -errno;
|
||||||
|
|
||||||
CMSG_FOREACH(cmsg, &mh) {
|
CMSG_FOREACH(cmsg, &mh) {
|
||||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
@@ -1074,12 +1118,33 @@ int receive_one_fd(int transport_fd, int flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found)
|
||||||
cmsg_close_all(&mh);
|
cmsg_close_all(&mh);
|
||||||
|
|
||||||
|
/* If didn't receive an FD or any data, return an error. */
|
||||||
|
if (k == 0 && !found)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
*ret_fd = *(int*) CMSG_DATA(found);
|
||||||
|
else
|
||||||
|
*ret_fd = -1;
|
||||||
|
|
||||||
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(int*) CMSG_DATA(found);
|
int receive_one_fd(int transport_fd, int flags) {
|
||||||
|
int fd;
|
||||||
|
ssize_t k;
|
||||||
|
|
||||||
|
k = receive_one_fd_iov(transport_fd, NULL, 0, flags, &fd);
|
||||||
|
if (k == 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
/* k must be negative, since receive_one_fd_iov() only returns
|
||||||
|
* a positive value if data was received through the iov. */
|
||||||
|
assert(k < 0);
|
||||||
|
return (int) k;
|
||||||
}
|
}
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
|
@@ -132,11 +132,19 @@ int getpeercred(int fd, struct ucred *ucred);
|
|||||||
int getpeersec(int fd, char **ret);
|
int getpeersec(int fd, char **ret);
|
||||||
int getpeergroups(int fd, gid_t **ret);
|
int getpeergroups(int fd, gid_t **ret);
|
||||||
|
|
||||||
|
ssize_t send_one_fd_iov_sa(
|
||||||
|
int transport_fd,
|
||||||
|
int fd,
|
||||||
|
struct iovec *iov, size_t iovlen,
|
||||||
|
const struct sockaddr *sa, socklen_t len,
|
||||||
|
int flags);
|
||||||
int send_one_fd_sa(int transport_fd,
|
int send_one_fd_sa(int transport_fd,
|
||||||
int fd,
|
int fd,
|
||||||
const struct sockaddr *sa, socklen_t len,
|
const struct sockaddr *sa, socklen_t len,
|
||||||
int flags);
|
int flags);
|
||||||
#define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags)
|
#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags)
|
||||||
|
#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags)
|
||||||
|
ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd);
|
||||||
int receive_one_fd(int transport_fd, int flags);
|
int receive_one_fd(int transport_fd, int flags);
|
||||||
|
|
||||||
ssize_t next_datagram_size_fd(int fd);
|
ssize_t next_datagram_size_fd(int fd);
|
||||||
|
@@ -48,6 +48,17 @@ int is_dir(const char* path, bool follow) {
|
|||||||
return !!S_ISDIR(st.st_mode);
|
return !!S_ISDIR(st.st_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int is_dir_fd(int fd) {
|
||||||
|
struct stat st;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = fstat(fd, &st);
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return !!S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
int is_device_node(const char *path) {
|
int is_device_node(const char *path) {
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
int is_symlink(const char *path);
|
int is_symlink(const char *path);
|
||||||
int is_dir(const char *path, bool follow);
|
int is_dir(const char *path, bool follow);
|
||||||
|
int is_dir_fd(int fd);
|
||||||
int is_device_node(const char *path);
|
int is_device_node(const char *path);
|
||||||
|
|
||||||
int dir_is_empty(const char *path);
|
int dir_is_empty(const char *path);
|
||||||
|
@@ -255,6 +255,10 @@ char **strv_split(const char *s, const char *separator) {
|
|||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
s += strspn(s, separator);
|
||||||
|
if (isempty(s))
|
||||||
|
return new0(char*, 1);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
|
FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
|
||||||
n++;
|
n++;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -1001,10 +1002,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
long long l, z = 0;
|
|
||||||
char *e;
|
|
||||||
unsigned n = 0;
|
|
||||||
usec_t multiplier = default_unit, k;
|
usec_t multiplier = default_unit, k;
|
||||||
|
long long l, z = 0;
|
||||||
|
unsigned n = 0;
|
||||||
|
char *e;
|
||||||
|
|
||||||
p += strspn(p, WHITESPACE);
|
p += strspn(p, WHITESPACE);
|
||||||
|
|
||||||
@@ -1015,6 +1016,9 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*p == '-') /* Don't allow "-0" */
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoll(p, &e, 10);
|
l = strtoll(p, &e, 10);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
@@ -1025,14 +1029,16 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
|
|||||||
if (*e == '.') {
|
if (*e == '.') {
|
||||||
char *b = e + 1;
|
char *b = e + 1;
|
||||||
|
|
||||||
|
/* Don't allow "0.-0", "3.+1" or "3. 1" */
|
||||||
|
if (*b == '-' || *b == '+' || isspace(*b))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
z = strtoll(b, &e, 10);
|
z = strtoll(b, &e, 10);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (z < 0)
|
if (z < 0)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (e == b)
|
if (e == b)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@@ -1149,26 +1155,28 @@ int parse_nsec(const char *t, nsec_t *nsec) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*p == '-')
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoll(p, &e, 10);
|
l = strtoll(p, &e, 10);
|
||||||
|
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (*e == '.') {
|
if (*e == '.') {
|
||||||
char *b = e + 1;
|
char *b = e + 1;
|
||||||
|
|
||||||
|
if (*b == '-' || *b == '+' || isspace(*b))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
z = strtoll(b, &e, 10);
|
z = strtoll(b, &e, 10);
|
||||||
if (errno > 0)
|
if (errno > 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (z < 0)
|
if (z < 0)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (e == b)
|
if (e == b)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2008-2011 Kay Sievers
|
|
||||||
***/
|
|
||||||
|
|
||||||
/* Parts of this file are based on the GLIB utf8 validation functions. The
|
/* Parts of this file are based on the GLIB utf8 validation functions. The
|
||||||
* original license text follows. */
|
* original license text follows. */
|
||||||
|
@@ -82,31 +82,6 @@ bool display_is_local(const char *display) {
|
|||||||
display[1] <= '9';
|
display[1] <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
int socket_from_display(const char *display, char **path) {
|
|
||||||
size_t k;
|
|
||||||
char *f, *c;
|
|
||||||
|
|
||||||
assert(display);
|
|
||||||
assert(path);
|
|
||||||
|
|
||||||
if (!display_is_local(display))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
k = strspn(display+1, "0123456789");
|
|
||||||
|
|
||||||
f = new(char, STRLEN("/tmp/.X11-unix/X") + k + 1);
|
|
||||||
if (!f)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
c = stpcpy(f, "/tmp/.X11-unix/X");
|
|
||||||
memcpy(c, display+1, k);
|
|
||||||
c[k] = 0;
|
|
||||||
|
|
||||||
*path = f;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool kexec_loaded(void) {
|
bool kexec_loaded(void) {
|
||||||
_cleanup_free_ char *s = NULL;
|
_cleanup_free_ char *s = NULL;
|
||||||
|
|
||||||
@@ -260,6 +235,11 @@ int container_get_leader(const char *machine, pid_t *pid) {
|
|||||||
assert(machine);
|
assert(machine);
|
||||||
assert(pid);
|
assert(pid);
|
||||||
|
|
||||||
|
if (streq(machine, ".host")) {
|
||||||
|
*pid = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!machine_name_is_valid(machine))
|
if (!machine_name_is_valid(machine))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@@ -50,7 +50,6 @@ static inline const char* enable_disable(bool b) {
|
|||||||
bool plymouth_running(void);
|
bool plymouth_running(void);
|
||||||
|
|
||||||
bool display_is_local(const char *display) _pure_;
|
bool display_is_local(const char *display) _pure_;
|
||||||
int socket_from_display(const char *display, char **path);
|
|
||||||
|
|
||||||
#define NULSTR_FOREACH(i, l) \
|
#define NULSTR_FOREACH(i, l) \
|
||||||
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
|
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
|
||||||
@@ -113,9 +112,7 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*com
|
|||||||
qsort_r(base, nmemb, size, compar, userdata);
|
qsort_r(base, nmemb, size, compar, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
|
||||||
* Normal memcpy requires src to be nonnull. We do nothing if n is 0.
|
|
||||||
*/
|
|
||||||
static inline void memcpy_safe(void *dst, const void *src, size_t n) {
|
static inline void memcpy_safe(void *dst, const void *src, size_t n) {
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
@@ -123,6 +120,15 @@ static inline void memcpy_safe(void *dst, const void *src, size_t n) {
|
|||||||
memcpy(dst, src, n);
|
memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
|
||||||
|
static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
|
||||||
|
if (n == 0)
|
||||||
|
return 0;
|
||||||
|
assert(s1);
|
||||||
|
assert(s2);
|
||||||
|
return memcmp(s1, s2, n);
|
||||||
|
}
|
||||||
|
|
||||||
int on_ac_power(void);
|
int on_ac_power(void);
|
||||||
|
|
||||||
#define memzero(x,l) (memset((x), 0, (l)))
|
#define memzero(x,l) (memset((x), 0, (l)))
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Axis Communications AB. All rights reserved.
|
Copyright © 2014 Axis Communications AB. All rights reserved.
|
||||||
Copyright © 2015 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2015 Tom Gundersen <teg@jklmen>
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
#include "libudev.h"
|
#include <linux/if_infiniband.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "dhcp-identifier.h"
|
#include "dhcp-identifier.h"
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
#include "sparse-endian.h"
|
#include "sparse-endian.h"
|
||||||
#include "udev-util.h"
|
|
||||||
#include "virt.h"
|
#include "virt.h"
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
@@ -23,6 +22,8 @@
|
|||||||
|
|
||||||
#define SYSTEMD_PEN 43793
|
#define SYSTEMD_PEN 43793
|
||||||
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
||||||
|
#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
|
||||||
|
#define USEC_2000 ((usec_t) 946684800000000) /* 2000-01-01 00:00:00 UTC */
|
||||||
|
|
||||||
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
|
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
|
||||||
struct duid d;
|
struct duid d;
|
||||||
@@ -55,6 +56,58 @@ int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
|
int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) {
|
||||||
|
uint16_t time_from_2000y;
|
||||||
|
|
||||||
|
assert(duid);
|
||||||
|
assert(len);
|
||||||
|
assert(addr);
|
||||||
|
|
||||||
|
if (arp_type == ARPHRD_ETHER)
|
||||||
|
assert_return(addr_len == ETH_ALEN, -EINVAL);
|
||||||
|
else if (arp_type == ARPHRD_INFINIBAND)
|
||||||
|
assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (t < USEC_2000)
|
||||||
|
time_from_2000y = 0;
|
||||||
|
else
|
||||||
|
time_from_2000y = (uint16_t) (((t - USEC_2000) / USEC_PER_SEC) & 0xffffffff);
|
||||||
|
|
||||||
|
unaligned_write_be16(&duid->type, DUID_TYPE_LLT);
|
||||||
|
unaligned_write_be16(&duid->llt.htype, arp_type);
|
||||||
|
unaligned_write_be32(&duid->llt.time, time_from_2000y);
|
||||||
|
memcpy(duid->llt.haddr, addr, addr_len);
|
||||||
|
|
||||||
|
*len = sizeof(duid->type) + sizeof(duid->llt.htype) + sizeof(duid->llt.time) + addr_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) {
|
||||||
|
assert(duid);
|
||||||
|
assert(len);
|
||||||
|
assert(addr);
|
||||||
|
|
||||||
|
if (arp_type == ARPHRD_ETHER)
|
||||||
|
assert_return(addr_len == ETH_ALEN, -EINVAL);
|
||||||
|
else if (arp_type == ARPHRD_INFINIBAND)
|
||||||
|
assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
unaligned_write_be16(&duid->type, DUID_TYPE_LL);
|
||||||
|
unaligned_write_be16(&duid->ll.htype, arp_type);
|
||||||
|
memcpy(duid->ll.haddr, addr, addr_len);
|
||||||
|
|
||||||
|
*len = sizeof(duid->type) + sizeof(duid->ll.htype) + addr_len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
|
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
|
||||||
sd_id128_t machine_id;
|
sd_id128_t machine_id;
|
||||||
uint64_t hash;
|
uint64_t hash;
|
||||||
@@ -73,18 +126,39 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
|
|||||||
*len = sizeof(duid->type) + sizeof(duid->en);
|
*len = sizeof(duid->type) + sizeof(duid->en);
|
||||||
|
|
||||||
/* a bit of snake-oil perhaps, but no need to expose the machine-id
|
/* a bit of snake-oil perhaps, but no need to expose the machine-id
|
||||||
directly; duid->en.id might not be aligned, so we need to copy */
|
* directly; duid->en.id might not be aligned, so we need to copy */
|
||||||
hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes));
|
hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes));
|
||||||
memcpy(duid->en.id, &hash, sizeof(duid->en.id));
|
memcpy(duid->en.id, &hash, sizeof(duid->en.id));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
|
int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) {
|
||||||
|
sd_id128_t machine_id;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(duid);
|
||||||
|
assert(len);
|
||||||
|
|
||||||
|
r = sd_id128_get_machine_app_specific(APPLICATION_ID, &machine_id);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
unaligned_write_be16(&duid->type, DUID_TYPE_UUID);
|
||||||
|
memcpy(&duid->raw.data, &machine_id, sizeof(machine_id));
|
||||||
|
|
||||||
|
*len = sizeof(duid->type) + sizeof(machine_id);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) {
|
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) {
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
/* name is a pointer to memory in the udev_device struct, so must
|
/* name is a pointer to memory in the sd_device struct, so must
|
||||||
have the same scope */
|
* have the same scope */
|
||||||
_cleanup_(udev_device_unrefp) struct udev_device *device = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||||
#else /* NM_IGNORED */
|
#else /* NM_IGNORED */
|
||||||
char name_buf[IF_NAMESIZE];
|
char name_buf[IF_NAMESIZE];
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
@@ -94,17 +168,15 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i
|
|||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
if (detect_container() <= 0) {
|
if (detect_container() <= 0) {
|
||||||
/* not in a container, udev will be around */
|
/* not in a container, udev will be around */
|
||||||
_cleanup_(udev_unrefp) struct udev *udev;
|
|
||||||
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
|
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
|
||||||
|
int initialized, r;
|
||||||
udev = udev_new();
|
|
||||||
if (!udev)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
sprintf(ifindex_str, "n%d", ifindex);
|
sprintf(ifindex_str, "n%d", ifindex);
|
||||||
device = udev_device_new_from_device_id(udev, ifindex_str);
|
if (sd_device_new_from_device_id(&device, ifindex_str) >= 0) {
|
||||||
if (device) {
|
r = sd_device_get_is_initialized(device, &initialized);
|
||||||
if (udev_device_get_is_initialized(device) <= 0)
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (!initialized)
|
||||||
/* not yet ready */
|
/* not yet ready */
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
@@ -1,14 +1,11 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2015 Tom Gundersen <teg@jklmen>
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "sparse-endian.h"
|
#include "sparse-endian.h"
|
||||||
|
#include "time-util.h"
|
||||||
#include "unaligned.h"
|
#include "unaligned.h"
|
||||||
|
|
||||||
typedef enum DUIDType {
|
typedef enum DUIDType {
|
||||||
@@ -31,18 +28,18 @@ struct duid {
|
|||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
/* DUID_TYPE_LLT */
|
/* DUID_TYPE_LLT */
|
||||||
uint16_t htype;
|
be16_t htype;
|
||||||
uint32_t time;
|
be32_t time;
|
||||||
uint8_t haddr[0];
|
uint8_t haddr[0];
|
||||||
} _packed_ llt;
|
} _packed_ llt;
|
||||||
struct {
|
struct {
|
||||||
/* DUID_TYPE_EN */
|
/* DUID_TYPE_EN */
|
||||||
uint32_t pen;
|
be32_t pen;
|
||||||
uint8_t id[8];
|
uint8_t id[8];
|
||||||
} _packed_ en;
|
} _packed_ en;
|
||||||
struct {
|
struct {
|
||||||
/* DUID_TYPE_LL */
|
/* DUID_TYPE_LL */
|
||||||
int16_t htype;
|
be16_t htype;
|
||||||
uint8_t haddr[0];
|
uint8_t haddr[0];
|
||||||
} _packed_ ll;
|
} _packed_ ll;
|
||||||
struct {
|
struct {
|
||||||
@@ -56,5 +53,8 @@ struct duid {
|
|||||||
} _packed_;
|
} _packed_;
|
||||||
|
|
||||||
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
|
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
|
||||||
|
int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
|
||||||
|
int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len);
|
||||||
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
|
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
|
||||||
|
int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len);
|
||||||
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
|
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2013 Intel Corporation. All rights reserved.
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2013 Intel Corporation. All rights reserved.
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2013 Intel Corporation. All rights reserved.
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014 Susant Sahani
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
#include "sd-lldp.h"
|
#include "sd-lldp.h"
|
||||||
|
|
||||||
|
@@ -28,22 +28,15 @@ static int lldp_neighbor_id_compare_func(const void *a, const void *b) {
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (x->chassis_id_size < y->chassis_id_size)
|
r = CMP(x->chassis_id_size, y->chassis_id_size);
|
||||||
return -1;
|
if (r != 0)
|
||||||
|
return r;
|
||||||
if (x->chassis_id_size > y->chassis_id_size)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size));
|
r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size));
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (x->port_id_size < y->port_id_size)
|
return CMP(x->port_id_size, y->port_id_size);
|
||||||
return -1;
|
|
||||||
if (x->port_id_size > y->port_id_size)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct hash_ops lldp_neighbor_id_hash_ops = {
|
const struct hash_ops lldp_neighbor_id_hash_ops = {
|
||||||
@@ -54,13 +47,7 @@ const struct hash_ops lldp_neighbor_id_hash_ops = {
|
|||||||
int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
|
int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
|
||||||
const sd_lldp_neighbor *x = a, *y = b;
|
const sd_lldp_neighbor *x = a, *y = b;
|
||||||
|
|
||||||
if (x->until < y->until)
|
return CMP(x->until, y->until);
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (x->until > y->until)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) {
|
_public_ sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) {
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014 Susant Sahani
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014 Susant Sahani
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
|
||||||
int lldp_network_bind_raw_socket(int ifindex);
|
int lldp_network_bind_raw_socket(int ifindex);
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2013 Tom Gundersen <teg@jklm.no>
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
@@ -29,24 +26,22 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
const char *net_get_name(struct udev_device *device) {
|
const char *net_get_name(sd_device *device) {
|
||||||
const char *name, *field;
|
const char *name, *field;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
|
|
||||||
/* fetch some persistent data unique (on this machine) to this device */
|
/* fetch some persistent data unique (on this machine) to this device */
|
||||||
FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
|
FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC")
|
||||||
name = udev_device_get_property_value(device, field);
|
if (sd_device_get_property_value(device, field, &name) >= 0)
|
||||||
if (name)
|
|
||||||
return name;
|
return name;
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
|
#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
|
||||||
|
|
||||||
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result) {
|
int net_get_unique_predictable_data(sd_device *device, uint64_t *result) {
|
||||||
size_t l, sz = 0;
|
size_t l, sz = 0;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
int r;
|
int r;
|
||||||
@@ -130,7 +125,7 @@ bool net_match_config(Set *match_mac,
|
|||||||
if (match_arch && condition_test(match_arch) <= 0)
|
if (match_arch && condition_test(match_arch) <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (match_mac && dev_mac && !set_contains(match_mac, dev_mac))
|
if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!net_condition_test_strv(match_paths, dev_path))
|
if (!net_condition_test_strv(match_paths, dev_path))
|
||||||
|
@@ -1,18 +1,14 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
Copyright © 2013 Tom Gundersen <teg@jklm.no>
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-dhcp-lease.h"
|
#include "sd-dhcp-lease.h"
|
||||||
|
|
||||||
#include "condition.h"
|
#include "condition.h"
|
||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "udev.h"
|
|
||||||
|
|
||||||
#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
|
#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
|
||||||
#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
|
#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
|
||||||
@@ -42,10 +38,10 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
|
||||||
#endif /* NM_IGNORED */
|
|
||||||
|
|
||||||
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
|
int net_get_unique_predictable_data(sd_device *device, uint64_t *result);
|
||||||
const char *net_get_name(struct udev_device *device);
|
const char *net_get_name(sd_device *device);
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
|
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
|
||||||
int deserialize_in_addrs(struct in_addr **addresses, const char *string);
|
int deserialize_in_addrs(struct in_addr **addresses, const char *string);
|
||||||
|
@@ -345,13 +345,14 @@ int sd_dhcp_client_set_client_id(
|
|||||||
* without further modification. Otherwise, if duid_type is supported, DUID
|
* without further modification. Otherwise, if duid_type is supported, DUID
|
||||||
* is set based on that type. Otherwise, an error is returned.
|
* is set based on that type. Otherwise, an error is returned.
|
||||||
*/
|
*/
|
||||||
static int dhcp_client_set_iaid_duid(
|
static int dhcp_client_set_iaid_duid_internal(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
uint32_t iaid,
|
uint32_t iaid,
|
||||||
bool append_iaid,
|
bool append_iaid,
|
||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len) {
|
size_t duid_len,
|
||||||
|
usec_t llt_time) {
|
||||||
|
|
||||||
DHCP_CLIENT_DONT_DESTROY(client);
|
DHCP_CLIENT_DONT_DESTROY(client);
|
||||||
int r;
|
int r;
|
||||||
@@ -385,18 +386,43 @@ static int dhcp_client_set_iaid_duid(
|
|||||||
client->client_id.ns.duid.type = htobe16(duid_type);
|
client->client_id.ns.duid.type = htobe16(duid_type);
|
||||||
memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
|
memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
|
||||||
len = sizeof(client->client_id.ns.duid.type) + duid_len;
|
len = sizeof(client->client_id.ns.duid.type) + duid_len;
|
||||||
} else if (duid_type == DUID_TYPE_EN) {
|
} else
|
||||||
|
switch (duid_type) {
|
||||||
|
case DUID_TYPE_LLT:
|
||||||
|
if (!client->mac_addr || client->mac_addr_len == 0)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
case DUID_TYPE_EN:
|
||||||
r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
|
r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else
|
break;
|
||||||
|
case DUID_TYPE_LL:
|
||||||
|
if (!client->mac_addr || client->mac_addr_len == 0)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
case DUID_TYPE_UUID:
|
||||||
|
r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
client->client_id_len = sizeof(client->client_id.type) + len +
|
client->client_id_len = sizeof(client->client_id.type) + len +
|
||||||
(append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
|
(append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
|
||||||
|
|
||||||
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
|
if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
|
||||||
log_dhcp_client(client, "Configured IAID+DUID, restarting.");
|
log_dhcp_client(client, "Configured %sDUID, restarting.", append_iaid ? "IAID+" : "");
|
||||||
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
|
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
|
||||||
sd_dhcp_client_start(client);
|
sd_dhcp_client_start(client);
|
||||||
}
|
}
|
||||||
@@ -410,7 +436,14 @@ int sd_dhcp_client_set_iaid_duid(
|
|||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len) {
|
size_t duid_len) {
|
||||||
return dhcp_client_set_iaid_duid(client, iaid, true, duid_type, duid, duid_len);
|
return dhcp_client_set_iaid_duid_internal(client, iaid, true, duid_type, duid, duid_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_set_iaid_duid_llt(
|
||||||
|
sd_dhcp_client *client,
|
||||||
|
uint32_t iaid,
|
||||||
|
usec_t llt_time) {
|
||||||
|
return dhcp_client_set_iaid_duid_internal(client, iaid, true, DUID_TYPE_LLT, NULL, 0, llt_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_set_duid(
|
int sd_dhcp_client_set_duid(
|
||||||
@@ -418,7 +451,13 @@ int sd_dhcp_client_set_duid(
|
|||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len) {
|
size_t duid_len) {
|
||||||
return dhcp_client_set_iaid_duid(client, 0, false, duid_type, duid, duid_len);
|
return dhcp_client_set_iaid_duid_internal(client, 0, false, duid_type, duid, duid_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_set_duid_llt(
|
||||||
|
sd_dhcp_client *client,
|
||||||
|
usec_t llt_time) {
|
||||||
|
return dhcp_client_set_iaid_duid_internal(client, 0, false, DUID_TYPE_LLT, NULL, 0, llt_time);
|
||||||
}
|
}
|
||||||
#endif /* NM_IGNORED */
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2013 Intel Corporation. All rights reserved.
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
@@ -28,6 +27,7 @@
|
|||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "stdio-util.h"
|
#include "stdio-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
#include "unaligned.h"
|
#include "unaligned.h"
|
||||||
|
|
||||||
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
|
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||||
|
@@ -184,13 +184,14 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
|
|||||||
* without further modification. Otherwise, if duid_type is supported, DUID
|
* without further modification. Otherwise, if duid_type is supported, DUID
|
||||||
* is set based on that type. Otherwise, an error is returned.
|
* is set based on that type. Otherwise, an error is returned.
|
||||||
*/
|
*/
|
||||||
int sd_dhcp6_client_set_duid(
|
static int dhcp6_client_set_duid_internal(
|
||||||
sd_dhcp6_client *client,
|
sd_dhcp6_client *client,
|
||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len) {
|
size_t duid_len,
|
||||||
|
usec_t llt_time) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(duid_len == 0 || duid != NULL, -EINVAL);
|
assert_return(duid_len == 0 || duid != NULL, -EINVAL);
|
||||||
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
||||||
@@ -199,23 +200,64 @@ int sd_dhcp6_client_set_duid(
|
|||||||
r = dhcp_validate_duid_len(duid_type, duid_len);
|
r = dhcp_validate_duid_len(duid_type, duid_len);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
if (duid != NULL) {
|
|
||||||
client->duid.type = htobe16(duid_type);
|
client->duid.type = htobe16(duid_type);
|
||||||
memcpy(&client->duid.raw.data, duid, duid_len);
|
memcpy(&client->duid.raw.data, duid, duid_len);
|
||||||
client->duid_len = sizeof(client->duid.type) + duid_len;
|
client->duid_len = sizeof(client->duid.type) + duid_len;
|
||||||
} else if (duid_type == DUID_TYPE_EN) {
|
} else
|
||||||
|
#if 0 /* NM_IGNORED */
|
||||||
|
switch (duid_type) {
|
||||||
|
case DUID_TYPE_LLT:
|
||||||
|
if (!client->mac_addr || client->mac_addr_len == 0)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
r = dhcp_identifier_set_duid_llt(&client->duid, 0, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
case DUID_TYPE_EN:
|
||||||
r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
|
r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else
|
break;
|
||||||
|
case DUID_TYPE_LL:
|
||||||
|
if (!client->mac_addr || client->mac_addr_len == 0)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
r = dhcp_identifier_set_duid_ll(&client->duid, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
case DUID_TYPE_UUID:
|
||||||
|
r = dhcp_identifier_set_duid_uuid(&client->duid, &client->duid_len);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#else /* NM_IGNORED */
|
||||||
|
g_return_val_if_reached (-EINVAL);
|
||||||
|
#endif /* NM_IGNORED */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp6_client_set_duid(
|
||||||
|
sd_dhcp6_client *client,
|
||||||
|
uint16_t duid_type,
|
||||||
|
const void *duid,
|
||||||
|
size_t duid_len) {
|
||||||
|
return dhcp6_client_set_duid_internal(client, duid_type, duid, duid_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0 /* NM_IGNORED */
|
#if 0 /* NM_IGNORED */
|
||||||
|
int sd_dhcp6_client_set_duid_llt(
|
||||||
|
sd_dhcp6_client *client,
|
||||||
|
usec_t llt_time) {
|
||||||
|
return dhcp6_client_set_duid_internal(client, DUID_TYPE_LLT, NULL, 0, llt_time);
|
||||||
|
}
|
||||||
|
|
||||||
int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
|
int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) {
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
|
||||||
@@ -1148,7 +1190,6 @@ static int client_receive_message(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r >= 0)
|
|
||||||
log_dhcp6_client(client, "Recv %s",
|
log_dhcp6_client(client, "Recv %s",
|
||||||
dhcp6_message_type_to_string(message->type));
|
dhcp6_message_type_to_string(message->type));
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Axis Communications AB. All rights reserved.
|
Copyright © 2014 Axis Communications AB. All rights reserved.
|
||||||
Copyright © 2015 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Axis Communications AB. All rights reserved.
|
Copyright © 2014 Axis Communications AB. All rights reserved.
|
||||||
Copyright © 2015 Tom Gundersen
|
|
||||||
***/
|
***/
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
@@ -1,8 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014 Susant Sahani
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
@@ -94,7 +92,7 @@ struct sd_event_source {
|
|||||||
char *description;
|
char *description;
|
||||||
|
|
||||||
EventSourceType type:5;
|
EventSourceType type:5;
|
||||||
int enabled:3;
|
signed int enabled:3;
|
||||||
bool pending:1;
|
bool pending:1;
|
||||||
bool dispatching:1;
|
bool dispatching:1;
|
||||||
bool floating:1;
|
bool floating:1;
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
|
@@ -1,6 +1,4 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include "nm-sd-adapt.h"
|
#include "nm-sd-adapt.h"
|
||||||
|
|
||||||
@@ -514,7 +512,7 @@ int dns_name_compare_func(const void *a, const void *b) {
|
|||||||
r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
|
r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
|
||||||
q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
|
q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
|
||||||
if (r < 0 || q < 0)
|
if (r < 0 || q < 0)
|
||||||
return r - q;
|
return CMP(r, q);
|
||||||
|
|
||||||
r = ascii_strcasecmp_nn(la, r, lb, q);
|
r = ascii_strcasecmp_nn(la, r, lb, q);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/***
|
|
||||||
***/
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#define foosdcommonhfoo
|
#define foosdcommonhfoo
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
@@ -131,11 +131,18 @@ int sd_dhcp_client_set_iaid_duid(
|
|||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len);
|
size_t duid_len);
|
||||||
|
int sd_dhcp_client_set_iaid_duid_llt(
|
||||||
|
sd_dhcp_client *client,
|
||||||
|
uint32_t iaid,
|
||||||
|
uint64_t llt_time);
|
||||||
int sd_dhcp_client_set_duid(
|
int sd_dhcp_client_set_duid(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len);
|
size_t duid_len);
|
||||||
|
int sd_dhcp_client_set_duid_llt(
|
||||||
|
sd_dhcp_client *client,
|
||||||
|
uint64_t llt_time);
|
||||||
int sd_dhcp_client_get_client_id(
|
int sd_dhcp_client_get_client_id(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
uint8_t *type,
|
uint8_t *type,
|
||||||
|
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2013 Intel Corporation. All rights reserved.
|
Copyright © 2013 Intel Corporation. All rights reserved.
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
@@ -102,6 +102,9 @@ int sd_dhcp6_client_set_duid(
|
|||||||
uint16_t duid_type,
|
uint16_t duid_type,
|
||||||
const void *duid,
|
const void *duid,
|
||||||
size_t duid_len);
|
size_t duid_len);
|
||||||
|
int sd_dhcp6_client_set_duid_llt(
|
||||||
|
sd_dhcp6_client *client,
|
||||||
|
uint64_t llt_time);
|
||||||
int sd_dhcp6_client_set_iaid(
|
int sd_dhcp6_client_set_iaid(
|
||||||
sd_dhcp6_client *client,
|
sd_dhcp6_client *client,
|
||||||
uint32_t iaid);
|
uint32_t iaid);
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#define foosddhcp6leasehfoo
|
#define foosddhcp6leasehfoo
|
||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
Copyright © 2014-2015 Intel Corporation. All rights reserved.
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#define foosdeventhfoo
|
#define foosdeventhfoo
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
#define foosdid128hfoo
|
#define foosdid128hfoo
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Axis Communications AB. All rights reserved.
|
Copyright © 2014 Axis Communications AB. All rights reserved.
|
||||||
Copyright © 2015 Tom Gundersen
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
@@ -3,9 +3,6 @@
|
|||||||
#define foosdlldphfoo
|
#define foosdlldphfoo
|
||||||
|
|
||||||
/***
|
/***
|
||||||
Copyright © 2014 Tom Gundersen
|
|
||||||
Copyright © 2014 Susant Sahani
|
|
||||||
|
|
||||||
systemd is free software; you can redistribute it and/or modify it
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
under the terms of the GNU Lesser General Public License as published by
|
under the terms of the GNU Lesser General Public License as published by
|
||||||
the Free Software Foundation; either version 2.1 of the License, or
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
Reference in New Issue
Block a user