diff --git a/src/systemd/src/basic/fd-util.c b/src/systemd/src/basic/fd-util.c index f3863722ee..a0820a9667 100644 --- a/src/systemd/src/basic/fd-util.c +++ b/src/systemd/src/basic/fd-util.c @@ -368,7 +368,7 @@ bool fdname_is_valid(const char *s) { } int fd_get_path(int fd, char **ret) { - char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; int r; xsprintf(procfs_path, "/proc/self/fd/%i", fd); diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index 1ce7b85fba..3ab50bca2f 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -167,6 +167,9 @@ int write_string_file_ts( } } + if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) + setvbuf(f, NULL, _IONBF, 0); + r = write_string_stream_ts(f, line, flags, ts); if (r < 0) goto fail; diff --git a/src/systemd/src/basic/fileio.h b/src/systemd/src/basic/fileio.h index c283f41f09..da5d5c66b5 100644 --- a/src/systemd/src/basic/fileio.h +++ b/src/systemd/src/basic/fileio.h @@ -35,6 +35,7 @@ typedef enum { WRITE_STRING_FILE_AVOID_NEWLINE = 1<<2, WRITE_STRING_FILE_VERIFY_ON_FAILURE = 1<<3, WRITE_STRING_FILE_SYNC = 1<<4, + WRITE_STRING_FILE_DISABLE_BUFFER = 1<<5, /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file() diff --git a/src/systemd/src/basic/hostname-util.c b/src/systemd/src/basic/hostname-util.c index 12a579b38a..b59e5425a5 100644 --- a/src/systemd/src/basic/hostname-util.c +++ b/src/systemd/src/basic/hostname-util.c @@ -221,6 +221,38 @@ int sethostname_idempotent(const char *s) { return 1; } +int shorten_overlong(const char *s, char **ret) { + char *h, *p; + + /* Shorten an overlong name to HOST_NAME_MAX or to the first dot, + * whatever comes earlier. */ + + assert(s); + + h = strdup(s); + if (!h) + return -ENOMEM; + + if (hostname_is_valid(h, false)) { + *ret = h; + return 0; + } + + p = strchr(h, '.'); + if (p) + *p = 0; + + strshorten(h, HOST_NAME_MAX); + + if (!hostname_is_valid(h, false)) { + free(h); + return -EDOM; + } + + *ret = h; + return 1; +} + int read_etc_hostname_stream(FILE *f, char **ret) { int r; diff --git a/src/systemd/src/basic/hostname-util.h b/src/systemd/src/basic/hostname-util.h index 52fd6b0899..d837d6f28c 100644 --- a/src/systemd/src/basic/hostname-util.h +++ b/src/systemd/src/basic/hostname-util.h @@ -39,5 +39,7 @@ bool is_gateway_hostname(const char *hostname); int sethostname_idempotent(const char *s); +int shorten_overlong(const char *s, char **ret); + int read_etc_hostname_stream(FILE *f, char **ret); int read_etc_hostname(const char *path, char **ret); diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h index 78679083e8..02d22de833 100644 --- a/src/systemd/src/basic/macro.h +++ b/src/systemd/src/basic/macro.h @@ -144,6 +144,14 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ sizeof(x)/sizeof((x)[0]), \ (void)0)) + +/* + * STRLEN - return the length of a string literal, minus the trailing NUL byte. + * Contrary to strlen(), this is a constant expression. + * @x: a string literal. + */ +#define STRLEN(x) (sizeof(""x"") - 1) + /* * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index 7063bd986e..a186bca38f 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -987,7 +987,7 @@ int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) { } LIST_FOREACH(options, option, lease->private_options) { - char key[strlen("OPTION_000")+1]; + char key[STRLEN("OPTION_000")+1]; xsprintf(key, "OPTION_%" PRIu8, option->tag); r = serialize_dhcp_option(f, key, option->data, option->length); diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c index bdef67dc4f..8c807e0e23 100644 --- a/src/systemd/src/shared/dns-domain.c +++ b/src/systemd/src/shared/dns-domain.c @@ -693,23 +693,26 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char } int dns_name_between(const char *a, const char *b, const char *c) { - int n; - /* Determine if b is strictly greater than a and strictly smaller than c. We consider the order of names to be circular, so that if a is strictly greater than c, we consider b to be between them if it is either greater than a or smaller than c. This is how the canonical DNS name order used in NSEC records work. */ - n = dns_name_compare_func(a, c); - if (n == 0) - return -EINVAL; - else if (n < 0) - /* a<---b--->c */ + if (dns_name_compare_func(a, c) < 0) + /* + a and c are properly ordered: + a<---b--->c + */ return dns_name_compare_func(a, b) < 0 && dns_name_compare_func(b, c) < 0; else - /* <--b--c a--b--> */ + /* + a and c are equal or 'reversed': + <--b--c a-----> + or: + <-----c a--b--> + */ return dns_name_compare_func(b, c) < 0 || dns_name_compare_func(a, b) < 0; }