Commit 8f4e6175 authored by Thomas Haller's avatar Thomas Haller
Browse files

systemd: update code from upstream

This is a direct dump from systemd git on 2015-08-12, git commit
3f1818cf70ac34c.

======

SYSTEMD_DIR=../systemd
COMMIT=3f1818cf70ac34cf93f1f033b4f1bbb7a89b3dff

(
  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/async.h"
nm_copy_sd "src/basic/fileio.c"
nm_copy_sd "src/basic/fileio.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/list.h"
nm_copy_sd "src/basic/log.h"
nm_copy_sd "src/basic/macro.h"
nm_copy_sd "src/basic/path-util.c"
nm_copy_sd "src/basic/path-util.h"
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/siphash24.c"
nm_copy_sd "src/basic/siphash24.h"
nm_copy_sd "src/basic/socket-util.h"
nm_copy_sd "src/basic/sparse-endian.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/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/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/ipv4ll-internal.h"
nm_copy_sd "src/libsystemd-network/ipv4ll-internal.h"
nm_copy_sd "src/libsystemd-network/ipv4ll-network.c"
nm_copy_sd "src/libsystemd-network/ipv4ll-packet.c"
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/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-id128.h"
nm_copy_sd "src/systemd/sd-ipv4ll.h"
parent 00051ad7
......@@ -27,60 +27,19 @@
#include "ctype.h"
#include "fileio.h"
int write_string_stream(FILE *f, const char *line) {
int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
assert(f);
assert(line);
errno = 0;
fputs(line, f);
if (!endswith(line, "\n"))
if (enforce_newline && !endswith(line, "\n"))
fputc('\n', f);
fflush(f);
if (ferror(f))
return errno ? -errno : -EIO;
return 0;
return fflush_and_check(f);
}
int write_string_file(const char *fn, const char *line) {
_cleanup_fclose_ FILE *f = NULL;
assert(fn);
assert(line);
f = fopen(fn, "we");
if (!f)
return -errno;
return write_string_stream(f, line);
}
int write_string_file_no_create(const char *fn, const char *line) {
_cleanup_fclose_ FILE *f = NULL;
int fd;
assert(fn);
assert(line);
/* We manually build our own version of fopen(..., "we") that
* works without O_CREAT */
fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return -errno;
f = fdopen(fd, "we");
if (!f) {
safe_close(fd);
return -errno;
}
return write_string_stream(f, line);
}
int write_string_file_atomic(const char *fn, const char *line) {
static int write_string_file_atomic(const char *fn, const char *line, bool enforce_newline) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *p = NULL;
int r;
......@@ -94,7 +53,7 @@ int write_string_file_atomic(const char *fn, const char *line) {
fchmod_umask(fileno(f), 0644);
r = write_string_stream(f, line);
r = write_string_stream(f, line, enforce_newline);
if (r >= 0) {
if (rename(p, fn) < 0)
r = -errno;
......@@ -106,6 +65,41 @@ int write_string_file_atomic(const char *fn, const char *line) {
return r;
}
int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
_cleanup_fclose_ FILE *f = NULL;
assert(fn);
assert(line);
if (flags & WRITE_STRING_FILE_ATOMIC) {
assert(flags & WRITE_STRING_FILE_CREATE);
return write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
}
if (flags & WRITE_STRING_FILE_CREATE) {
f = fopen(fn, "we");
if (!f)
return -errno;
} else {
int fd;
/* We manually build our own version of fopen(..., "we") that
* works without O_CREAT */
fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return -errno;
f = fdopen(fd, "we");
if (!f) {
safe_close(fd);
return -errno;
}
}
return write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
}
int read_one_line_file(const char *fn, char **line) {
_cleanup_fclose_ FILE *f = NULL;
char t[LINE_MAX], *c;
......@@ -134,6 +128,17 @@ int read_one_line_file(const char *fn, char **line) {
return 0;
}
int verify_one_line_file(const char *fn, const char *line) {
_cleanup_free_ char *value = NULL;
int r;
r = read_one_line_file(fn, &value);
if (r < 0)
return r;
return streq(value, line);
}
int read_full_stream(FILE *f, char **contents, size_t *size) {
size_t n, l;
_cleanup_free_ char *buf = NULL;
......@@ -775,7 +780,7 @@ int executable_is_script(const char *path, char **interpreter) {
*/
int get_status_field(const char *filename, const char *pattern, char **field) {
_cleanup_free_ char *status = NULL;
char *t;
char *t, *f;
size_t len;
int r;
......@@ -809,9 +814,10 @@ int get_status_field(const char *filename, const char *pattern, char **field) {
len = strcspn(t, WHITESPACE);
*field = strndup(t, len);
if (!*field)
f = strndup(t, len);
if (!f)
return -ENOMEM;
*field = f;
return 0;
}
......@@ -25,15 +25,21 @@
#include "macro.h"
int write_string_stream(FILE *f, const char *line);
int write_string_file(const char *fn, const char *line);
int write_string_file_no_create(const char *fn, const char *line);
int write_string_file_atomic(const char *fn, const char *line);
typedef enum {
WRITE_STRING_FILE_CREATE = 1,
WRITE_STRING_FILE_ATOMIC = 2,
WRITE_STRING_FILE_AVOID_NEWLINE = 4,
} 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 read_one_line_file(const char *fn, char **line);
int read_full_file(const char *fn, char **contents, size_t *size);
int read_full_stream(FILE *f, char **contents, size_t *size);
int verify_one_line_file(const char *fn, const char *line);
int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
......
......@@ -61,14 +61,22 @@ static bool hostname_valid_char(char c) {
c == '.';
}
bool hostname_is_valid(const char *s) {
/**
* Check if s looks like a valid host name or fqdn. This does not do
* full DNS validation, but only checks if the name is composed of
* allowed characters and the length is not above the maximum allowed
* by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
* relax is true and at least two components are present in the name.
*/
bool hostname_is_valid(const char *s, bool relax) {
const char *p;
bool dot;
unsigned dots = 0;
if (isempty(s))
return false;
/* Doesn't accept empty hostnames, hostnames with trailing or
/* Doesn't accept empty hostnames, hostnames with
* leading dots, and hostnames with multiple dots in a
* sequence. Also ensures that the length stays below
* HOST_NAME_MAX. */
......@@ -79,6 +87,7 @@ bool hostname_is_valid(const char *s) {
return false;
dot = true;
dots ++;
} else {
if (!hostname_valid_char(*p))
return false;
......@@ -87,7 +96,7 @@ bool hostname_is_valid(const char *s) {
}
}
if (dot)
if (dot && (dots < 2 || !relax))
return false;
if (p-s > HOST_NAME_MAX)
......@@ -96,7 +105,7 @@ bool hostname_is_valid(const char *s) {
return true;
}
char* hostname_cleanup(char *s, bool lowercase) {
char* hostname_cleanup(char *s) {
char *p, *d;
bool dot;
......@@ -110,7 +119,7 @@ char* hostname_cleanup(char *s, bool lowercase) {
*(d++) = '.';
dot = true;
} else if (hostname_valid_char(*p)) {
*(d++) = lowercase ? tolower(*p) : *p;
*(d++) = *p;
dot = false;
}
......@@ -132,14 +141,14 @@ bool is_localhost(const char *hostname) {
/* This tries to identify local host and domain names
* described in RFC6761 plus the redhatism of .localdomain */
return streq(hostname, "localhost") ||
streq(hostname, "localhost.") ||
streq(hostname, "localdomain.") ||
streq(hostname, "localdomain") ||
endswith(hostname, ".localhost") ||
endswith(hostname, ".localhost.") ||
endswith(hostname, ".localdomain") ||
endswith(hostname, ".localdomain.");
return strcaseeq(hostname, "localhost") ||
strcaseeq(hostname, "localhost.") ||
strcaseeq(hostname, "localdomain.") ||
strcaseeq(hostname, "localdomain") ||
endswith_no_case(hostname, ".localhost") ||
endswith_no_case(hostname, ".localhost.") ||
endswith_no_case(hostname, ".localdomain") ||
endswith_no_case(hostname, ".localdomain.");
}
int sethostname_idempotent(const char *s) {
......@@ -176,7 +185,7 @@ int read_hostname_config(const char *path, char **hostname) {
truncate_nl(l);
if (l[0] != '\0' && l[0] != '#') {
/* found line with value */
name = hostname_cleanup(l, false);
name = hostname_cleanup(l);
name = strdup(name);
if (!name)
return -ENOMEM;
......
......@@ -29,8 +29,8 @@ bool hostname_is_set(void);
char* gethostname_malloc(void);
bool hostname_is_valid(const char *s) _pure_;
char* hostname_cleanup(char *s, bool lowercase);
bool hostname_is_valid(const char *s, bool relax) _pure_;
char* hostname_cleanup(char *s);
bool is_localhost(const char *hostname);
......
......@@ -123,6 +123,32 @@
} \
} while(false)
/* Insert an item before another one (a = where, b = what) */
#define LIST_INSERT_BEFORE(name,head,a,b) \
do { \
typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
assert(_b); \
if (!_a) { \
if (!*_head) { \
_b->name##_next = NULL; \
_b->name##_prev = NULL; \
*_head = _b; \
} else { \
typeof(*(head)) *_tail = (head); \
while (_tail->name##_next) \
_tail = _tail->name##_next; \
_b->name##_next = NULL; \
_b->name##_prev = _tail; \
_tail->name##_next = _b; \
} \
} else { \
if ((_b->name##_prev = _a->name##_prev)) \
_b->name##_prev->name##_next = _b; \
_b->name##_next = _a; \
_a->name##_prev = _b; \
} \
} while(false)
#define LIST_JUST_US(name,item) \
(!(item)->name##_prev && !(item)->name##_next) \
......
......@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <inttypes.h>
#include <stdbool.h>
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
#define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
......@@ -406,12 +407,12 @@ do { \
#define IN_SET(x, y, ...) \
({ \
const typeof(y) _y = (y); \
const typeof(_y) _x = (x); \
static const typeof(y) _array[] = { (y), __VA_ARGS__ }; \
const typeof(y) _x = (x); \
unsigned _i; \
bool _found = false; \
for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \
if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \
for (_i = 0; _i < ELEMENTSOF(_array); _i++) \
if (_array[_i] == _x) { \
_found = true; \
break; \
} \
......@@ -461,6 +462,18 @@ do { \
#define GID_INVALID ((gid_t) -1)
#define MODE_INVALID ((mode_t) -1)
static inline bool UID_IS_INVALID(uid_t uid) {
/* We consider both the old 16bit -1 user and the newer 32bit
* -1 user invalid, since they are or used to be incompatible
* with syscalls such as setresuid() or chown(). */
return uid == (uid_t) ((uint32_t) -1) || uid == (uid_t) ((uint16_t) -1);
}
static inline bool GID_IS_INVALID(gid_t gid) {
return gid == (gid_t) ((uint32_t) -1) || gid == (gid_t) ((uint16_t) -1);
}
#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \
static inline void func##p(type *p) { \
if (*p) \
......
......@@ -528,7 +528,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) {
*
* If that didn't work we will try to read the mount id from
* /proc/self/fdinfo/<fd>. This is almost as good as
* name_to_handle_at(), however, does not return the the
* name_to_handle_at(), however, does not return the
* opaque file handle. The opaque file handle is pretty useful
* to detect the root directory, which we should always
* consider a mount point. Hence we use this only as
......@@ -656,9 +656,11 @@ int path_is_mount_point(const char *t, int flags) {
canonical = canonicalize_file_name(t);
if (!canonical)
return -errno;
t = canonical;
}
r = path_get_parent(canonical ?: t, &parent);
r = path_get_parent(t, &parent);
if (r < 0)
return r;
......@@ -666,7 +668,7 @@ int path_is_mount_point(const char *t, int flags) {
if (fd < 0)
return -errno;
return fd_is_mount_point(fd, basename(canonical ?: t), flags);
return fd_is_mount_point(fd, basename(t), flags);
}
int path_is_read_only_fs(const char *path) {
......
This diff is collapsed.
......@@ -71,6 +71,7 @@ size_t page_size(void) _pure_;
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
bool streq_ptr(const char *a, const char *b) _pure_;
int strcmp_ptr(const char *a, const char *b) _pure_;
#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
......@@ -84,6 +85,11 @@ bool streq_ptr(const char *a, const char *b) _pure_;
#define malloc0(n) (calloc((n), 1))
static inline void *mfree(void *memory) {
free(memory);
return NULL;
}
static inline const char* yes_no(bool b) {
return b ? "yes" : "no";
}
......@@ -240,6 +246,10 @@ char octchar(int x) _const_;
int unoctchar(char c) _const_;
char decchar(int x) _const_;
int undecchar(char c) _const_;
char base32hexchar(int x) _const_;
int unbase32hexchar(char c) _const_;
char base64char(int x) _const_;
int unbase64char(char c) _const_;
char *cescape(const char *s);
size_t cescape_char(char c, char *buf);
......@@ -614,7 +624,13 @@ static inline void *mempset(void *s, int c, size_t n) {
}
char *hexmem(const void *p, size_t l);
void *unhexmem(const char *p, size_t l);
int unhexmem(const char *p, size_t l, void **mem, size_t *len);
char *base32hexmem(const void *p, size_t l, bool padding);
int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len);
char *base64mem(const void *p, size_t l);
int unbase64mem(const char *p, size_t l, void **mem, size_t *len);
char *strextend(char **x, ...) _sentinel_;
char *strrep(const char *s, unsigned n);
......@@ -848,6 +864,11 @@ int unquote_first_word(const char **p, char **ret, UnquoteFlags flags);
int unquote_first_word_and_warn(const char **p, char **ret, UnquoteFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
int unquote_many_words(const char **p, UnquoteFlags flags, ...) _sentinel_;
static inline void free_and_replace(char **s, char *v) {
free(*s);
*s = v;
}
int free_and_strdup(char **p, const char *s);
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
......@@ -903,3 +924,6 @@ int parse_mode(const char *s, mode_t *ret);
int mount_move_root(const char *path);
int reset_uid_gid(void);
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
int fgetxattr_malloc(int fd, const char *name, char **value);
......@@ -27,6 +27,7 @@
#include "refcnt.h"
#include "util.h"
#include "list.h"
#include "dhcp-protocol.h"
......@@ -38,6 +39,14 @@ struct sd_dhcp_route {
unsigned char dst_prefixlen;
};
struct sd_dhcp_raw_option {
LIST_FIELDS(struct sd_dhcp_raw_option, options);
uint8_t tag;
uint8_t length;
void *data;
};
struct sd_dhcp_lease {
RefCount n_ref;
......@@ -72,11 +81,16 @@ struct sd_dhcp_lease {
char *root_path;
uint8_t *client_id;
size_t client_id_len;
uint8_t *vendor_specific;
size_t vendor_specific_len;
LIST_HEAD(struct sd_dhcp_raw_option, private_options);
};
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
void *user_data);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag,
const uint8_t *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
......
......@@ -125,6 +125,7 @@ enum {
DHCP_OPTION_BROADCAST = 28,
DHCP_OPTION_STATIC_ROUTE = 33,
DHCP_OPTION_NTP_SERVER = 42,
DHCP_OPTION_VENDOR_SPECIFIC = 43,
DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
DHCP_OPTION_OVERLOAD = 52,
......@@ -137,5 +138,7 @@ enum {
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
DHCP_OPTION_PRIVATE_BASE = 224,
DHCP_OPTION_PRIVATE_LAST = 254,
DHCP_OPTION_END = 255,
};
......@@ -509,3 +509,30 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
return 0;
}
int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size) {
_cleanup_free_ char *hex_buf = NULL;
assert(f);
assert(key);
assert(data);
hex_buf = hexmem(data, size);
if (hex_buf == NULL)
return -ENOMEM;
fprintf(f, "%s=%s\n", key, hex_buf);
return 0;
}
int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string) {
assert(data);
assert(data_len);
assert(string);
if (strlen(string) % 2)
return -EINVAL;
return unhexmem(string, strlen(string), (void **)data, data_len);
}
......@@ -74,3 +74,6 @@ struct sd_dhcp_route;
void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
int serialize_dhcp_option(FILE *f, const char *key, const uint8_t *data, size_t size);
int deserialize_dhcp_option(uint8_t **data, size_t *data_len, const char *string);
......@@ -179,6 +179,21 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes
return 0;
}
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const uint8_t **data,
size_t *data_len) {
assert_return(lease, -EINVAL);
assert_return(data, -EINVAL);
assert_return(data_len, -EINVAL);
if (!lease->vendor_specific)
return -ENOENT;
*data = lease->vendor_specific;
*data_len = lease->vendor_specific_len;
return 0;
}
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
if (lease)
assert_se(REFCNT_INC(lease->n_ref) >= 2);
......@@ -188,12 +203,21 @@ sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
if (lease && REFCNT_DEC(lease->n_ref) == 0) {
while (lease->private_options) {
struct sd_dhcp_raw_option *option = lease->private_options;
LIST_REMOVE(options, lease->private_options, option);
free(option->data);
free(option);
}
free(lease->hostname);
free(lease->domainname);
free(lease->dns);
free(lease->ntp);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
free(lease);
}
......@@ -435,7 +459,8 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
break;
case DHCP_OPTION_ROUTER:
lease_parse_be32(option, len, &lease->router);