systemd: merge branch 'systemd' into master

This commit is contained in:
Thomas Haller 2016-02-12 10:51:05 +01:00
commit 2835934244
94 changed files with 330 additions and 336 deletions

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -121,7 +119,7 @@ char *cescape(const char *s) {
return cescape_length(s, strlen(s));
}
int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit) {
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) {
int r = 1;
assert(p);
@ -232,7 +230,7 @@ int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit)
int a[8];
unsigned i;
uint32_t c;
char32_t c;
if (length != (size_t) -1 && length < 9)
return -EINVAL;
@ -269,7 +267,7 @@ int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit)
case '7': {
/* octal encoding */
int a, b, c;
uint32_t m;
char32_t m;
if (length != (size_t) -1 && length < 3)
return -EINVAL;
@ -329,8 +327,8 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
for (f = s, t = r + pl; f < s + length; f++) {
size_t remaining;
uint32_t u;
bool eight_bit = false;
char32_t u;
int k;
remaining = s + length - f;

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -27,8 +25,12 @@
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <uchar.h>
#include "string-util.h"
#if 0 /* NM_IGNORED */
#include "missing.h"
#endif /* NM_IGNORED */
/* What characters are special in the shell? */
/* must be escaped outside and inside double-quotes */
@ -47,7 +49,7 @@ size_t cescape_char(char c, char *buf);
int cunescape(const char *s, UnescapeFlags flags, char **ret);
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit);
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
char *xescape(const char *s, const char *bad);

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -1259,3 +1257,32 @@ int read_timestamp_file(const char *fn, usec_t *ret) {
*ret = (usec_t) t;
return 0;
}
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
int r;
assert(s);
/* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
* when specified shall initially point to a boolean variable initialized to false. It is set to true after the
* first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
* element, but not before the first one. */
if (!f)
f = stdout;
if (space) {
if (!separator)
separator = " ";
if (*space) {
r = fputs(separator, f);
if (r < 0)
return r;
}
*space = true;
}
return fputs(s, f);
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -84,3 +82,5 @@ int tempfn_random_child(const char *p, const char *extra, char **ret);
int write_timestamp_file_atomic(const char *fn, usec_t n);
int read_timestamp_file(const char *fn, usec_t *ret);
int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space);

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -352,7 +350,8 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi
if (parents)
mkdir_parents(path, 0755);
fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
(mode == 0 || mode == MODE_INVALID) ? 0644 : mode);
if (fd < 0)
return -errno;

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -516,14 +514,14 @@ int unbase64char(char c) {
return -EINVAL;
}
char *base64mem(const void *p, size_t l) {
ssize_t base64mem(const void *p, size_t l, char **out) {
char *r, *z;
const uint8_t *x;
/* three input bytes makes four output bytes, padding is added so we must round up */
z = r = malloc(4 * (l + 2) / 3 + 1);
if (!r)
return NULL;
return -ENOMEM;
for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
/* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
@ -551,9 +549,64 @@ char *base64mem(const void *p, size_t l) {
}
*z = 0;
return r;
*out = r;
return z - r;
}
static int base64_append_width(char **prefix, int plen,
const char *sep, int indent,
const void *p, size_t l,
int width) {
_cleanup_free_ char *x = NULL;
char *t, *s;
ssize_t slen, len, avail;
int line, lines;
len = base64mem(p, l, &x);
if (len <= 0)
return len;
lines = (len + width - 1) / width;
slen = sep ? strlen(sep) : 0;
t = realloc(*prefix, plen + 1 + slen + (indent + width + 1) * lines);
if (!t)
return -ENOMEM;
memcpy(t + plen, sep, slen);
for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
int act = MIN(width, avail);
if (line > 0 || sep) {
memset(s, ' ', indent);
s += indent;
}
memcpy(s, x + width * line, act);
s += act;
*(s++) = line < lines - 1 ? '\n' : '\0';
avail -= act;
}
assert(avail == 0);
*prefix = t;
return 0;
}
int base64_append(char **prefix, int plen,
const void *p, size_t l,
int indent, int width) {
if (plen > width / 2 || plen + indent > width)
/* leave indent on the left, keep last column free */
return base64_append_width(prefix, plen, "\n", indent, p, l, width - indent - 1);
else
/* leave plen on the left, keep last column free */
return base64_append_width(prefix, plen, NULL, plen, p, l, width - plen - 1);
};
int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
_cleanup_free_ uint8_t *r = NULL;
int a, b, c, d;

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -51,7 +49,10 @@ int unbase64char(char c) _const_;
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);
ssize_t base64mem(const void *p, size_t l, char **out);
int base64_append(char **prefix, int plen,
const void *p, size_t l,
int margin, int width);
int unbase64mem(const char *p, size_t l, void **mem, size_t *len);
void hexdump(FILE *f, const void *p, size_t s);

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -79,3 +77,21 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
return k;
}
static inline bool FILE_SIZE_VALID(uint64_t l) {
/* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than
* 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */
return (l >> 63) == 0;
}
static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) {
/* Same as above, but allows one extra value: -1 as indication for infinity. */
if (l == (uint64_t) -1)
return true;
return FILE_SIZE_VALID(l);
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -103,17 +103,18 @@ void initialize_srand(void) {
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... */
/* The kernel provides us with 16 bytes 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;
if (auxv) {
assert_cc(sizeof(x) < 16);
memcpy(&x, auxv, sizeof(x));
} else
#endif
x = 0;
x ^= (unsigned) now(CLOCK_REALTIME);
x ^= (unsigned) gettid();

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,6 +1,4 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -455,6 +453,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
char *e;
const char *i, *j;
unsigned k, len, len2;
int r;
assert(s);
assert(percent <= 100);
@ -474,10 +473,10 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
k = 0;
for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
int c;
char32_t c;
c = utf8_encoded_to_unichar(i);
if (c < 0)
r = utf8_encoded_to_unichar(i, &c);
if (r < 0)
return NULL;
k += unichar_iswide(c) ? 2 : 1;
}
@ -486,11 +485,11 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
x ++;
for (j = s + old_length; k < new_length && j > i; ) {
int c;
char32_t c;
j = utf8_prev_char(j);
c = utf8_encoded_to_unichar(j);
if (c < 0)
r = utf8_encoded_to_unichar(j, &c);
if (r < 0)
return NULL;
k += unichar_iswide(c) ? 2 : 1;
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -33,6 +31,7 @@
#if 0 /* NM_IGNORED */
#include "extract-word.h"
#endif /* NM_IGNORED */
#include "fileio.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
@ -877,3 +876,22 @@ rollback:
nl[k] = NULL;
return -ENOMEM;
}
int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
bool b = false;
char **s;
int r;
/* Like fputs(), but for strv, and with a less stupid argument order */
if (!space)
space = &b;
STRV_FOREACH(s, l) {
r = fputs_with_space(f, *s, separator, space);
if (r < 0)
return r;
}
return 0;
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -175,3 +173,5 @@ char ***strv_free_free(char ***l);
char **strv_skip(char **l, size_t n);
int strv_extend_n(char ***l, const char *value, size_t n);
int fputstrv(FILE *f, char **l, const char *separator, bool *space);

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -44,6 +42,8 @@
#include "strv.h"
#include "time-util.h"
static nsec_t timespec_load_nsec(const struct timespec *ts);
usec_t now(clockid_t clock_id) {
struct timespec ts;
@ -81,12 +81,7 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
ts->monotonic = now(CLOCK_MONOTONIC);
if ((int64_t) ts->monotonic > delta)
ts->monotonic -= delta;
else
ts->monotonic = 0;
ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
return ts;
}
@ -102,12 +97,7 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
ts->monotonic = u;
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
ts->realtime = now(CLOCK_REALTIME);
if ((int64_t) ts->realtime > delta)
ts->realtime -= delta;
else
ts->realtime = 0;
ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
return ts;
}
@ -119,25 +109,15 @@ dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, us
ts->realtime = ts->monotonic = USEC_INFINITY;
return ts;
}
ts->realtime = now(CLOCK_REALTIME);
ts->monotonic = now(CLOCK_MONOTONIC);
dual_timestamp_get(ts);
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
if ((int64_t) ts->realtime > delta)
ts->realtime -= delta;
else
ts->realtime = 0;
if ((int64_t) ts->monotonic > delta)
ts->monotonic -= delta;
else
ts->monotonic = 0;
ts->realtime = usec_sub(ts->realtime, delta);
ts->monotonic = usec_sub(ts->monotonic, delta);
return ts;
}
usec_t timespec_load(const struct timespec *ts) {
assert(ts);
@ -153,7 +133,7 @@ usec_t timespec_load(const struct timespec *ts) {
(usec_t) ts->tv_nsec / NSEC_PER_USEC;
}
nsec_t timespec_load_nsec(const struct timespec *ts) {
static nsec_t timespec_load_nsec(const struct timespec *ts) {
assert(ts);
if (ts->tv_sec == (time_t) -1 &&
@ -210,9 +190,11 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) {
return tv;
}
static char *format_timestamp_internal(char *buf, size_t l, usec_t t, bool utc) {
static char *format_timestamp_internal(char *buf, size_t l, usec_t t,
bool utc, bool us) {
struct tm tm;
time_t sec;
int k;
assert(buf);
assert(l > 0);
@ -223,48 +205,36 @@ static char *format_timestamp_internal(char *buf, size_t l, usec_t t, bool utc)
sec = (time_t) (t / USEC_PER_SEC);
localtime_or_gmtime_r(&sec, &tm, utc);
if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm) <= 0)
if (us)
k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm);
else
k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm);
if (k <= 0)
return NULL;
if (us) {
snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
return NULL;
}
return buf;
}
char *format_timestamp(char *buf, size_t l, usec_t t) {
return format_timestamp_internal(buf, l, t, false);
return format_timestamp_internal(buf, l, t, false, false);
}
char *format_timestamp_utc(char *buf, size_t l, usec_t t) {
return format_timestamp_internal(buf, l, t, true);
}
static char *format_timestamp_internal_us(char *buf, size_t l, usec_t t, bool utc) {
struct tm tm;
time_t sec;
assert(buf);
assert(l > 0);
if (t <= 0 || t == USEC_INFINITY)
return NULL;
sec = (time_t) (t / USEC_PER_SEC);
localtime_or_gmtime_r(&sec, &tm, utc);
if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0)
return NULL;
snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
return NULL;
return buf;
return format_timestamp_internal(buf, l, t, true, false);
}
char *format_timestamp_us(char *buf, size_t l, usec_t t) {
return format_timestamp_internal_us(buf, l, t, false);
return format_timestamp_internal(buf, l, t, false, true);
}
char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) {
return format_timestamp_internal_us(buf, l, t, true);
return format_timestamp_internal(buf, l, t, true, true);
}
char *format_timestamp_relative(char *buf, size_t l, usec_t t) {

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -71,7 +69,7 @@ typedef struct dual_timestamp {
#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
#define FORMAT_TIMESPAN_MAX 64
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1)
#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0ULL, 0ULL })
@ -94,8 +92,6 @@ struct timespec *timespec_store(struct timespec *ts, usec_t u);
usec_t timeval_load(const struct timeval *tv) _pure_;
struct timeval *timeval_store(struct timeval *tv, usec_t u);
nsec_t timespec_load_nsec(const struct timespec *ts) _pure_;
char *format_timestamp(char *buf, size_t l, usec_t t);
char *format_timestamp_utc(char *buf, size_t l, usec_t t);
char *format_timestamp_us(char *buf, size_t l, usec_t t);
@ -129,3 +125,29 @@ time_t mktime_or_timegm(struct tm *tm, bool utc);
struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc);
unsigned long usec_to_jiffies(usec_t usec);
static inline usec_t usec_add(usec_t a, usec_t b) {
usec_t c;
/* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't
* overflow. */
c = a + b;
if (c < a || c < b) /* overflow check */
return USEC_INFINITY;
return c;
}
static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
if (delta < 0)
return usec_add(timestamp, (usec_t) (-delta));
if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
return USEC_INFINITY;
if (timestamp < (usec_t) delta)
return 0;
return timestamp - delta;
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -55,7 +53,7 @@
#include "macro.h"
#include "utf8.h"
bool unichar_is_valid(uint32_t ch) {
bool unichar_is_valid(char32_t ch) {
if (ch >= 0x110000) /* End of unicode space */
return false;
@ -69,7 +67,7 @@ bool unichar_is_valid(uint32_t ch) {
return true;
}
static bool unichar_is_control(uint32_t ch) {
static bool unichar_is_control(char32_t ch) {
/*
0 to ' '-1 is the C0 range.
@ -105,8 +103,9 @@ static int utf8_encoded_expected_len(const char *str) {
}
/* decode one unicode char */
int utf8_encoded_to_unichar(const char *str) {
int unichar, len, i;
int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
char32_t unichar;
int len, i;
assert(str);
@ -114,34 +113,37 @@ int utf8_encoded_to_unichar(const char *str) {
switch (len) {
case 1:
return (int)str[0];
*ret_unichar = (char32_t)str[0];
return 0;
case 2:
unichar = str[0] & 0x1f;
break;
case 3:
unichar = (int)str[0] & 0x0f;
unichar = (char32_t)str[0] & 0x0f;
break;
case 4:
unichar = (int)str[0] & 0x07;
unichar = (char32_t)str[0] & 0x07;
break;
case 5:
unichar = (int)str[0] & 0x03;
unichar = (char32_t)str[0] & 0x03;
break;
case 6:
unichar = (int)str[0] & 0x01;
unichar = (char32_t)str[0] & 0x01;
break;
default:
return -EINVAL;
}
for (i = 1; i < len; i++) {
if (((int)str[i] & 0xc0) != 0x80)
if (((char32_t)str[i] & 0xc0) != 0x80)
return -EINVAL;
unichar <<= 6;
unichar |= (int)str[i] & 0x3f;
unichar |= (char32_t)str[i] & 0x3f;
}
return unichar;
*ret_unichar = unichar;
return 0;
}
bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
@ -150,15 +152,16 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) {
assert(str);
for (p = str; length;) {
int encoded_len, val;
int encoded_len, r;
char32_t val;
encoded_len = utf8_encoded_valid_unichar(p);
if (encoded_len < 0 ||
(size_t) encoded_len > length)
return false;
val = utf8_encoded_to_unichar(p);
if (val < 0 ||
r = utf8_encoded_to_unichar(p, &val);
if (r < 0 ||
unichar_is_control(val) ||
(!newline && val == '\n'))
return false;
@ -278,7 +281,7 @@ char *ascii_is_valid(const char *str) {
* Returns: The length in bytes that the UTF-8 representation does or would
* occupy.
*/
size_t utf8_encode_unichar(char *out_utf8, uint32_t g) {
size_t utf8_encode_unichar(char *out_utf8, char32_t g) {
if (g < (1 << 7)) {
if (out_utf8)
@ -322,7 +325,7 @@ char *utf16_to_utf8(const void *s, size_t length) {
t = r;
while (f < (const uint8_t*) s + length) {
uint16_t w1, w2;
char16_t w1, w2;
/* see RFC 2781 section 2.2 */
@ -356,7 +359,7 @@ char *utf16_to_utf8(const void *s, size_t length) {
}
/* expected size used to encode one unicode char */
static int utf8_unichar_to_encoded_len(int unichar) {
static int utf8_unichar_to_encoded_len(char32_t unichar) {
if (unichar < 0x80)
return 1;
@ -374,7 +377,8 @@ static int utf8_unichar_to_encoded_len(int unichar) {
/* validate one encoded unicode char and return its length */
int utf8_encoded_valid_unichar(const char *str) {
int len, unichar, i;
int len, i, r;
char32_t unichar;
assert(str);
@ -391,7 +395,9 @@ int utf8_encoded_valid_unichar(const char *str) {
if ((str[i] & 0x80) != 0x80)
return -EINVAL;
unichar = utf8_encoded_to_unichar(str);
r = utf8_encoded_to_unichar(str, &unichar);
if (r < 0)
return r;
/* check if encoded length matches encoded value */
if (utf8_unichar_to_encoded_len(unichar) != len)

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
@ -26,12 +24,16 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <uchar.h>
#include "macro.h"
#if 0 /* NM_IGNORED */
#include "missing.h"
#endif /* NM_IGNORED */
#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
bool unichar_is_valid(uint32_t c);
bool unichar_is_valid(char32_t c);
const char *utf8_is_valid(const char *s) _pure_;
char *ascii_is_valid(const char *s) _pure_;
@ -42,20 +44,20 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pu
char *utf8_escape_invalid(const char *s);
char *utf8_escape_non_printable(const char *str);
size_t utf8_encode_unichar(char *out_utf8, uint32_t g);
size_t utf8_encode_unichar(char *out_utf8, char32_t g);
char *utf16_to_utf8(const void *s, size_t length);
int utf8_encoded_valid_unichar(const char *str);
int utf8_encoded_to_unichar(const char *str);
int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar);
static inline bool utf16_is_surrogate(uint16_t c) {
static inline bool utf16_is_surrogate(char16_t c) {
return (0xd800 <= c && c <= 0xdfff);
}
static inline bool utf16_is_trailing_surrogate(uint16_t c) {
static inline bool utf16_is_trailing_surrogate(char16_t c) {
return (0xdc00 <= c && c <= 0xdfff);
}
static inline uint32_t utf16_surrogate_pair_to_unichar(uint16_t lead, uint16_t trail) {
static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) {
return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
}

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***

View file

@ -45,6 +45,9 @@
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
#define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
#define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
struct sd_dhcp_client {
unsigned n_ref;
@ -103,6 +106,7 @@ struct sd_dhcp_client {
sd_dhcp_client_cb_t cb;
void *userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
};
static const uint8_t default_req_opts[] = {
@ -947,6 +951,7 @@ error:
}
static int client_initialize_time_events(sd_dhcp_client *client) {
uint64_t usec = 0;
int r;
assert(client);
@ -954,10 +959,15 @@ static int client_initialize_time_events(sd_dhcp_client *client) {
client->timeout_resend = sd_event_source_unref(client->timeout_resend);
if (client->start_delay) {
sd_event_now(client->event, clock_boottime_or_monotonic(), &usec);
usec += client->start_delay;
}
r = sd_event_add_time(client->event,
&client->timeout_resend,
clock_boottime_or_monotonic(),
0, 0,
usec, 0,
client_timeout_resend, client);
if (r < 0)
goto error;
@ -987,7 +997,7 @@ static int client_initialize_events(sd_dhcp_client *client,
return 0;
}
static int client_start(sd_dhcp_client *client) {
static int client_start_delayed(sd_dhcp_client *client) {
int r;
assert_return(client, -EINVAL);
@ -1015,6 +1025,11 @@ static int client_start(sd_dhcp_client *client) {
return client_initialize_events(client, client_receive_message_raw);
}
static int client_start(sd_dhcp_client *client) {
client->start_delay = 0;
return client_start_delayed(client);
}
static int client_timeout_expire(sd_event_source *s, uint64_t usec,
void *userdata) {
sd_dhcp_client *client = userdata;
@ -1364,6 +1379,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
int len) {
DHCP_CLIENT_DONT_DESTROY(client);
char time_string[FORMAT_TIMESPAN_MAX];
int r = 0, notify_event = 0;
assert(client);
@ -1411,6 +1427,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
r = client_handle_ack(client, message, len);
if (r >= 0) {
client->start_delay = 0;
client->timeout_resend =
sd_event_source_unref(client->timeout_resend);
client->receive_message =
@ -1460,11 +1477,15 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
if (r < 0)
goto error;
r = client_start(client);
r = client_start_delayed(client);
if (r < 0)
goto error;
log_dhcp_client(client, "REBOOTED");
log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
client->start_delay, USEC_PER_SEC));
client->start_delay = CLAMP(client->start_delay * 2,
RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
return 0;
} else if (r == -ENOMSG)

View file

@ -355,6 +355,38 @@ static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
return 0;
}
static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
_cleanup_free_ char *name = NULL, *normalized = NULL;
int r;
assert(option);
assert(ret);
r = lease_parse_string(option, len, &name);
if (r < 0)
return r;
if (!name) {
*ret = mfree(*ret);
return 0;
}
r = dns_name_normalize(name, &normalized);
if (r < 0)
return r;
if (is_localhost(normalized))
return -EINVAL;
if (dns_name_is_root(normalized))
return -EINVAL;
free(*ret);
*ret = normalized;
normalized = NULL;
return 0;
}
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option);
assert(ret);
@ -549,59 +581,23 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
break;
case SD_DHCP_OPTION_DOMAIN_NAME: {
_cleanup_free_ char *domainname = NULL, *normalized = NULL;
r = lease_parse_string(option, len, &domainname);
case SD_DHCP_OPTION_DOMAIN_NAME:
r = lease_parse_domain(option, len, &lease->domainname);
if (r < 0) {
log_debug_errno(r, "Failed to parse domain name, ignoring: %m");
return 0;
}
r = dns_name_normalize(domainname, &normalized);
if (r < 0) {
log_debug_errno(r, "Failed to normalize domain name '%s': %m", domainname);
return 0;
}
if (is_localhost(normalized)) {
log_debug_errno(r, "Detected 'localhost' as suggested domain name, ignoring.");
break;
}
free(lease->domainname);
lease->domainname = normalized;
normalized = NULL;
break;
}
case SD_DHCP_OPTION_HOST_NAME: {
_cleanup_free_ char *hostname = NULL, *normalized = NULL;
r = lease_parse_string(option, len, &hostname);
case SD_DHCP_OPTION_HOST_NAME:
r = lease_parse_domain(option, len, &lease->hostname);
if (r < 0) {
log_debug_errno(r, "Failed to parse host name, ignoring: %m");
return 0;
}
r = dns_name_normalize(hostname, &normalized);
if (r < 0) {
log_debug_errno(r, "Failed to normalize host name '%s', ignoring: %m", hostname);
return 0;
}
if (is_localhost(normalized)) {
log_debug_errno(r, "Detected 'localhost' as suggested host name, ignoring.");
return 0;
}
free(lease->hostname);
lease->hostname = normalized;
normalized = NULL;
break;
}
case SD_DHCP_OPTION_ROOT_PATH:
r = lease_parse_string(option, len, &lease->root_path);

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
@ -407,11 +405,17 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded,
int dns_name_concat(const char *a, const char *b, char **_ret) {
_cleanup_free_ char *ret = NULL;
size_t n = 0, allocated = 0;
const char *p = a;
const char *p;
bool first = true;
int r;
assert(a);
if (a)
p = a;
else if (b) {
p = b;
b = NULL;
} else
goto finish;
for (;;) {
char label[DNS_LABEL_MAX];
@ -459,12 +463,21 @@ int dns_name_concat(const char *a, const char *b, char **_ret) {
n += r;
}
finish:
if (n > DNS_HOSTNAME_MAX)
return -EINVAL;
if (_ret) {
if (!GREEDY_REALLOC(ret, allocated, n + 1))
return -ENOMEM;
if (n == 0) {
/* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */
if (!GREEDY_REALLOC(ret, allocated, 2))
return -ENOMEM;
ret[n++] = '.';
} else {
if (!GREEDY_REALLOC(ret, allocated, n + 1))
return -ENOMEM;
}
ret[n] = 0;
*_ret = ret;

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdcommonhfoo
#define foosdcommonhfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosddhcpclienthfoo
#define foosddhcpclienthfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosddhcpleasehfoo
#define foosddhcpleasehfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosddhcp6clienthfoo
#define foosddhcp6clienthfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosddhcp6leasehfoo
#define foosddhcp6leasehfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdeventhfoo
#define foosdeventhfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdid128hfoo
#define foosdid128hfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdipv4acdfoo
#define foosdipv4acdfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdipv4llfoo
#define foosdipv4llfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdlldphfoo
#define foosdlldphfoo

View file

@ -1,5 +1,3 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdndiscfoo
#define foosdndiscfoo