mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-01 13:50:32 +01:00
dhcp: merge branch 'systemd-dhcp' into master
Conflicts: src/dhcp-manager/systemd-dhcp/src/shared/util.c
This commit is contained in:
commit
99df201a0c
11 changed files with 176 additions and 91 deletions
|
|
@ -1471,7 +1471,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
|||
_cleanup_free_ DHCPMessage *message = NULL;
|
||||
int buflen = 0, len, r;
|
||||
const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
|
||||
const struct ether_addr *expected_chaddr = NULL;
|
||||
bool expect_chaddr;
|
||||
uint8_t expected_hlen = 0;
|
||||
|
||||
assert(s);
|
||||
|
|
@ -1516,11 +1516,11 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
|||
|
||||
if (client->arp_type == ARPHRD_ETHER) {
|
||||
expected_hlen = ETH_ALEN;
|
||||
expected_chaddr = (const struct ether_addr *) &client->mac_addr;
|
||||
expect_chaddr = true;
|
||||
} else {
|
||||
/* Non-ethernet links expect zero chaddr */
|
||||
expected_hlen = 0;
|
||||
expected_chaddr = &zero_mac;
|
||||
expect_chaddr = false;
|
||||
}
|
||||
|
||||
if (message->hlen != expected_hlen) {
|
||||
|
|
@ -1528,7 +1528,10 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
|
||||
if (memcmp(&message->chaddr[0], expect_chaddr ?
|
||||
(void *)&client->mac_addr :
|
||||
(void *)&zero_mac,
|
||||
ETH_ALEN)) {
|
||||
log_dhcp_client(client, "received chaddr does not match "
|
||||
"expected: ignoring");
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
|||
static thread_local bool saved_machine_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[33];
|
||||
ssize_t k;
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
|
|
@ -127,13 +127,9 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
|||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
k = loop_read(fd, buf, 33, false);
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
|
||||
if (k != 33)
|
||||
return -EIO;
|
||||
|
||||
r = loop_read_exact(fd, buf, 33, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (buf[32] !='\n')
|
||||
return -EIO;
|
||||
|
||||
|
|
@ -162,10 +158,10 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
|||
static thread_local bool saved_boot_id_valid = false;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char buf[36];
|
||||
ssize_t k;
|
||||
unsigned j;
|
||||
sd_id128_t t;
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
|
|
@ -178,22 +174,19 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
|||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
k = loop_read(fd, buf, 36, false);
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
|
||||
if (k != 36)
|
||||
return -EIO;
|
||||
r = loop_read_exact(fd, buf, 36, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (j = 0, p = buf; j < 16; j++) {
|
||||
int a, b;
|
||||
|
||||
if (p >= buf + k - 1)
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
if (p >= buf + k - 1)
|
||||
if (p >= buf + 35)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <errno.h>
|
||||
|
|
|
|||
|
|
@ -407,12 +407,18 @@ char* path_startswith(const char *path, const char *prefix) {
|
|||
}
|
||||
}
|
||||
|
||||
bool path_equal(const char *a, const char *b) {
|
||||
int path_compare(const char *a, const char *b) {
|
||||
int d;
|
||||
|
||||
assert(a);
|
||||
assert(b);
|
||||
|
||||
if ((a[0] == '/') != (b[0] == '/'))
|
||||
return false;
|
||||
/* A relative path and an abolute path must not compare as equal.
|
||||
* Which one is sorted before the other does not really matter.
|
||||
* Here a relative path is ordered before an absolute path. */
|
||||
d = (a[0] == '/') - (b[0] == '/');
|
||||
if (d)
|
||||
return d;
|
||||
|
||||
for (;;) {
|
||||
size_t j, k;
|
||||
|
|
@ -421,25 +427,36 @@ bool path_equal(const char *a, const char *b) {
|
|||
b += strspn(b, "/");
|
||||
|
||||
if (*a == 0 && *b == 0)
|
||||
return true;
|
||||
return 0;
|
||||
|
||||
if (*a == 0 || *b == 0)
|
||||
return false;
|
||||
/* Order prefixes first: "/foo" before "/foo/bar" */
|
||||
if (*a == 0)
|
||||
return -1;
|
||||
if (*b == 0)
|
||||
return 1;
|
||||
|
||||
j = strcspn(a, "/");
|
||||
k = strcspn(b, "/");
|
||||
|
||||
if (j != k)
|
||||
return false;
|
||||
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
|
||||
d = memcmp(a, b, MIN(j, k));
|
||||
if (d)
|
||||
return (d > 0) - (d < 0); /* sign of d */
|
||||
|
||||
if (memcmp(a, b, j) != 0)
|
||||
return false;
|
||||
/* Sort "/foo/a" before "/foo/aaa" */
|
||||
d = (j > k) - (j < k); /* sign of (j - k) */
|
||||
if (d)
|
||||
return d;
|
||||
|
||||
a += j;
|
||||
b += k;
|
||||
}
|
||||
}
|
||||
|
||||
bool path_equal(const char *a, const char *b) {
|
||||
return path_compare(a, b) == 0;
|
||||
}
|
||||
|
||||
bool path_equal_or_files_same(const char *a, const char *b) {
|
||||
return path_equal(a, b) || files_same(a, b) > 0;
|
||||
}
|
||||
|
|
@ -464,9 +481,9 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
|||
|
||||
union file_handle_union h = FILE_HANDLE_INIT;
|
||||
int mount_id = -1, mount_id_parent = -1;
|
||||
_cleanup_free_ char *parent = NULL;
|
||||
struct stat a, b;
|
||||
int r;
|
||||
_cleanup_close_ int fd = -1;
|
||||
bool nosupp = false;
|
||||
|
||||
/* We are not actually interested in the file handles, but
|
||||
|
|
@ -476,7 +493,15 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
|||
if (path_equal(t, "/"))
|
||||
return 1;
|
||||
|
||||
r = name_to_handle_at(AT_FDCWD, t, &h.handle, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
|
||||
fd = openat(AT_FDCWD, t, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|(allow_symlink ? 0 : O_PATH));
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = name_to_handle_at(fd, "", &h.handle, &mount_id, AT_EMPTY_PATH);
|
||||
if (r < 0) {
|
||||
if (errno == ENOSYS)
|
||||
/* This kernel does not support name_to_handle_at()
|
||||
|
|
@ -493,12 +518,9 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
|||
return -errno;
|
||||
}
|
||||
|
||||
r = path_get_parent(t, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
h.handle.handle_bytes = MAX_HANDLE_SZ;
|
||||
r = name_to_handle_at(AT_FDCWD, parent, &h.handle, &mount_id_parent, AT_SYMLINK_FOLLOW);
|
||||
r = name_to_handle_at(fd, "..", &h.handle, &mount_id_parent, 0);
|
||||
if (r < 0)
|
||||
if (errno == EOPNOTSUPP)
|
||||
if (nosupp)
|
||||
|
|
@ -517,10 +539,7 @@ int path_is_mount_point(const char *t, bool allow_symlink) {
|
|||
return mount_id != mount_id_parent;
|
||||
|
||||
fallback:
|
||||
if (allow_symlink)
|
||||
r = stat(t, &a);
|
||||
else
|
||||
r = lstat(t, &a);
|
||||
r = fstatat(fd, "", &a, AT_EMPTY_PATH);
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENOENT)
|
||||
|
|
@ -529,14 +548,8 @@ fallback:
|
|||
return -errno;
|
||||
}
|
||||
|
||||
free(parent);
|
||||
parent = NULL;
|
||||
|
||||
r = path_get_parent(t, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = stat(parent, &b);
|
||||
r = fstatat(fd, "..", &b, 0);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ char* path_make_absolute_cwd(const char *p);
|
|||
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
||||
char* path_kill_slashes(char *path);
|
||||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||
int path_compare(const char *a, const char *b) _pure_;
|
||||
bool path_equal(const char *a, const char *b) _pure_;
|
||||
bool path_equal_or_files_same(const char *a, const char *b);
|
||||
char* path_join(const char *root, const char *path, const char *rest);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ const char* socket_address_get_path(const SocketAddress *a);
|
|||
|
||||
bool socket_ipv6_is_supported(void);
|
||||
|
||||
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, char **ret);
|
||||
int sockaddr_port(const struct sockaddr *_sa) _pure_;
|
||||
|
||||
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
|
||||
int getpeername_pretty(int fd, char **ret);
|
||||
int getsockname_pretty(int fd, char **ret);
|
||||
|
||||
|
|
|
|||
|
|
@ -82,9 +82,10 @@ void strv_clear(char **l) {
|
|||
*l = NULL;
|
||||
}
|
||||
|
||||
void strv_free(char **l) {
|
||||
char **strv_free(char **l) {
|
||||
strv_clear(l);
|
||||
free(l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **strv_copy(char * const *l) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ char *strv_find(char **l, const char *name) _pure_;
|
|||
char *strv_find_prefix(char **l, const char *name) _pure_;
|
||||
char *strv_find_startswith(char **l, const char *name) _pure_;
|
||||
|
||||
void strv_free(char **l);
|
||||
char **strv_free(char **l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
|
||||
#define _cleanup_strv_free_ _cleanup_(strv_freep)
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@
|
|||
#include "sparse-endian.h"
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
/* Put this test here for a lack of better place */
|
||||
assert_cc(EAGAIN == EWOULDBLOCK);
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int saved_argc = 0;
|
||||
char **saved_argv = NULL;
|
||||
|
|
@ -2350,6 +2353,17 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
|
|||
return n;
|
||||
}
|
||||
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
|
||||
ssize_t n;
|
||||
|
||||
n = loop_read(fd, buf, nbytes, do_poll);
|
||||
if (n < 0)
|
||||
return n;
|
||||
if ((size_t) n != nbytes)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0 /* NM_IGNORED */
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
||||
const uint8_t *p = buf;
|
||||
|
|
@ -2607,8 +2621,9 @@ char* dirname_malloc(const char *path) {
|
|||
int dev_urandom(void *p, size_t n) {
|
||||
#if 0 /* NM_IGNORED */
|
||||
static int have_syscall = -1;
|
||||
int r, fd;
|
||||
ssize_t k;
|
||||
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
/* Gathers some randomness from the kernel. This call will
|
||||
* never block, and will always return some data from the
|
||||
|
|
@ -2643,26 +2658,17 @@ int dev_urandom(void *p, size_t n) {
|
|||
return -errno;
|
||||
} else
|
||||
/* too short read? */
|
||||
return -EIO;
|
||||
return -ENODATA;
|
||||
}
|
||||
#else /* NM IGNORED */
|
||||
int fd;
|
||||
ssize_t k;
|
||||
_cleanup_close_ int fd = -1;
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return errno == ENOENT ? -ENOSYS : -errno;
|
||||
|
||||
k = loop_read(fd, p, n, true);
|
||||
safe_close(fd);
|
||||
|
||||
if (k < 0)
|
||||
return (int) k;
|
||||
if ((size_t) k != n)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
return loop_read_exact(fd, p, n, true);
|
||||
}
|
||||
|
||||
void initialize_srand(void) {
|
||||
|
|
@ -2951,31 +2957,30 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
|
|||
|
||||
/* This is an ugly hack */
|
||||
if (major(devnr) == 136) {
|
||||
asprintf(&b, "pts/%u", minor(devnr));
|
||||
goto finish;
|
||||
if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* Probably something like the ptys which have no
|
||||
* symlink in /dev/char. Let's return something
|
||||
* vaguely useful. */
|
||||
|
||||
b = strdup(fn + 5);
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
if (startswith(s, "/dev/"))
|
||||
p = s + 5;
|
||||
else if (startswith(s, "../"))
|
||||
p = s + 3;
|
||||
else
|
||||
p = s;
|
||||
|
||||
/* Probably something like the ptys which have no
|
||||
* symlink in /dev/char. Let's return something
|
||||
* vaguely useful. */
|
||||
|
||||
b = strdup(fn + 5);
|
||||
goto finish;
|
||||
b = strdup(p);
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (startswith(s, "/dev/"))
|
||||
p = s + 5;
|
||||
else if (startswith(s, "../"))
|
||||
p = s + 3;
|
||||
else
|
||||
p = s;
|
||||
|
||||
b = strdup(p);
|
||||
|
||||
finish:
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
|
||||
*r = b;
|
||||
if (_devnr)
|
||||
*_devnr = devnr;
|
||||
|
|
@ -4147,8 +4152,7 @@ static int do_execute(char **directories, usec_t timeout, char *argv[]) {
|
|||
if (null_or_empty_path(path)) {
|
||||
log_debug("%s is empty (a mask).", path);
|
||||
continue;
|
||||
} else
|
||||
log_debug("%s will be executed.", path);
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
|
|
@ -6710,7 +6714,7 @@ int getpeersec(int fd, char **ret) {
|
|||
|
||||
if (isempty(s)) {
|
||||
free(s);
|
||||
return -ENOTSUP;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
*ret = s;
|
||||
|
|
@ -7890,6 +7894,28 @@ int chattr_path(const char *p, bool b, unsigned mask) {
|
|||
return chattr_fd(fd, b, mask);
|
||||
}
|
||||
|
||||
int change_attr_fd(int fd, unsigned value, unsigned mask) {
|
||||
unsigned old_attr, new_attr;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
|
||||
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
new_attr = (old_attr & ~mask) |(value & mask);
|
||||
|
||||
if (new_attr == old_attr)
|
||||
return 0;
|
||||
|
||||
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret) {
|
||||
assert(fd >= 0);
|
||||
|
||||
|
|
@ -8172,4 +8198,45 @@ void cmsg_close_all(struct msghdr *mh) {
|
|||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
|
||||
close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
|
||||
}
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
|
||||
struct stat buf;
|
||||
int ret;
|
||||
|
||||
ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
|
||||
/* Even though renameat2() exists since Linux 3.15, btrfs added
|
||||
* support for it later. If it is not implemented, fallback to another
|
||||
* method. */
|
||||
if (errno != EINVAL)
|
||||
return -errno;
|
||||
|
||||
/* The link()/unlink() fallback does not work on directories. But
|
||||
* renameat() without RENAME_NOREPLACE gives the same semantics on
|
||||
* directories, except when newpath is an *empty* directory. This is
|
||||
* good enough. */
|
||||
ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
|
||||
if (ret >= 0 && S_ISDIR(buf.st_mode)) {
|
||||
ret = renameat(olddirfd, oldpath, newdirfd, newpath);
|
||||
return ret >= 0 ? 0 : -errno;
|
||||
}
|
||||
|
||||
/* If it is not a directory, use the link()/unlink() fallback. */
|
||||
ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
ret = unlinkat(olddirfd, oldpath, 0);
|
||||
if (ret < 0) {
|
||||
/* backup errno before the following unlinkat() alters it */
|
||||
ret = errno;
|
||||
(void) unlinkat(newdirfd, newpath, 0);
|
||||
errno = ret;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
|
|
|||
|
|
@ -438,6 +438,7 @@ int sigaction_many(const struct sigaction *sa, ...);
|
|||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
|
||||
|
||||
ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
|
||||
int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
|
||||
|
||||
bool is_device_path(const char *path);
|
||||
|
|
@ -1062,6 +1063,7 @@ int same_fd(int a, int b);
|
|||
|
||||
int chattr_fd(int fd, bool b, unsigned mask);
|
||||
int chattr_path(const char *p, bool b, unsigned mask);
|
||||
int change_attr_fd(int fd, unsigned value, unsigned mask);
|
||||
|
||||
int read_attr_fd(int fd, unsigned *ret);
|
||||
int read_attr_path(const char *p, unsigned *ret);
|
||||
|
|
@ -1090,3 +1092,5 @@ void sigkill_wait(pid_t *pid);
|
|||
int syslog_parse_priority(const char **p, int *priority, bool with_facility);
|
||||
|
||||
void cmsg_close_all(struct msghdr *mh);
|
||||
|
||||
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
SD_EVENT_PASSIVE,
|
||||
SD_EVENT_PREPARED,
|
||||
SD_EVENT_INITIAL,
|
||||
SD_EVENT_ARMED,
|
||||
SD_EVENT_PENDING,
|
||||
SD_EVENT_RUNNING,
|
||||
SD_EVENT_EXITING,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue