Commit cd5ef1ed authored by Thomas Haller's avatar Thomas Haller

systemd: update code from upstream (2017-06-14)

This is a direct dump from systemd git on 2017-06-14, git commit
42d3bf86bb75842602d3712caa2baccd09a1c795.

======

SYSTEMD_DIR=../systemd
COMMIT=42d3bf86bb75842602d3712caa2baccd09a1c795

(
  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/id128-util.c"
nm_copy_sd "src/libsystemd/sd-id128/id128-util.h"
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 c5decf7e
......@@ -51,7 +51,7 @@
#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts) {
assert(f);
assert(line);
......@@ -60,6 +60,13 @@ int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
if (enforce_newline && !endswith(line, "\n"))
fputc('\n', f);
if (ts) {
struct timespec twice[2] = {*ts, *ts};
if (futimens(fileno(f), twice) < 0)
return -errno;
}
return fflush_and_check(f);
}
......@@ -89,7 +96,7 @@ static int write_string_file_atomic(const char *fn, const char *line, bool enfor
return r;
}
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
_cleanup_fclose_ FILE *f = NULL;
int q, r;
......@@ -104,7 +111,8 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
goto fail;
return r;
}
} else
assert(ts == NULL);
if (flags & WRITE_STRING_FILE_CREATE) {
f = fopen(fn, "we");
......@@ -131,7 +139,7 @@ int write_string_file(const char *fn, const char *line, WriteStringFileFlags fla
}
}
r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
r = write_string_stream_ts(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE), ts);
if (r < 0)
goto fail;
......
......@@ -35,8 +35,14 @@ typedef enum {
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8,
} WriteStringFileFlags;
int write_string_stream(FILE *f, const char *line, bool enforce_newline);
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags);
int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts);
static inline int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
return write_string_stream_ts(f, line, enforce_newline, NULL);
}
int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
return write_string_file_ts(fn, line, flags, NULL);
}
int read_one_line_file(const char *fn, char **line);
int read_full_file(const char *fn, char **contents, size_t *size);
......
......@@ -31,6 +31,16 @@
#include "macro.h"
typedef enum LogRealm {
LOG_REALM_SYSTEMD,
LOG_REALM_UDEV,
_LOG_REALM_MAX,
} LogRealm;
#ifndef LOG_REALM
# define LOG_REALM LOG_REALM_SYSTEMD
#endif
typedef enum LogTarget{
LOG_TARGET_CONSOLE,
LOG_TARGET_CONSOLE_PREFIXED,
......@@ -44,14 +54,24 @@ typedef enum LogTarget{
LOG_TARGET_NULL,
_LOG_TARGET_MAX,
_LOG_TARGET_INVALID = -1
} LogTarget;
} LogTarget;
#define LOG_REALM_PLUS_LEVEL(realm, level) \
((realm) << 10 | (level))
#define LOG_REALM_REMOVE_LEVEL(realm_level) \
((realm_level >> 10))
void log_set_target(LogTarget target);
void log_set_max_level(int level);
void log_set_max_level_realm(LogRealm realm, int level);
#define log_set_max_level(level) \
log_set_max_level_realm(LOG_REALM, (level))
void log_set_facility(int facility);
int log_set_target_from_string(const char *e);
int log_set_max_level_from_string(const char *e);
int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
#define log_set_max_level_from_string(e) \
log_set_max_level_from_string_realm(LOG_REALM, (e))
void log_show_color(bool b);
bool log_get_show_color(void) _pure_;
......@@ -62,7 +82,9 @@ int log_show_color_from_string(const char *e);
int log_show_location_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
int log_get_max_level(void) _pure_;
int log_get_max_level_realm(LogRealm realm) _pure_;
#define log_get_max_level() \
log_get_max_level_realm(LOG_REALM)
int log_open(void);
void log_close(void);
......@@ -73,7 +95,9 @@ void log_close_journal(void);
void log_close_kmsg(void);
void log_close_console(void);
void log_parse_environment(void);
void log_parse_environment_realm(LogRealm realm);
#define log_parse_environment() \
log_parse_environment_realm(LOG_REALM)
int log_dispatch_internal(
int level,
......@@ -87,15 +111,17 @@ int log_dispatch_internal(
const char *extra_field,
char *buffer);
int log_internal(
int log_internal_realm(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) _printf_(6,7);
#define log_internal(level, ...) \
log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
int log_internalv(
int log_internalv_realm(
int level,
int error,
const char *file,
......@@ -103,7 +129,10 @@ int log_internalv(
const char *func,
const char *format,
va_list ap) _printf_(6,0);
#define log_internalv(level, ...) \
log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
/* Realm is fixed to LOG_REALM_SYSTEMD for those */
int log_object_internal(
int level,
int error,
......@@ -138,6 +167,7 @@ int log_struct_internal(
const char *format, ...) _printf_(6,0) _sentinel_;
int log_oom_internal(
LogRealm realm,
const char *file,
int line,
const char *func);
......@@ -161,37 +191,50 @@ int log_dump_internal(
char *buffer);
/* Logging for various assertions */
noreturn void log_assert_failed(
noreturn void log_assert_failed_realm(
LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
#define log_assert_failed(text, ...) \
log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
noreturn void log_assert_failed_unreachable(
noreturn void log_assert_failed_unreachable_realm(
LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
#define log_assert_failed_unreachable(text, ...) \
log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
void log_assert_failed_return(
void log_assert_failed_return_realm(
LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
#define log_assert_failed_return(text, ...) \
log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
#define log_dispatch(level, error, buffer) \
log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
/* Logging with level */
#define log_full_errno(level, error, ...) \
#define log_full_errno_realm(realm, level, error, ...) \
({ \
int _level = (level), _e = (error); \
(log_get_max_level() >= LOG_PRI(_level)) \
? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
(log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \
? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \
__FILE__, __LINE__, __func__, __VA_ARGS__) \
: -abs(_e); \
})
#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
#define log_full_errno(level, error, ...) \
log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
/* Normal logging */
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
......@@ -216,13 +259,17 @@ void log_assert_failed_return(
#endif
/* Structured logging */
#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define log_struct_errno(level, error, ...) \
log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
error, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
/* This modifies the buffer passed! */
#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
#define log_dump(level, buffer) \
log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
0, __FILE__, __LINE__, __func__, buffer)
#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
bool log_on_console(void) _pure_;
......
......@@ -19,7 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
......
......@@ -555,15 +555,29 @@ void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
uint64_t a, b;
int r, pos;
assert(value);
assert(t);
if (sscanf(value, "%" PRIu64 "%" PRIu64, &a, &b) != 2) {
log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
pos = strspn(value, WHITESPACE);
if (value[pos] == '-')
return -EINVAL;
pos += strspn(value + pos, DIGITS);
pos += strspn(value + pos, WHITESPACE);
if (value[pos] == '-')
return -EINVAL;
r = sscanf(value, "%" PRIu64 "%" PRIu64 "%n", &a, &b, &pos);
if (r != 2) {
log_debug("Failed to parse dual timestamp value \"%s\".", value);
return -EINVAL;
}
if (value[pos] != '\0')
/* trailing garbage */
return -EINVAL;
t->realtime = a;
t->monotonic = b;
......
......@@ -75,6 +75,7 @@ struct sd_dhcp_lease {
uint16_t mtu; /* 0 if unset */
char *domainname;
char **search_domains;
char *hostname;
char *root_path;
......@@ -92,6 +93,7 @@ struct sd_dhcp_lease {
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
......
......@@ -1655,7 +1655,8 @@ static int client_receive_message_udp(
if (errno == EAGAIN || errno == EINTR)
return 0;
return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m");
return log_dhcp_client_errno(client, errno,
"Could not receive message from UDP socket: %m");
}
if ((size_t) len < sizeof(DHCPMessage)) {
log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
......@@ -1748,9 +1749,8 @@ static int client_receive_message_raw(
if (errno == EAGAIN || errno == EINTR)
return 0;
log_dhcp_client(client, "Could not receive message from raw socket: %m");
return -errno;
return log_dhcp_client_errno(client, errno,
"Could not receive message from raw socket: %m");
} else if ((size_t)len < sizeof(DHCPPacket))
return 0;
......
......@@ -231,6 +231,21 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
return (int) lease->static_route_size;
}
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
unsigned r;
assert_return(lease, -EINVAL);
assert_return(domains, -EINVAL);
r = strv_length(lease->search_domains);
if (r > 0) {
*domains = lease->search_domains;
return (int) r;
}
return -ENODATA;
}
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
assert_return(lease, -EINVAL);
assert_return(data, -EINVAL);
......@@ -282,6 +297,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
strv_free(lease->search_domains);
return mfree(lease);
}
......@@ -594,6 +610,11 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
r = lease_parse_u16(option, len, &lease->mtu, 68);
if (r < 0)
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
if (lease->mtu < DHCP_DEFAULT_MIN_SIZE) {
log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_DEFAULT_MIN_SIZE);
lease->mtu = DHCP_DEFAULT_MIN_SIZE;
}
break;
case SD_DHCP_OPTION_DOMAIN_NAME:
......@@ -605,6 +626,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
if (r < 0)
log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
break;
case SD_DHCP_OPTION_HOST_NAME:
r = lease_parse_domain(option, len, &lease->hostname);
if (r < 0) {
......@@ -696,6 +723,96 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
return 0;
}
/* Parses compressed domain names. */
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
_cleanup_strv_free_ char **names = NULL;
size_t pos = 0, cnt = 0;
int r;
assert(domains);
assert_return(option && len > 0, -ENODATA);
while (pos < len) {
_cleanup_free_ char *name = NULL;
size_t n = 0, allocated = 0;
size_t jump_barrier = pos, next_chunk = 0;
bool first = true;
for (;;) {
uint8_t c;
c = option[pos++];
if (c == 0) {
/* End of name */
break;
} else if (c <= 63) {
const char *label;
/* Literal label */
label = (const char*) (option + pos);
pos += c;
if (pos >= len)
return -EBADMSG;
if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
return -ENOMEM;
if (first)
first = false;
else
name[n++] = '.';
r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
if (r < 0)
return r;
n += r;
} else if ((c & 0xc0) == 0xc0) {
/* Pointer */
uint8_t d;
uint16_t ptr;
if (pos >= len)
return -EBADMSG;
d = option[pos++];
ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
/* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
if (ptr >= jump_barrier)
return -EBADMSG;
jump_barrier = ptr;
/* Save current location so we don't end up re-parsing what's parsed so far. */
if (next_chunk == 0)
next_chunk = pos;
pos = ptr;
} else
return -EBADMSG;
}
if (!GREEDY_REALLOC(name, allocated, n + 1))
return -ENOMEM;
name[n] = 0;
r = strv_extend(&names, name);
if (r < 0)
return r;
cnt++;
if (next_chunk != 0)
pos = next_chunk;
}
*domains = names;
names = NULL;
return cnt;
}
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
struct sd_dhcp_raw_option *cur, *option;
......@@ -751,6 +868,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
const char *string;
uint16_t mtu;
_cleanup_free_ sd_dhcp_route **routes = NULL;
char **search_domains = NULL;
uint32_t t1, t2, lifetime;
int r;
......@@ -824,6 +942,13 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
if (r > 0) {
fputs("DOMAIN_SEARCH_LIST=", f);
fputstrv(f, search_domains, NULL, NULL);
fputs("\n", f);
}
r = sd_dhcp_lease_get_hostname(lease, &string);
if (r >= 0)
fprintf(f, "HOSTNAME=%s\n", string);
......@@ -905,6 +1030,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*ntp = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
*client_id_hex = NULL,
*vendor_specific_hex = NULL,
*lifetime = NULL,
......@@ -933,6 +1059,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
"DOMAIN_SEARCH_LIST", &domains,
"ROOT_PATH", &lease->root_path,
"ROUTES", &routes,
"CLIENTID", &client_id_hex,
......@@ -1038,6 +1165,18 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
}
if (domains) {
_cleanup_strv_free_ char **a = NULL;
a = strv_split(domains, " ");
if (!a)
return -ENOMEM;
if (!strv_isempty(a)) {
lease->search_domains = a;
a = NULL;
}
}
if (routes) {
r = deserialize_dhcp_routes(
&lease->static_route,
......
......@@ -17,9 +17,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#ifdef HAVE_LIBIDN
#include <idna.h>
#include <stringprep.h>
#if defined(HAVE_LIBIDN2)
# include <idn2.h>
#elif defined(HAVE_LIBIDN)
# include <idna.h>
# include <stringprep.h>
#endif
#include <endian.h>
......@@ -299,8 +301,8 @@ int dns_label_escape_new(const char *p, size_t l, char **ret) {
return r;
}
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
#ifdef HAVE_LIBIDN
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
_cleanup_free_ uint32_t *input = NULL;
size_t input_size, l;
const char *p;
......@@ -348,13 +350,9 @@ int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded
decoded[l] = 0;
return (int) l;
#else
return 0;
#endif
}
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
#ifdef HAVE_LIBIDN
size_t input_size, output_size;
_cleanup_free_ uint32_t *input = NULL;
_cleanup_free_ char *result = NULL;
......@@ -399,10 +397,8 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
decoded[w] = 0;
return w;
#else
return 0;
#endif
}
#endif
int dns_name_concat(const char *a, const char *b, char **_ret) {
_cleanup_free_ char *ret = NULL;
......@@ -1274,6 +1270,23 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret) {
}
int dns_name_apply_idna(const char *name, char **ret) {
/* Return negative on error, 0 if not implemented, positive on success. */
#if defined(HAVE_LIBIDN2)
int r;
assert(name);
assert(ret);
r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
if (r == IDN2_OK)
return 1; /* *ret has been written */
else if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
return -ENOSPC;
else
return -EINVAL;
#elif defined(HAVE_LIBIDN)
_cleanup_free_ char *buf = NULL;
size_t n = 0, allocated = 0;
bool first = true;
......@@ -1323,6 +1336,9 @@ int dns_name_apply_idna(const char *name, char **ret) {
buf = NULL;
return (int) n;
#else
return 0;
#endif
}
int dns_name_is_valid_or_address(const char *name) {
......
......@@ -51,8 +51,10 @@ static inline int dns_name_parent(const char **name) {
return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
}
#if defined(HAVE_LIBIDN)
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
#endif
int dns_name_concat(const char *a, const char *b, char **ret);
......
......@@ -76,6 +76,7 @@ enum {
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,