Commit b4564eaa authored by Thomas Haller's avatar Thomas Haller

systemd: update code from upstream

This is a direct dump from systemd git on 2016-05-12, git commit
42d35e1301928d08dd32ec51f0205252ae658ba5.

======

SYSTEMD_DIR=../systemd
COMMIT=42d35e1301928d08dd32ec51f0205252ae658ba5

(
  cd "$SYSTEMD_DIR"
  git checkout "$COMMIT"
  git reset --hard
  git clean -fdx
)

git ls-files :/src/systemd/src/ | xargs -d '\n' rm -f

nm_copy_sd() {
    mkdir -p "./src/systemd/$(dirname "$1")"
    cp "$SYSTEMD_DIR/$1" "./src/systemd/$1"
}

nm_copy_sd "src/basic/alloc-util.c"
nm_copy_sd "src/basic/alloc-util.h"
nm_copy_sd "src/basic/async.h"
nm_copy_sd "src/basic/escape.c"
nm_copy_sd "src/basic/escape.h"
nm_copy_sd "src/basic/ether-addr-util.c"
nm_copy_sd "src/basic/ether-addr-util.h"
nm_copy_sd "src/basic/extract-word.c"
nm_copy_sd "src/basic/extract-word.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.h"
nm_copy_sd "src/basic/fd-util.c"
nm_copy_sd "src/basic/fd-util.h"
nm_copy_sd "src/basic/fs-util.c"
nm_copy_sd "src/basic/fs-util.h"
nm_copy_sd "src/basic/hash-funcs.c"
nm_copy_sd "src/basic/hash-funcs.h"
nm_copy_sd "src/basic/hashmap.c"
nm_copy_sd "src/basic/hashmap.h"
nm_copy_sd "src/basic/hexdecoct.c"
nm_copy_sd "src/basic/hexdecoct.h"
nm_copy_sd "src/basic/hostname-util.c"
nm_copy_sd "src/basic/hostname-util.h"
nm_copy_sd "src/basic/in-addr-util.c"
nm_copy_sd "src/basic/in-addr-util.h"
nm_copy_sd "src/basic/io-util.c"
nm_copy_sd "src/basic/io-util.h"
nm_copy_sd "src/basic/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/mempool.h"
nm_copy_sd "src/basic/mempool.c"
nm_copy_sd "src/basic/parse-util.c"
nm_copy_sd "src/basic/parse-util.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
nm_copy_sd "src/basic/prioq.h"
nm_copy_sd "src/basic/prioq.c"
nm_copy_sd "src/basic/random-util.c"
nm_copy_sd "src/basic/random-util.h"
nm_copy_sd "src/basic/refcnt.h"
nm_copy_sd "src/basic/set.h"
nm_copy_sd "src/basic/signal-util.h"
nm_copy_sd "src/basic/siphash24.c"
nm_copy_sd "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.c"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.h"
nm_copy_sd "src/basic/stdio-util.h"
nm_copy_sd "src/basic/string-table.c"
nm_copy_sd "src/basic/string-table.h"
nm_copy_sd "src/basic/string-util.c"
nm_copy_sd "src/basic/string-util.h"
nm_copy_sd "src/basic/strv.c"
nm_copy_sd "src/basic/strv.h"
nm_copy_sd "src/basic/time-util.c"
nm_copy_sd "src/basic/time-util.h"
nm_copy_sd "src/basic/umask-util.h"
nm_copy_sd "src/basic/unaligned.h"
nm_copy_sd "src/basic/utf8.c"
nm_copy_sd "src/basic/utf8.h"
nm_copy_sd "src/basic/util.c"
nm_copy_sd "src/basic/util.h"
nm_copy_sd "src/libsystemd-network/arp-util.c"
nm_copy_sd "src/libsystemd-network/arp-util.h"
nm_copy_sd "src/libsystemd-network/dhcp6-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp6-network.c"
nm_copy_sd "src/libsystemd-network/dhcp6-option.c"
nm_copy_sd "src/libsystemd-network/dhcp6-protocol.h"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.c"
nm_copy_sd "src/libsystemd-network/dhcp-identifier.h"
nm_copy_sd "src/libsystemd-network/dhcp-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-lease-internal.h"
nm_copy_sd "src/libsystemd-network/dhcp-network.c"
nm_copy_sd "src/libsystemd-network/dhcp-option.c"
nm_copy_sd "src/libsystemd-network/dhcp-packet.c"
nm_copy_sd "src/libsystemd-network/dhcp-protocol.h"
nm_copy_sd "src/libsystemd-network/lldp-internal.h"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.c"
nm_copy_sd "src/libsystemd-network/lldp-neighbor.h"
nm_copy_sd "src/libsystemd-network/lldp-network.c"
nm_copy_sd "src/libsystemd-network/lldp-network.h"
nm_copy_sd "src/libsystemd-network/network-internal.c"
nm_copy_sd "src/libsystemd-network/network-internal.h"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp6-lease.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-client.c"
nm_copy_sd "src/libsystemd-network/sd-dhcp-lease.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4ll.c"
nm_copy_sd "src/libsystemd-network/sd-ipv4acd.c"
nm_copy_sd "src/libsystemd-network/sd-lldp.c"
nm_copy_sd "src/libsystemd/sd-event/sd-event.c"
nm_copy_sd "src/libsystemd/sd-id128/sd-id128.c"
nm_copy_sd "src/shared/dns-domain.c"
nm_copy_sd "src/shared/dns-domain.h"
nm_copy_sd "src/systemd/_sd-common.h"
nm_copy_sd "src/systemd/sd-dhcp6-client.h"
nm_copy_sd "src/systemd/sd-dhcp6-lease.h"
nm_copy_sd "src/systemd/sd-dhcp-client.h"
nm_copy_sd "src/systemd/sd-dhcp-lease.h"
nm_copy_sd "src/systemd/sd-event.h"
nm_copy_sd "src/systemd/sd-ndisc.h"
nm_copy_sd "src/systemd/sd-id128.h"
nm_copy_sd "src/systemd/sd-ipv4acd.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
nm_copy_sd "src/systemd/sd-lldp.h"
parent 38abb711
This diff is collapsed.
#pragma once
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
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
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "macro.h"
typedef enum ExtractFlags {
EXTRACT_RELAX = 1,
EXTRACT_CUNESCAPE = 2,
EXTRACT_CUNESCAPE_RELAX = 4,
EXTRACT_QUOTES = 8,
EXTRACT_DONT_COALESCE_SEPARATORS = 16,
EXTRACT_RETAIN_ESCAPE = 32,
} ExtractFlags;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
......@@ -25,11 +25,13 @@
#include <unistd.h>
#include "fd-util.h"
#include "fs-util.h"
#include "macro.h"
#include "missing.h"
#include "parse-util.h"
#include "path-util.h"
#include "socket-util.h"
#include "stdio-util.h"
#include "util.h"
int close_nointr(int fd) {
......@@ -229,7 +231,7 @@ int close_all_fds(const int except[], unsigned n_except) {
while ((de = readdir(d))) {
int fd = -1;
if (hidden_file(de->d_name))
if (hidden_or_backup_file(de->d_name))
continue;
if (safe_atoi(de->d_name, &fd) < 0)
......@@ -356,3 +358,17 @@ bool fdname_is_valid(const char *s) {
return p - s < 256;
}
int fd_get_path(int fd, char **ret) {
char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
int r;
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
r = readlink_malloc(procfs_path, ret);
if (r == -ENOENT) /* If the file doesn't exist the fd is invalid */
return -EBADF;
return r;
}
......@@ -72,6 +72,8 @@ void cmsg_close_all(struct msghdr *mh);
bool fdname_is_valid(const char *s);
int fd_get_path(int fd, char **ret);
/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
#define ERRNO_IS_DISCONNECT(r) \
IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
......@@ -1083,30 +1083,6 @@ int mkostemp_safe(char *pattern, int flags) {
return fd;
}
int open_tmpfile(const char *path, int flags) {
char *p;
int fd;
assert(path);
#ifdef O_TMPFILE
/* Try O_TMPFILE first, if it is supported */
fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
if (fd >= 0)
return fd;
#endif
/* Fall back to unguessable name + unlinking */
p = strjoina(path, "/systemd-tmp-XXXXXX");
fd = mkostemp_safe(p, flags);
if (fd < 0)
return fd;
unlink(p);
return fd;
}
int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
const char *fn;
char *t;
......@@ -1278,3 +1254,103 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
return fputs(s, f);
}
int open_tmpfile_unlinkable(const char *directory, int flags) {
char *p;
int fd;
assert(directory);
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */
#ifdef O_TMPFILE
/* Try O_TMPFILE first, if it is supported */
fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
if (fd >= 0)
return fd;
#endif
/* Fall back to unguessable name + unlinking */
p = strjoina(directory, "/systemd-tmp-XXXXXX");
fd = mkostemp_safe(p, flags);
if (fd < 0)
return fd;
(void) unlink(p);
return fd;
}
int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
_cleanup_free_ char *tmp = NULL;
int r, fd;
assert(target);
assert(ret_path);
/* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
assert((flags & O_EXCL) == 0);
/* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – 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. */
#ifdef O_TMPFILE
{
_cleanup_free_ char *dn = NULL;
dn = dirname_malloc(target);
if (!dn)
return -ENOMEM;
fd = open(dn, O_TMPFILE|flags, 0640);
if (fd >= 0) {
*ret_path = NULL;
return fd;
}
log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
}
#endif
r = tempfn_random(target, NULL, &tmp);
if (r < 0)
return r;
fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
if (fd < 0)
return -errno;
*ret_path = tmp;
tmp = NULL;
return fd;
}
int link_tmpfile(int fd, const char *path, const char *target) {
assert(fd >= 0);
assert(target);
/* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
* created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
* on the directory, and renameat2() is used instead.
*
* Note that in both cases we will not replace existing files. This is because linkat() does not support this
* operation currently (renameat2() does), and there is no nice way to emulate this. */
if (path) {
if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
return -errno;
} else {
char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
return -errno;
}
return 0;
}
......@@ -72,7 +72,6 @@ int fflush_and_check(FILE *f);
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
int mkostemp_safe(char *pattern, int flags);
int open_tmpfile(const char *path, int flags);
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
int tempfn_random(const char *p, const char *extra, char **ret);
......@@ -82,3 +81,8 @@ int write_timestamp_file_atomic(const char *fn, usec_t n);
int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);
int open_tmpfile_unlinkable(const char *directory, int flags);
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
int link_tmpfile(int fd, const char *path, const char *target);
......@@ -38,6 +38,7 @@
#include "mkdir.h"
#include "parse-util.h"
#include "path-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
......@@ -493,3 +494,17 @@ int get_files_in_directory(const char *path, char ***list) {
return n;
}
int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
char path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
int r;
/* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
xsprintf(path, "/proc/self/fd/%i", what);
r = inotify_add_watch(fd, path, mask);
if (r < 0)
return -errno;
return r;
}
......@@ -72,3 +72,5 @@ union inotify_event_buffer {
struct inotify_event ev;
uint8_t raw[INOTIFY_EVENT_MAX];
};
int inotify_add_watch_fd(int fd, int what, uint32_t mask);
......@@ -1773,20 +1773,18 @@ int set_consume(Set *s, void *value) {
int set_put_strdup(Set *s, const char *p) {
char *c;
int r;
assert(s);
assert(p);
if (set_contains(s, (char*) p))
return 0;
c = strdup(p);
if (!c)
return -ENOMEM;
r = set_consume(s, c);
if (r == -EEXIST)
return 0;
return r;
return set_consume(s, c);
}
int set_put_strdupv(Set *s, char **l) {
......
......@@ -33,6 +33,11 @@ int flush_fd(int fd) {
.events = POLLIN,
};
/* Read from the specified file descriptor, until POLLIN is not set anymore, throwing away everything
* read. Note that some file descriptors (notable IP sockets) will trigger POLLIN even when no data can be read
* (due to IP packet checksum mismatches), hence this function is only safe to be non-blocking if the fd used
* was set to non-blocking too. */
for (;;) {
char buf[LINE_MAX];
ssize_t l;
......
......@@ -93,7 +93,7 @@ static inline int safe_atoli(const char *s, long int *ret_u) {
#if SIZE_MAX == UINT_MAX
static inline int safe_atozu(const char *s, size_t *ret_u) {
assert_cc(sizeof(size_t) == sizeof(unsigned));
return safe_atou(s, ret_u);
return safe_atou(s, (unsigned *) ret_u);
}
#else
static inline int safe_atozu(const char *s, size_t *ret_u) {
......
......@@ -756,34 +756,53 @@ char *file_in_same_dir(const char *path, const char *filename) {
return ret;
}
bool hidden_file_allow_backup(const char *filename) {
assert(filename);
return
filename[0] == '.' ||
streq(filename, "lost+found") ||
streq(filename, "aquota.user") ||
streq(filename, "aquota.group") ||
endswith(filename, ".rpmnew") ||
endswith(filename, ".rpmsave") ||
endswith(filename, ".rpmorig") ||
endswith(filename, ".dpkg-old") ||
endswith(filename, ".dpkg-new") ||
endswith(filename, ".dpkg-tmp") ||
endswith(filename, ".dpkg-dist") ||
endswith(filename, ".dpkg-bak") ||
endswith(filename, ".dpkg-backup") ||
endswith(filename, ".dpkg-remove") ||
endswith(filename, ".swp");
}
bool hidden_or_backup_file(const char *filename) {
const char *p;
bool hidden_file(const char *filename) {
assert(filename);
if (endswith(filename, "~"))
if (filename[0] == '.' ||
streq(filename, "lost+found") ||
streq(filename, "aquota.user") ||
streq(filename, "aquota.group") ||
endswith(filename, "~"))
return true;
return hidden_file_allow_backup(filename);
p = strrchr(filename, '.');
if (!p)
return false;
/* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
* with always new suffixes and that everybody else should just adjust to that, then it really should be on
* them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
* one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
* string. Specifically: there's now:
*
* The generic suffixes "~" and ".bak" for backup files
* The generic prefix "." for hidden files
*
* Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
* or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
*/
return STR_IN_SET(p + 1,
"rpmnew",
"rpmsave",
"rpmorig",
"dpkg-old",
"dpkg-new",
"dpkg-tmp",
"dpkg-dist",
"dpkg-bak",
"dpkg-backup",
"dpkg-remove",
"ucf-new",
"ucf-old",
"ucf-dist",
"swp",
"bak",
"old",
"new");
}
bool is_device_path(const char *path) {
......
......@@ -122,7 +122,6 @@ bool path_is_safe(const char *p) _pure_;
char *file_in_same_dir(const char *path, const char *filename);
bool hidden_file_allow_backup(const char *filename);
bool hidden_file(const char *filename) _pure_;
bool hidden_or_backup_file(const char *filename) _pure_;
bool is_device_path(const char *path);
......@@ -23,6 +23,7 @@
#include <net/if.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <poll.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
......@@ -42,7 +43,9 @@
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
#include "utf8.h"
#include "util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
......@@ -794,6 +797,42 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
bool ifname_valid(const char *p) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
* but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
* also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
if (isempty(p))
return false;
if (strlen(p) >= IFNAMSIZ)
return false;
if (STR_IN_SET(p, ".", ".."))
return false;
while (*p) {
if ((unsigned char) *p >= 127U)
return false;
if ((unsigned char) *p <= 32U)
return false;
if (*p == ':' || *p == '/')
return false;
numeric = numeric && (*p >= '0' && *p <= '9');
p++;
}
if (numeric)
return false;
return true;
}
int getpeercred(int fd, struct ucred *ucred) {
socklen_t n = sizeof(struct ucred);
struct ucred u;
......@@ -970,3 +1009,42 @@ fallback:
return (ssize_t) k;
}
int flush_accept(int fd) {
struct pollfd pollfd = {
.fd = fd,
.events = POLLIN,
};
int r;
/* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
for (;;) {
int cfd;
r = poll(&pollfd, 1, 0);
if (r < 0) {
if (errno == EINTR)
continue;
return -errno;
} else if (r == 0)
return 0;
cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
if (cfd < 0) {
if (errno == EINTR)
continue;
if (errno == EAGAIN)
return 0;
return -errno;
}
close(cfd);
}
}
......@@ -123,6 +123,8 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
bool ifname_valid(const char *p);
int getpeercred(int fd, struct ucred *ucred);
int getpeersec(int fd, char **ret);
......@@ -135,5 +137,18 @@ int receive_one_fd(int transport_fd, int flags);
ssize_t next_datagram_size_fd(int fd);
int flush_accept(int fd);
#define CMSG_FOREACH(cmsg, mh) \
for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
#define SOCKADDR_UN_LEN(sa) \
({ \
const struct sockaddr_un *_sa = &(sa); \
assert(_sa->sun_family == AF_UNIX); \
offsetof(struct sockaddr_un, sun_path) + \
(_sa->sun_path[0] == 0 ? \
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
})
......@@ -1080,22 +1080,31 @@ bool timezone_is_valid(const char *name) {
return true;
}
clockid_t clock_boottime_or_monotonic(void) {
static clockid_t clock = -1;
int fd;
if (clock != -1)
return clock;
fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
if (fd < 0)
clock = CLOCK_MONOTONIC;
else {
safe_close(fd);
clock = CLOCK_BOOTTIME;
bool clock_boottime_supported(void) {
static int supported = -1;
/* Note that this checks whether CLOCK_BOOTTIME is available in general as well as available for timerfds()! */
if (supported < 0) {
int fd;
fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
if (fd < 0)
supported = false;
else {
safe_close(fd);
supported = true;
}
}
return clock;
return supported;
}
clockid_t clock_boottime_or_monotonic(void) {
if (clock_boottime_supported())
return CLOCK_BOOTTIME;
else
return CLOCK_MONOTONIC;
}
int get_timezone(char **tz) {
......
......@@ -112,6 +112,7 @@ bool ntp_synced(void);
int get_timezones(char ***l);
bool timezone_is_valid(const char *name);
bool clock_boottime_supported(void);
clockid_t clock_boottime_or_monotonic(void);
#define xstrftime(buf, fmt, tm) \
......
......@@ -522,7 +522,7 @@ int on_ac_power(void) {
if (!de)
break;
if (hidden_file(de->d_name))
if (hidden_or_backup_file(de->d_name))
continue;
device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
......
......@@ -31,6 +31,37 @@
#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)
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
struct duid d;
assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
if (duid_len > MAX_DUID_LEN)
return -EINVAL;
switch (duid_type) {
case DUID_TYPE_LLT:
if (duid_len <= sizeof(d.llt))
return -EINVAL;
break;
case DUID_TYPE_EN:
if (duid_len != sizeof(d.en))
return -EINVAL;
break;
case DUID_TYPE_LL:
if (duid_len <= sizeof(d.ll))
return -EINVAL;
break;
case DUID_TYPE_UUID:
if (duid_len != sizeof(d.uuid))
return -EINVAL;
break;
default:
/* accept unknown type in order to be forward compatible */
break;
}
return 0;
}
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
uint64_t hash;
......
......@@ -26,7 +26,6 @@
#include "unaligned.h"
typedef enum DUIDType {
DUID_TYPE_RAW = 0,
DUID_TYPE_LLT = 1,
DUID_TYPE_EN = 2,
DUID_TYPE_LL = 3,
......@@ -40,27 +39,28 @@ typedef enum DUIDType {
*/
#define MAX_DUID_LEN 128
/* https://tools.ietf.org/html/rfc3315#section-9.1 */
struct duid {
be16_t type;
union {
struct {
/* DHCP6_DUID_LLT */
/* DUID_TYPE_LLT */
uint16_t htype;
uint32_t time;
uint8_t haddr[0];
} _packed_ llt;
struct {
/* DHCP6_DUID_EN */
/* DUID_TYPE_EN */
uint32_t pen;
uint8_t id[8];
} _packed_ en;
struct {
/* DHCP6_DUID_LL */
/* DUID_TYPE_LL */
int16_t htype;
uint8_t haddr[0];
} _packed_ ll;
struct {
/* DHCP6_DUID_UUID */
/* DUID_TYPE_UUID */
sd_id128_t uuid;
} _packed_ uuid;
struct {
......@@ -69,36 +69,6 @@ struct duid {
};
} _packed_;
int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
struct duid d;
assert(duid_len > 0);
switch (duid_type) {
case DUID_TYPE_LLT:
if (duid_len <= sizeof(d.llt))
return -EINVAL;
break;
case DUID_TYPE_EN