diff options
author | Dan Winship <danw@redhat.com> | 2014-11-19 12:02:36 -0500 |
---|---|---|
committer | Dan Winship <danw@redhat.com> | 2014-11-19 12:02:36 -0500 |
commit | 44eb50d12f996904edb9c7110d8642d426382f9c (patch) | |
tree | 99eb83c85d0949fba794486e8670b60855044862 | |
parent | af525e8a18b3bd822751c339916cc3c7396d9832 (diff) | |
parent | e30b07149f889ef8480b6f14030a1b6bda521e43 (diff) | |
download | NetworkManager-44eb50d12f996904edb9c7110d8642d426382f9c.tar.gz |
dhcp: update system-dhcp code from upstream
22 files changed, 455 insertions, 355 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a317705110..808e59eb33 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,6 +99,7 @@ libsystemd_dhcp_la_SOURCES = \ dhcp-manager/systemd-dhcp/src/shared/fileio.c \ dhcp-manager/systemd-dhcp/src/shared/strv.h \ dhcp-manager/systemd-dhcp/src/shared/strv.c \ + dhcp-manager/systemd-dhcp/src/shared/unaligned.h \ dhcp-manager/systemd-dhcp/src/shared/utf8.h \ dhcp-manager/systemd-dhcp/src/shared/utf8.c \ dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h \ diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c index ecb4282dc1..9cdd9e206b 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -389,7 +389,7 @@ nm_dhcp_systemd_get_lease_ip_configs (const char *iface, return NULL; path = get_leasefile_path (iface, uuid, FALSE); - r = sd_dhcp_lease_load (path, &lease); + r = sd_dhcp_lease_load (&lease, path); if (r == 0) { ip4_config = lease_to_ip4_config (lease, NULL, 0, FALSE, NULL); if (ip4_config) @@ -457,7 +457,7 @@ bound4_handle (NMDhcpSystemd *self) add_requests_to_options (options, dhcp4_requests); sd_dhcp_lease_save (lease, priv->lease_file); - client_id = sd_dhcp_client_get_client_id(priv->client4, &type, &client_id_len); + sd_dhcp_client_get_client_id(priv->client4, &type, &client_id, &client_id_len); if (client_id) _save_client_id (self, type, client_id, client_id_len); @@ -576,7 +576,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last goto error; } - sd_dhcp_lease_load (priv->lease_file, &lease); + sd_dhcp_lease_load (&lease, priv->lease_file); if (last_ip4_address) inet_pton (AF_INET, last_ip4_address, &last_addr); diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c index cc5ad2abd2..a6d817278e 100644 --- a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c +++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c @@ -68,12 +68,12 @@ sd_event_source_unref (sd_event_source *s) } int -sd_event_source_set_name(sd_event_source *s, const char *name) +sd_event_source_set_description(sd_event_source *s, const char *description) { if (!s) return -EINVAL; - g_source_set_name_by_id (s->id, name); + g_source_set_name_by_id (s->id, description); return 0; } diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h index 375ded31a5..9e184ac4b5 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h @@ -35,7 +35,7 @@ struct sd_dhcp_route { struct in_addr dst_addr; struct in_addr gw_addr; - uint8_t dst_prefixlen; + unsigned char dst_prefixlen; }; struct sd_dhcp_lease { diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c index 17398a5a49..3d6e24623a 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c @@ -28,31 +28,37 @@ #include <string.h> #include "sparse-endian.h" +#include "unaligned.h" #include "util.h" #include "dhcp6-internal.h" #include "dhcp6-protocol.h" -#define DHCP6_OPTION_HDR_LEN 4 #define DHCP6_OPTION_IA_NA_LEN 12 #define DHCP6_OPTION_IA_TA_LEN 4 +typedef struct DHCP6Option { + be16_t code; + be16_t len; + uint8_t data[]; +} _packed_ DHCP6Option; + static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) { + DHCP6Option *option = (DHCP6Option*) *buf; + assert_return(buf, -EINVAL); assert_return(*buf, -EINVAL); assert_return(buflen, -EINVAL); - if (optlen > 0xffff || *buflen < optlen + DHCP6_OPTION_HDR_LEN) + if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option)) return -ENOBUFS; - (*buf)[0] = optcode >> 8; - (*buf)[1] = optcode & 0xff; - (*buf)[2] = optlen >> 8; - (*buf)[3] = optlen & 0xff; + option->code = htobe16(optcode); + option->len = htobe16(optlen); - *buf += DHCP6_OPTION_HDR_LEN; - *buflen -= DHCP6_OPTION_HDR_LEN; + *buf += sizeof(DHCP6Option); + *buflen -= sizeof(DHCP6Option); return 0; } @@ -104,8 +110,8 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { ia_hdr = *buf; ia_buflen = *buflen; - *buf += DHCP6_OPTION_HDR_LEN; - *buflen -= DHCP6_OPTION_HDR_LEN; + *buf += sizeof(DHCP6Option); + *buflen -= sizeof(DHCP6Option); memcpy(*buf, &ia->id, len); @@ -123,7 +129,7 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { *buf += sizeof(addr->iaaddr); *buflen -= sizeof(addr->iaaddr); - ia_addrlen += DHCP6_OPTION_HDR_LEN + sizeof(addr->iaaddr); + ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr); } r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen); @@ -134,23 +140,23 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) { } -static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *opt, - size_t *optlen) { +static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) { + DHCP6Option *option = (DHCP6Option*) *buf; uint16_t len; assert_return(buf, -EINVAL); - assert_return(opt, -EINVAL); + assert_return(optcode, -EINVAL); assert_return(optlen, -EINVAL); - if (*buflen < 4) + if (*buflen < sizeof(DHCP6Option)) return -ENOMSG; - len = (*buf)[2] << 8 | (*buf)[3]; + len = be16toh(option->len); if (len > *buflen) return -ENOMSG; - *opt = (*buf)[0] << 8 | (*buf)[1]; + *optcode = be16toh(option->code); *optlen = len; *buf += 4; @@ -194,7 +200,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, switch (iatype) { case DHCP6_OPTION_IA_NA: - if (*buflen < DHCP6_OPTION_IA_NA_LEN + DHCP6_OPTION_HDR_LEN + + if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) + sizeof(addr->iaaddr)) { r = -ENOBUFS; goto error; @@ -216,7 +222,7 @@ int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, break; case DHCP6_OPTION_IA_TA: - if (*buflen < DHCP6_OPTION_IA_TA_LEN + DHCP6_OPTION_HDR_LEN + + if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) + sizeof(addr->iaaddr)) { r = -ENOBUFS; goto error; diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c index 7fc49b4ce8..41a380eb5a 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c @@ -109,16 +109,16 @@ bool net_match_config(const struct ether_addr *match_mac, const char *dev_type, const char *dev_name) { - if (match_host && !condition_test_host(match_host)) + if (match_host && !condition_test(match_host)) return 0; - if (match_virt && !condition_test_virtualization(match_virt)) + if (match_virt && !condition_test(match_virt)) return 0; - if (match_kernel && !condition_test_kernel_command_line(match_kernel)) + if (match_kernel && !condition_test(match_kernel)) return 0; - if (match_arch && !condition_test_architecture(match_arch)) + if (match_arch && !condition_test(match_arch)) return 0; if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h index f4ff1dd4e8..f87c863d91 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h @@ -29,7 +29,7 @@ #if 0 /* NM_IGNORED */ #include "udev.h" -#include "condition-util.h" +#include "condition.h" bool net_match_config(const struct ether_addr *match_mac, const char *match_path, diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c index 30c5c940cc..3e4cd8d9e7 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c @@ -42,7 +42,7 @@ #include "dhcp-lease-internal.h" #include "sd-dhcp-client.h" -#define MAX_CLIENT_ID_LEN 32 +#define MAX_CLIENT_ID_LEN 64 /* Arbitrary limit */ #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN struct sd_dhcp_client { @@ -231,20 +231,25 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, return 0; } -const uint8_t *sd_dhcp_client_get_client_id(sd_dhcp_client *client, - uint8_t *type, - size_t *len) { +int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type, + const uint8_t **data, size_t *data_len) { - assert_return(client, NULL); - assert_return(type, NULL); - assert_return(len, NULL); + assert_return(client, -EINVAL); + assert_return(type, -EINVAL); + assert_return(data, -EINVAL); + assert_return(data_len, -EINVAL); - if (!client->client_id_len) - return NULL; + *type = 0; + *data = NULL; + *data_len = 0; + if (client->client_id_len) { + *type = client->client_id.raw.type; + *data = client->client_id.raw.data; + *data_len = client->client_id_len - + sizeof (client->client_id.raw.type); + } - *type = client->client_id.raw.type; - *len = client->client_id_len - 1; /* -1 for sizeof(type) */ - return (const uint8_t *) &client->client_id.raw.data; + return 0; } int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, @@ -269,7 +274,7 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, break; } - if (client->client_id_len == data_len + 1 && + if (client->client_id_len == data_len + sizeof (client->client_id.raw.type) && client->client_id.raw.type == type && memcmp(&client->client_id.raw.data, data, data_len) == 0) return 0; @@ -283,7 +288,7 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, client->client_id.raw.type = type; memcpy(&client->client_id.raw.data, data, data_len); - client->client_id_len = data_len + 1; /* +1 for sizeof(type) */ + client->client_id_len = data_len + sizeof (client->client_id.raw.type); if (need_restart && client->state != DHCP_STATE_STOPPED) sd_dhcp_client_start(client); @@ -814,8 +819,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, if (r < 0) goto error; - r = sd_event_source_set_name(client->timeout_resend, - "dhcp4-resend-timer"); + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); if (r < 0) goto error; @@ -892,8 +896,7 @@ static int client_initialize_io_events(sd_dhcp_client *client, if (r < 0) goto error; - r = sd_event_source_set_name(client->receive_message, - "dhcp4-receive-message"); + r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message"); if (r < 0) goto error; @@ -923,8 +926,7 @@ static int client_initialize_time_events(sd_dhcp_client *client) { r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); - r = sd_event_source_set_name(client->timeout_resend, - "dhcp4-resend-timer"); + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); if (r < 0) goto error; @@ -1035,7 +1037,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, if (client->client_id_len) { r = dhcp_lease_set_client_id(lease, - (uint8_t *) &client->client_id, + (uint8_t *) &client->client_id.raw, client->client_id_len); if (r < 0) return r; @@ -1102,7 +1104,7 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, if (client->client_id_len) { r = dhcp_lease_set_client_id(lease, - (uint8_t *) &client->client_id, + (uint8_t *) &client->client_id.raw, client->client_id_len); if (r < 0) return r; @@ -1254,8 +1256,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { if (r < 0) return r; - r = sd_event_source_set_name(client->timeout_expire, - "dhcp4-lifetime"); + r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime"); if (r < 0) return r; @@ -1282,8 +1283,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { if (r < 0) return r; - r = sd_event_source_set_name(client->timeout_t2, - "dhcp4-t2-timeout"); + r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout"); if (r < 0) return r; @@ -1309,8 +1309,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { if (r < 0) return r; - r = sd_event_source_set_name(client->timeout_t1, - "dhcp4-t1-timer"); + r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer"); if (r < 0) return r; @@ -1355,8 +1354,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, if (r < 0) goto error; - r = sd_event_source_set_name(client->timeout_resend, - "dhcp4-resend-timer"); + r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); if (r < 0) goto error; } else if (r == -ENOMSG) diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c index d2b83a2500..2d13d503e1 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c @@ -36,6 +36,7 @@ #include "mkdir.h" #endif #include "fileio.h" +#include "unaligned.h" #include "in-addr-util.h" #include "dhcp-protocol.h" @@ -212,14 +213,11 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { } static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { - be32_t val; - assert(option); assert(ret); if (len == 4) { - memcpy(&val, option, 4); - *ret = be32toh(val); + *ret = unaligned_read_be32((be32_t*) option); if (*ret < min) *ret = min; @@ -231,14 +229,11 @@ static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) { } static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) { - be16_t val; - assert(option); assert(ret); if (len == 2) { - memcpy(&val, option, 2); - *ret = be16toh(val); + *ret = unaligned_read_be16((be16_t*) option); if (*ret < min) *ret = min; @@ -322,23 +317,6 @@ static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2); } -static int class_prefixlen(uint8_t msb_octet, uint8_t *ret) { - if (msb_octet < 128) - /* Class A */ - *ret = 8; - else if (msb_octet < 192) - /* Class B */ - *ret = 16; - else if (msb_octet < 224) - /* Class C */ - *ret = 24; - else - /* Class D or E -- no subnet mask */ - return -ERANGE; - - return 0; -} - static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) { @@ -360,8 +338,10 @@ static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_ while (len >= 8) { struct sd_dhcp_route *route = *routes + *routes_size; + int r; - if (class_prefixlen(*option, &route->dst_prefixlen) < 0) { + r = in_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen); + if (r < 0) { log_error("Failed to determine destination prefix length from class based IP, ignoring"); continue; } @@ -716,7 +696,7 @@ finish: return r; } -int sd_dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret) { +int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL; _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL, *server_address = NULL, *next_server = NULL, diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c index 935bc947ed..6c5a6ab536 100644 --- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c @@ -597,8 +597,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, if (r < 0) goto error; - r = sd_event_source_set_name(client->timeout_resend, - "dhcp6-resend-timer"); + r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer"); if (r < 0) goto error; @@ -621,8 +620,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, if (r < 0) goto error; - r = sd_event_source_set_name(client->timeout_resend_expire, - "dhcp6-resend-expire-timer"); + r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer"); if (r < 0) goto error; } @@ -994,8 +992,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) if (r < 0) return r; - r = sd_event_source_set_name(client->receive_message, - "dhcp6-receive-message"); + r = sd_event_source_set_description(client->receive_message, "dhcp6-receive-message"); if (r < 0) return r; @@ -1043,8 +1040,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) if (r < 0) return r; - r = sd_event_source_set_name(client->lease->ia.timeout_t1, - "dhcp6-t1-timeout"); + r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout"); if (r < 0) return r; @@ -1068,8 +1064,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) if (r < 0) return r; - r = sd_event_source_set_name(client->lease->ia.timeout_t2, - "dhcp6-t2-timeout"); + r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout"); if (r < 0) return r; @@ -1092,8 +1087,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) if (r < 0) return r; - r = sd_event_source_set_name(client->timeout_resend, - "dhcp6-resend-timeout"); + r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout"); if (r < 0) return r; diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c index 75437d08fe..0757d5d977 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c +++ b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.c @@ -22,12 +22,12 @@ #include "config.h" #include <unistd.h> -#include <sys/sendfile.h> -#include "fileio.h" + #include "util.h" #include "strv.h" #include "utf8.h" #include "ctype.h" +#include "fileio.h" int write_string_stream(FILE *f, const char *line) { assert(f); @@ -68,7 +68,7 @@ int write_string_file_no_create(const char *fn, const char *line) { assert(line); /* We manually build our own version of fopen(..., "we") that - * without O_CREAT */ + * works without O_CREAT */ fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) return -errno; @@ -96,20 +96,10 @@ int write_string_file_atomic(const char *fn, const char *line) { fchmod_umask(fileno(f), 0644); - errno = 0; - fputs(line, f); - if (!endswith(line, "\n")) - fputc('\n', f); - - fflush(f); - - if (ferror(f)) - r = errno ? -errno : -EIO; - else { + r = write_string_stream(f, line); + if (r >= 0) { if (rename(p, fn) < 0) r = -errno; - else - r = 0; } if (r < 0) @@ -146,77 +136,6 @@ int read_one_line_file(const char *fn, char **line) { return 0; } -ssize_t sendfile_full(int out_fd, const char *fn) { - _cleanup_fclose_ FILE *f = NULL; - struct stat st; - int r; - ssize_t s; - - size_t n, l; - _cleanup_free_ char *buf = NULL; - - assert(out_fd > 0); - assert(fn); - - f = fopen(fn, "re"); - if (!f) - return -errno; - - r = fstat(fileno(f), &st); - if (r < 0) - return -errno; - - s = sendfile(out_fd, fileno(f), NULL, st.st_size); - if (s < 0) - if (errno == EINVAL || errno == ENOSYS) { - /* continue below */ - } else - return -errno; - else - return s; - - /* sendfile() failed, fall back to read/write */ - - /* Safety check */ - if (st.st_size > 4*1024*1024) - return -E2BIG; - - n = st.st_size > 0 ? st.st_size : LINE_MAX; - l = 0; - - while (true) { - char *t; - size_t k; - - t = realloc(buf, n); - if (!t) - return -ENOMEM; - - buf = t; - k = fread(buf + l, 1, n - l, f); - - if (k <= 0) { - if (ferror(f)) - return -errno; - - break; - } - - l += k; - n *= 2; - - /* Safety check */ - if (n > 4*1024*1024) - return -E2BIG; - } - - r = write(out_fd, buf, l); - if (r < 0) - return -errno; - - return (ssize_t) l; -} - int read_full_stream(FILE *f, char **contents, size_t *size) { size_t n, l; _cleanup_free_ char *buf = NULL; diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h index c256915799..5ae51c1e28 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h +++ b/src/dhcp-manager/systemd-dhcp/src/shared/fileio.h @@ -33,7 +33,6 @@ int write_string_file_atomic(const char *fn, const char *line); 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); -ssize_t sendfile_full(int out_fd, const char *fn); 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); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c index 49882d06b8..27edeb8d93 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c +++ b/src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c @@ -252,21 +252,20 @@ unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr) { } int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) { - uint32_t address; + uint8_t msb_octet = *(uint8_t*) addr; + + /* addr may not be aligned, so make sure we only access it byte-wise */ assert(addr); - assert(addr->s_addr != INADDR_ANY); assert(prefixlen); - address = be32toh(addr->s_addr); - - if ((address >> 31) == 0x0) + if (msb_octet < 128) /* class A, leading bits: 0 */ *prefixlen = 8; - else if ((address >> 30) == 0x2) + else if (msb_octet < 192) /* class B, leading bits 10 */ *prefixlen = 16; - else if ((address >> 29) == 0x6) + else if (msb_octet < 224) /* class C, leading bits 110 */ *prefixlen = 24; else diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/strv.c b/src/dhcp-manager/systemd-dhcp/src/shared/strv.c index dbb4cbb7a7..be2bd51106 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/strv.c +++ b/src/dhcp-manager/systemd-dhcp/src/shared/strv.c @@ -252,40 +252,6 @@ char **strv_split(const char *s, const char *separator) { return r; } -int strv_split_quoted(char ***t, const char *s) { - const char *word, *state; - size_t l; - unsigned n, i; - char **r; - - assert(s); - - n = 0; - FOREACH_WORD_QUOTED(word, l, s, state) - n++; - if (!isempty(state)) - /* bad syntax */ - return -EINVAL; - - r = new(char*, n+1); - if (!r) - return -ENOMEM; - - i = 0; - FOREACH_WORD_QUOTED(word, l, s, state) { - r[i] = cunescape_length(word, l); - if (!r[i]) { - strv_free(r); - return -ENOMEM; - } - i++; - } - - r[i] = NULL; - *t = r; - return 0; -} - char **strv_split_newlines(const char *s) { char **l; unsigned n; @@ -311,6 +277,43 @@ char **strv_split_newlines(const char *s) { return l; } +#if 0 /* NM_IGNORED */ +int strv_split_quoted(char ***t, const char *s, bool relax) { + size_t n = 0, allocated = 0; + _cleanup_strv_free_ char **l = NULL; + int r; + + assert(t); + assert(s); + + for (;;) { + _cleanup_free_ char *word = NULL; + + r = unquote_first_word(&s, &word, relax); + if (r < 0) + return r; + if (r == 0) + break; + + if (!GREEDY_REALLOC(l, allocated, n + 2)) + return -ENOMEM; + + l[n++] = word; + word = NULL; + + l[n] = NULL; + } + + if (!l) + l = new0(char*, 1); + + *t = l; + l = NULL; + + return 0; +} +#endif + char *strv_join(char **l, const char *separator) { char *r, *e; char **s; diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/strv.h b/src/dhcp-manager/systemd-dhcp/src/shared/strv.h index 9c9633c515..47618bd26c 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/strv.h +++ b/src/dhcp-manager/systemd-dhcp/src/shared/strv.h @@ -63,9 +63,10 @@ static inline bool strv_isempty(char * const *l) { } char **strv_split(const char *s, const char *separator); -int strv_split_quoted(char ***t, const char *s); char **strv_split_newlines(const char *s); +int strv_split_quoted(char ***t, const char *s, bool relax); + char *strv_join(char **l, const char *separator); char *strv_join_quoted(char **l); diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h b/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h new file mode 100644 index 0000000000..d6181dd9a9 --- /dev/null +++ b/src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen + + 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 <stdint.h> + +static inline uint16_t unaligned_read_be16(const void *_u) { + const uint8_t *u = _u; + + return (((uint16_t) u[0]) << 8) | + ((uint16_t) u[1]); +} + +static inline uint32_t unaligned_read_be32(const void *_u) { + const uint8_t *u = _u; + + return (((uint32_t) unaligned_read_be16(u)) << 16) | + ((uint32_t) unaligned_read_be16(u + 2)); +} + +static inline uint64_t unaligned_read_be64(const void *_u) { + const uint8_t *u = _u; + + return (((uint64_t) unaligned_read_be32(u)) << 32) | + ((uint64_t) unaligned_read_be32(u + 4)); +} + +static inline void unaligned_write_be16(void *_u, uint16_t a) { + uint8_t *u = _u; + + u[0] = (uint8_t) (a >> 8); + u[1] = (uint8_t) a; +} + +static inline void unaligned_write_be32(void *_u, uint32_t a) { + uint8_t *u = _u; + + unaligned_write_be16(u, (uint16_t) (a >> 16)); + unaligned_write_be16(u + 2, (uint16_t) a); +} + +static inline void unaligned_write_be64(void *_u, uint64_t a) { + uint8_t *u = _u; + + unaligned_write_be32(u, (uint32_t) (a >> 32)); + unaligned_write_be32(u + 4, (uint32_t) a); +} diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c index 5bfeeac2d3..cfedbfcb99 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c +++ b/src/dhcp-manager/systemd-dhcp/src/shared/utf8.c @@ -154,10 +154,12 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) { int encoded_len, val; encoded_len = utf8_encoded_valid_unichar((const char *) p); - val = utf8_encoded_to_unichar((const char*) p); - if (encoded_len < 0 || - val < 0 || + (size_t) encoded_len > length) + return false; + + val = utf8_encoded_to_unichar((const char*) p); + if (val < 0 || is_unicode_control(val) || (!newline && val == '\n')) return false; diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/util.c b/src/dhcp-manager/systemd-dhcp/src/shared/util.c index c872170b02..05d4eb757a 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/util.c +++ b/src/dhcp-manager/systemd-dhcp/src/shared/util.c @@ -374,6 +374,46 @@ int safe_atou8(const char *s, uint8_t *ret) { return 0; } +int safe_atou16(const char *s, uint16_t *ret) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((unsigned long) (uint16_t) l != l) + return -ERANGE; + + *ret = (uint16_t) l; + return 0; +} + +int safe_atoi16(const char *s, int16_t *ret) { + char *x = NULL; + long l; + + assert(s); + assert(ret); + + errno = 0; + l = strtol(s, &x, 0); + + if (!x || x == s || *x || errno) + return errno > 0 ? -errno : -EINVAL; + + if ((long) (int16_t) l != l) + return -ERANGE; + + *ret = (int16_t) l; + return 0; +} + int safe_atollu(const char *s, long long unsigned *ret_llu) { char *x = NULL; unsigned long long l; @@ -710,7 +750,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * } /* Kernel threads have no argv[] */ - if (r == NULL || r[0] == 0) { + if (isempty(r)) { _cleanup_free_ char *t = NULL; int h; @@ -910,6 +950,28 @@ int readlink_malloc(const char *p, char **ret) { return readlinkat_malloc(AT_FDCWD, p, ret); } +int readlink_value(const char *p, char **ret) { + _cleanup_free_ char *link = NULL; + char *value; + int r; + + r = readlink_malloc(p, &link); + if (r < 0) + return r; + + value = basename(link); + if (!value) + return -ENOENT; + + value = strdup(value); + if (!value) + return -ENOMEM; + + *ret = value; + + return 0; +} + int readlink_and_make_absolute(const char *p, char **r) { _cleanup_free_ char *target = NULL; char *k; @@ -2492,14 +2554,58 @@ char* dirname_malloc(const char *path) { #endif int dev_urandom(void *p, size_t n) { - _cleanup_close_ int fd = -1; +#if 0 /* NM_IGNORED */ + static int have_syscall = -1; + int r, fd; + ssize_t k; + + /* Gathers some randomness from the kernel. This call will + * never block, and will always return some data from the + * kernel, regardless if the random pool is fully initialized + * or not. It thus makes no guarantee for the quality of the + * returned entropy, but is good enough for or usual usecases + * of seeding the hash functions for hashtable */ + + /* Use the getrandom() syscall unless we know we don't have + * it, or when the requested size is too large for it. */ + if (have_syscall != 0 || (size_t) (int) n != n) { + r = getrandom(p, n, GRND_NONBLOCK); + if (r == (int) n) { + have_syscall = true; + return 0; + } + + if (r < 0) { + if (errno == ENOSYS) + /* we lack the syscall, continue with + * reading from /dev/urandom */ + have_syscall = false; + else if (errno == EAGAIN) + /* not enough entropy for now. Let's + * remember to use the syscall the + * next time, again, but also read + * from /dev/urandom for now, which + * doesn't care about the current + * amount of entropy. */ + have_syscall = true; + else + return -errno; + } else + /* too short read? */ + return -EIO; + } +#else /* NM IGNORED */ + int fd; ssize_t k; +#endif 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) @@ -2508,8 +2614,36 @@ int dev_urandom(void *p, size_t n) { return 0; } -void random_bytes(void *p, size_t n) { +void initialize_srand(void) { static bool srand_called = false; + unsigned x; +#ifdef HAVE_SYS_AUXV_H + void *auxv; +#endif + + if (srand_called) + return; + + x = 0; + +#ifdef HAVE_SYS_AUXV_H + /* The kernel provides us with a bit of entropy in auxv, so + * let's try to make use of that to seed the pseudo-random + * generator. It's better than nothing... */ + + auxv = (void*) getauxval(AT_RANDOM); + if (auxv) + x ^= *(unsigned*) auxv; +#endif + + x ^= (unsigned) now(CLOCK_REALTIME); + x ^= (unsigned) gettid(); + + srand(x); + srand_called = true; +} + +void random_bytes(void *p, size_t n) { uint8_t *q; int r; @@ -2520,28 +2654,7 @@ void random_bytes(void *p, size_t n) { /* If some idiot made /dev/urandom unavailable to us, he'll * get a PRNG instead. */ - if (!srand_called) { - unsigned x = 0; - -#ifdef HAVE_SYS_AUXV_H - /* The kernel provides us with a bit of entropy in - * auxv, so let's try to make use of that to seed the - * pseudo-random generator. It's better than - * nothing... */ - - void *auxv; - - auxv = (void*) getauxval(AT_RANDOM); - if (auxv) - x ^= *(unsigned*) auxv; -#endif - - x ^= (unsigned) now(CLOCK_REALTIME); - x ^= (unsigned) gettid(); - - srand(x); - srand_called = true; - } + initialize_srand(); for (q = p; q < (uint8_t*) p + n; q ++) *q = rand(); @@ -2764,7 +2877,7 @@ int get_ctty(pid_t pid, dev_t *_devnr, char **r) { if (k < 0) return k; - snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr)); + sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr)); k = readlink_malloc(fn, &s); if (k < 0) { @@ -2922,6 +3035,19 @@ int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev); } +static int file_is_priv_sticky(const char *p) { + struct stat st; + + assert(p); + + if (lstat(p, &st) < 0) + return -errno; + + return + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); +} + static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) { int fd, r; struct statfs s; @@ -3160,7 +3286,8 @@ char *replace_env(const char *format, char **env) { case CURLY: if (*e == '{') { - if (!(k = strnappend(r, word, e-word-1))) + k = strnappend(r, word, e-word-1); + if (!k) goto fail; free(r); @@ -3170,7 +3297,8 @@ char *replace_env(const char *format, char **env) { state = VARIABLE; } else if (*e == '$') { - if (!(k = strnappend(r, word, e-word))) + k = strnappend(r, word, e-word); + if (!k) goto fail; free(r); @@ -3202,7 +3330,8 @@ char *replace_env(const char *format, char **env) { } } - if (!(k = strnappend(r, word, e-word))) + k = strnappend(r, word, e-word); + if (!k) goto fail; free(r); @@ -3213,6 +3342,7 @@ fail: return NULL; } +#if 0 /* NM_IGNORED */ char **replace_env_argv(char **argv, char **env) { char **ret, **i; unsigned k = 0, l = 0; @@ -3235,7 +3365,7 @@ char **replace_env_argv(char **argv, char **env) { if (e) { int r; - r = strv_split_quoted(&m, e); + r = strv_split_quoted(&m, e, true); if (r < 0) { ret[k] = NULL; strv_free(ret); @@ -3277,6 +3407,7 @@ char **replace_env_argv(char **argv, char **env) { ret[k] = NULL; return ret; } +#endif int fd_columns(int fd) { struct winsize ws = {}; @@ -3556,41 +3687,33 @@ char *unquote(const char *s, const char* quotes) { } char *normalize_env_assignment(const char *s) { - _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL; - char *eq, *r; + _cleanup_free_ char *value = NULL; + const char *eq; + char *p, *name; eq = strchr(s, '='); if (!eq) { - char *t; + char *r, *t; r = strdup(s); if (!r) return NULL; t = strstrip(r); - if (t == r) - return r; + if (t != r) + memmove(r, t, strlen(t) + 1); - memmove(r, t, strlen(t) + 1); return r; } - name = strndup(s, eq - s); - if (!name) - return NULL; - - p = strdup(eq + 1); - if (!p) - return NULL; + name = strndupa(s, eq - s); + p = strdupa(eq + 1); value = unquote(strstrip(p), QUOTES); if (!value) return NULL; - if (asprintf(&r, "%s=%s", strstrip(name), value) < 0) - r = NULL; - - return r; + return strjoin(strstrip(name), "=", value, NULL); } int wait_for_terminate(pid_t pid, siginfo_t *status) { @@ -4813,19 +4936,6 @@ int block_get_whole_disk(dev_t d, dev_t *ret) { return -ENOENT; } -int file_is_priv_sticky(const char *p) { - struct stat st; - - assert(p); - - if (lstat(p, &st) < 0) - return -errno; - - return - (st.st_uid == 0 || st.st_uid == getuid()) && - (st.st_mode & S_ISVTX); -} - static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", @@ -6136,27 +6246,28 @@ int split_pair(const char *s, const char *sep, char **l, char **r) { int shall_restore_state(void) { _cleanup_free_ char *line = NULL; - const char *word, *state; - size_t l; + const char *p; int r; r = proc_cmdline(&line); if (r < 0) return r; - if (r == 0) /* Container ... */ - return 1; r = 1; + p = line; - FOREACH_WORD_QUOTED(word, l, line, state) { + for (;;) { + _cleanup_free_ char *word = NULL; const char *e; - char n[l+1]; int k; - memcpy(n, word, l); - n[l] = 0; + k = unquote_first_word(&p, &word, true); + if (k < 0) + return k; + if (k == 0) + break; - e = startswith(n, "systemd.restore_state="); + e = startswith(word, "systemd.restore_state="); if (!e) continue; @@ -6169,51 +6280,35 @@ int shall_restore_state(void) { } int proc_cmdline(char **ret) { - int r; - - if (detect_container(NULL) > 0) { - char *buf = NULL, *p; - size_t sz = 0; - - r = read_full_file("/proc/1/cmdline", &buf, &sz); - if (r < 0) - return r; - - for (p = buf; p + 1 < buf + sz; p++) - if (*p == 0) - *p = ' '; - - *p = 0; - *ret = buf; - return 1; - } - - r = read_one_line_file("/proc/cmdline", ret); - if (r < 0) - return r; + assert(ret); - return 1; + if (detect_container(NULL) > 0) + return get_process_cmdline(1, 0, false, ret); + else + return read_one_line_file("/proc/cmdline", ret); } int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) { _cleanup_free_ char *line = NULL; - const char *w, *state; - size_t l; + const char *p; int r; assert(parse_item); r = proc_cmdline(&line); if (r < 0) - log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); - if (r <= 0) - return 0; + return r; - FOREACH_WORD_QUOTED(w, l, line, state) { - char word[l+1], *value; + p = line; + for (;;) { + _cleanup_free_ char *word = NULL; + char *value = NULL; - memcpy(word, w, l); - word[l] = 0; + r = unquote_first_word(&p, &word, true); + if (r < 0) + return r; + if (r == 0) + break; /* Filter out arguments that are intended only for the * initrd */ @@ -6983,19 +7078,19 @@ int is_symlink(const char *path) { int is_dir(const char* path, bool follow) { struct stat st; + int r; - if (follow) { - if (stat(path, &st) < 0) - return -errno; - } else { - if (lstat(path, &st) < 0) - return -errno; - } + if (follow) + r = stat(path, &st); + else + r = lstat(path, &st); + if (r < 0) + return -errno; return !!S_ISDIR(st.st_mode); } -int unquote_first_word(const char **p, char **ret) { +int unquote_first_word(const char **p, char **ret, bool relax) { _cleanup_free_ char *s = NULL; size_t allocated = 0, sz = 0; @@ -7054,8 +7149,11 @@ int unquote_first_word(const char **p, char **ret) { break; case VALUE_ESCAPE: - if (c == 0) + if (c == 0) { + if (relax) + goto finish; return -EINVAL; + } if (!GREEDY_REALLOC(s, allocated, sz+2)) return -ENOMEM; @@ -7066,9 +7164,11 @@ int unquote_first_word(const char **p, char **ret) { break; case SINGLE_QUOTE: - if (c == 0) + if (c == 0) { + if (relax) + goto finish; return -EINVAL; - else if (c == '\'') + } else if (c == '\'') state = VALUE; else if (c == '\\') state = SINGLE_QUOTE_ESCAPE; @@ -7082,8 +7182,11 @@ int unquote_first_word(const char **p, char **ret) { break; case SINGLE_QUOTE_ESCAPE: - if (c == 0) + if (c == 0) { + if (relax) + goto finish; return -EINVAL; + } if (!GREEDY_REALLOC(s, allocated, sz+2)) return -ENOMEM; @@ -7109,8 +7212,11 @@ int unquote_first_word(const char **p, char **ret) { break; case DOUBLE_QUOTE_ESCAPE: - if (c == 0) + if (c == 0) { + if (relax) + goto finish; return -EINVAL; + } if (!GREEDY_REALLOC(s, allocated, sz+2)) return -ENOMEM; @@ -7170,7 +7276,7 @@ int unquote_many_words(const char **p, ...) { l = newa0(char*, n); for (c = 0; c < n; c++) { - r = unquote_first_word(p, &l[c]); + r = unquote_first_word(p, &l[c], false); if (r < 0) { int j; diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/util.h b/src/dhcp-manager/systemd-dhcp/src/shared/util.h index f6ff8ea40f..a7690655eb 100644 --- a/src/dhcp-manager/systemd-dhcp/src/shared/util.h +++ b/src/dhcp-manager/systemd-dhcp/src/shared/util.h @@ -251,6 +251,9 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) { return safe_atolli(s, (long long int*) ret_i); } +int safe_atou16(const char *s, uint16_t *ret); +int safe_atoi16(const char *s, int16_t *ret); + const char* split(const char **state, size_t *l, const char *separator, bool quoted); #define FOREACH_WORD(word, length, s, state) \ @@ -276,6 +279,7 @@ char **replace_env_argv(char **argv, char **env); int readlinkat_malloc(int fd, const char *p, char **ret); int readlink_malloc(const char *p, char **r); +int readlink_value(const char *p, char **ret); int readlink_and_make_absolute(const char *p, char **r); int readlink_and_canonicalize(const char *p, char **r); @@ -327,6 +331,7 @@ int make_console_stdio(void); int dev_urandom(void *p, size_t n); void random_bytes(void *p, size_t n); +void initialize_srand(void); static inline uint64_t random_u64(void) { uint64_t u; @@ -587,8 +592,6 @@ static inline bool _pure_ in_charset(const char *s, const char* charset) { int block_get_whole_disk(dev_t d, dev_t *ret); -int file_is_priv_sticky(const char *p); - #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) @@ -799,6 +802,15 @@ static inline void _reset_errno_(int *saved_errno) { #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno +static inline int negative_errno(void) { + /* This helper should be used to shut up gcc if you know 'errno' is + * negative. Instead of "return -errno;", use "return negative_errno();" + * It will suppress bogus gcc warnings in case it assumes 'errno' might + * be 0 and thus the caller's error-handling might not be triggered. */ + assert_return(errno > 0, -EINVAL); + return -errno; +} + struct _umask_struct_ { mode_t mask; bool quit; @@ -835,6 +847,21 @@ static inline int log2i(int x) { return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1; } +static inline unsigned log2u(unsigned x) { + assert(x > 0); + + return sizeof(unsigned) * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u_round_up(unsigned x) { + assert(x > 0); + + if (x == 1) + return 0; + + return log2u(x - 1) + 1; +} + static inline bool logind_running(void) { return access("/run/systemd/seats/", F_OK) >= 0; } @@ -1003,7 +1030,7 @@ int take_password_lock(const char *root); int is_symlink(const char *path); int is_dir(const char *path, bool follow); -int unquote_first_word(const char **p, char **ret); +int unquote_first_word(const char **p, char **ret, bool relax); int unquote_many_words(const char **p, ...) _sentinel_; int free_and_strdup(char **p, const char *s); diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h index 953f6cddef..951662e56c 100644 --- a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h @@ -53,9 +53,8 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, size_t addr_len, uint16_t arp_type); int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type, const uint8_t *data, size_t data_len); -const uint8_t *sd_dhcp_client_get_client_id(sd_dhcp_client *client, - uint8_t *type, - size_t *len); +int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type, + const uint8_t **data, size_t *data_len); int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu); int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname); int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci); diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h index 1b0207b1c4..4296b91d8a 100644 --- a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h @@ -49,6 +49,6 @@ int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id, size_t *client_id_len); int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); -int sd_dhcp_lease_load(const char *lease_file, sd_dhcp_lease **ret); +int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); #endif diff --git a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h index 0dbdcdf2a5..25a10f99ab 100644 --- a/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h +++ b/src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h @@ -109,8 +109,8 @@ sd_event *sd_event_source_get_event(sd_event_source *s); void* sd_event_source_get_userdata(sd_event_source *s); void* sd_event_source_set_userdata(sd_event_source *s, void *userdata); -int sd_event_source_set_name(sd_event_source *s, const char *name); -int sd_event_source_get_name(sd_event_source *s, const char **name); +int sd_event_source_set_description(sd_event_source *s, const char *description); +int sd_event_source_get_description(sd_event_source *s, const char **description); int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback); int sd_event_source_get_pending(sd_event_source *s); int sd_event_source_get_priority(sd_event_source *s, int64_t *priority); |