summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/time-util.c3
-rw-r--r--src/core/unit.c2
-rw-r--r--src/journal-remote/journal-remote.c2
-rw-r--r--src/journal/catalog.c146
-rw-r--r--src/journal/catalog.h2
-rw-r--r--src/journal/journal-file.c32
-rw-r--r--src/journal/journald-server.c13
-rw-r--r--src/journal/mmap-cache.c66
-rw-r--r--src/journal/sd-journal.c2
-rw-r--r--src/journal/test-catalog.c130
-rw-r--r--src/resolve/resolved-dns-dnssec.c2
-rw-r--r--src/resolve/resolved-dns-packet.c2
-rw-r--r--src/resolve/resolved-dns-rr.c2
13 files changed, 301 insertions, 103 deletions
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index bfc7cf870c..293442cf0e 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -117,9 +117,8 @@ 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)
diff --git a/src/core/unit.c b/src/core/unit.c
index 0c1efc0e16..be4dac8fea 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2852,7 +2852,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
/* Versions before 228 did not carry a state change timestamp. In this case, take the current time. This is
* useful, so that timeouts based on this timestamp don't trigger too early, and is in-line with the logic from
- * before 228 where the base for timeouts was not peristet across reboots. */
+ * before 228 where the base for timeouts was not persistent across reboots. */
if (!dual_timestamp_is_set(&u->state_change_timestamp))
dual_timestamp_get(&u->state_change_timestamp);
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index cfe111fd91..fa4a4ff931 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -645,7 +645,7 @@ static int setup_microhttpd_server(RemoteServer *s,
{ MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free},
{ MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger},
{ MHD_OPTION_LISTEN_SOCKET, fd},
- { MHD_OPTION_CONNECTION_MEMORY_LIMIT, DATA_SIZE_MAX},
+ { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
diff --git a/src/journal/catalog.c b/src/journal/catalog.c
index fcaa54aa0c..ddec6bd503 100644
--- a/src/journal/catalog.c
+++ b/src/journal/catalog.c
@@ -94,25 +94,87 @@ const struct hash_ops catalog_hash_ops = {
.compare = catalog_compare_func
};
+static bool next_header(const char **s) {
+ const char *e;
+
+ e = strchr(*s, '\n');
+
+ /* Unexpected end */
+ if (!e)
+ return false;
+
+ /* End of headers */
+ if (e == *s)
+ return false;
+
+ *s = e + 1;
+ return true;
+}
+
+static const char *skip_header(const char *s) {
+ while (next_header(&s))
+ ;
+ return s;
+}
+
+static char *combine_entries(const char *one, const char *two) {
+ const char *b1, *b2;
+ size_t l1, l2, n;
+ char *dest, *p;
+
+ /* Find split point of headers to body */
+ b1 = skip_header(one);
+ b2 = skip_header(two);
+
+ l1 = strlen(one);
+ l2 = strlen(two);
+ dest = new(char, l1 + l2 + 1);
+ if (!dest) {
+ log_oom();
+ return NULL;
+ }
+
+ p = dest;
+
+ /* Headers from @one */
+ n = b1 - one;
+ p = mempcpy(p, one, n);
+
+ /* Headers from @two, these will only be found if not present above */
+ n = b2 - two;
+ p = mempcpy(p, two, n);
+
+ /* Body from @one */
+ n = l1 - (b1 - one);
+ if (n > 0) {
+ memcpy(p, b1, n);
+ p += n;
+
+ /* Body from @two */
+ } else {
+ n = l2 - (b2 - two);
+ memcpy(p, b2, n);
+ p += n;
+ }
+
+ assert(p - dest <= (ptrdiff_t)(l1 + l2));
+ p[0] = '\0';
+ return dest;
+}
+
static int finish_item(
Hashmap *h,
- struct strbuf *sb,
sd_id128_t id,
const char *language,
- const char *payload) {
+ char *payload) {
- ssize_t offset;
_cleanup_free_ CatalogItem *i = NULL;
+ _cleanup_free_ char *combined = NULL, *prev = NULL;
int r;
assert(h);
- assert(sb);
assert(payload);
- offset = strbuf_add_string(sb, payload, strlen(payload));
- if (offset < 0)
- return log_oom();
-
i = new0(CatalogItem, 1);
if (!i)
return log_oom();
@@ -122,17 +184,27 @@ static int finish_item(
assert(strlen(language) > 1 && strlen(language) < 32);
strcpy(i->language, language);
}
- i->offset = htole64((uint64_t) offset);
- r = hashmap_put(h, i, i);
- if (r == -EEXIST) {
- log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.",
- SD_ID128_FORMAT_VAL(id), language ? language : "C");
- return 0;
- } else if (r < 0)
- return r;
+ prev = hashmap_get(h, i);
+
+ /* Already have such an item, combine them */
+ if (prev) {
+ combined = combine_entries(payload, prev);
+ if (!combined)
+ return log_oom();
+ r = hashmap_update(h, i, combined);
+ if (r < 0)
+ return r;
+ combined = NULL;
+
+ /* A new item */
+ } else {
+ r = hashmap_put(h, i, payload);
+ if (r < 0)
+ return r;
+ i = NULL;
+ }
- i = NULL;
return 0;
}
@@ -189,7 +261,7 @@ static int catalog_entry_lang(const char* filename, int line,
return 0;
}
-int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
+int catalog_import_file(Hashmap *h, const char *path) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *payload = NULL;
unsigned n = 0;
@@ -199,7 +271,6 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
int r;
assert(h);
- assert(sb);
assert(path);
f = fopen(path, "re");
@@ -254,10 +325,11 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
if (got_id) {
- r = finish_item(h, sb, id, lang ?: deflang, payload);
+ r = finish_item(h, id, lang ?: deflang, payload);
if (r < 0)
return r;
+ payload = NULL;
lang = mfree(lang);
}
@@ -310,9 +382,10 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
}
if (got_id) {
- r = finish_item(h, sb, id, lang ?: deflang, payload);
+ r = finish_item(h, id, lang ?: deflang, payload);
if (r < 0)
return r;
+ payload = NULL;
}
return 0;
@@ -389,8 +462,10 @@ int catalog_update(const char* database, const char* root, const char* const* di
_cleanup_strv_free_ char **files = NULL;
char **f;
struct strbuf *sb = NULL;
- _cleanup_hashmap_free_free_ Hashmap *h = NULL;
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
_cleanup_free_ CatalogItem *items = NULL;
+ ssize_t offset;
+ char *payload;
CatalogItem *i;
Iterator j;
unsigned n;
@@ -413,7 +488,7 @@ int catalog_update(const char* database, const char* root, const char* const* di
STRV_FOREACH(f, files) {
log_debug("Reading file '%s'", *f);
- r = catalog_import_file(h, sb, *f);
+ r = catalog_import_file(h, *f);
if (r < 0) {
log_error_errno(r, "Failed to import file '%s': %m", *f);
goto finish;
@@ -426,8 +501,6 @@ int catalog_update(const char* database, const char* root, const char* const* di
} else
log_debug("Found %u items in catalog.", hashmap_size(h));
- strbuf_complete(sb);
-
items = new(CatalogItem, hashmap_size(h));
if (!items) {
r = log_oom();
@@ -435,16 +508,25 @@ int catalog_update(const char* database, const char* root, const char* const* di
}
n = 0;
- HASHMAP_FOREACH(i, h, j) {
+ HASHMAP_FOREACH_KEY(payload, i, h, j) {
log_debug("Found " SD_ID128_FORMAT_STR ", language %s",
SD_ID128_FORMAT_VAL(i->id),
isempty(i->language) ? "C" : i->language);
+
+ offset = strbuf_add_string(sb, payload, strlen(payload));
+ if (offset < 0) {
+ r = log_oom();
+ goto finish;
+ }
+ i->offset = htole64((uint64_t) offset);
items[n++] = *i;
}
assert(n == hashmap_size(h));
qsort_safe(items, n, sizeof(CatalogItem), catalog_compare_func);
+ strbuf_complete(sb);
+
sz = write_catalog(database, sb, items, n);
if (sz < 0)
r = log_error_errno(sz, "Failed to write %s: %m", database);
@@ -587,7 +669,7 @@ finish:
static char *find_header(const char *s, const char *header) {
for (;;) {
- const char *v, *e;
+ const char *v;
v = startswith(s, header);
if (v) {
@@ -595,16 +677,8 @@ static char *find_header(const char *s, const char *header) {
return strndup(v, strcspn(v, NEWLINE));
}
- /* End of text */
- e = strchr(s, '\n');
- if (!e)
+ if (!next_header(&s))
return NULL;
-
- /* End of header */
- if (e == s)
- return NULL;
-
- s = e + 1;
}
}
diff --git a/src/journal/catalog.h b/src/journal/catalog.h
index bcc73c2631..b3856d2de0 100644
--- a/src/journal/catalog.h
+++ b/src/journal/catalog.h
@@ -28,7 +28,7 @@
#include "hashmap.h"
#include "strbuf.h"
-int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path);
+int catalog_import_file(Hashmap *h, const char *path);
int catalog_update(const char* database, const char* root, const char* const* dirs);
int catalog_get(const char* database, sd_id128_t id, char **data);
int catalog_list(FILE *f, const char* database, bool oneline);
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 2973176c8d..3d87e25724 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -100,7 +100,7 @@ static int journal_file_set_online(JournalFile *f) {
if (mmap_cache_got_sigbus(f->mmap, f->fd))
return -EIO;
- switch(f->header->state) {
+ switch (f->header->state) {
case STATE_ONLINE:
return 0;
@@ -247,6 +247,7 @@ static int journal_file_refresh_header(JournalFile *f) {
int r;
assert(f);
+ assert(f->header);
r = sd_id128_get_machine(&f->header->machine_id);
if (r < 0)
@@ -273,6 +274,7 @@ static int journal_file_verify_header(JournalFile *f) {
uint32_t flags;
assert(f);
+ assert(f->header);
if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
return -EBADMSG;
@@ -381,6 +383,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
int r;
assert(f);
+ assert(f->header);
/* We assume that this file is not sparse, and we know that
* for sure, since we always call posix_fallocate()
@@ -544,6 +547,7 @@ static uint64_t journal_file_entry_seqnum(JournalFile *f, uint64_t *seqnum) {
uint64_t r;
assert(f);
+ assert(f->header);
r = le64toh(f->header->tail_entry_seqnum) + 1;
@@ -573,6 +577,7 @@ int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, O
void *t;
assert(f);
+ assert(f->header);
assert(type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX);
assert(size >= sizeof(ObjectHeader));
assert(offset);
@@ -622,6 +627,7 @@ static int journal_file_setup_data_hash_table(JournalFile *f) {
int r;
assert(f);
+ assert(f->header);
/* We estimate that we need 1 hash table entry per 768 bytes
of journal file and we want to make sure we never get
@@ -655,6 +661,7 @@ static int journal_file_setup_field_hash_table(JournalFile *f) {
int r;
assert(f);
+ assert(f->header);
/* We use a fixed size hash table for the fields as this
* number should grow very slowly only */
@@ -681,6 +688,7 @@ int journal_file_map_data_hash_table(JournalFile *f) {
int r;
assert(f);
+ assert(f->header);
if (f->data_hash_table)
return 0;
@@ -706,6 +714,7 @@ int journal_file_map_field_hash_table(JournalFile *f) {
int r;
assert(f);
+ assert(f->header);
if (f->field_hash_table)
return 0;
@@ -735,6 +744,8 @@ static int journal_file_link_field(
int r;
assert(f);
+ assert(f->header);
+ assert(f->field_hash_table);
assert(o);
assert(offset > 0);
@@ -778,6 +789,8 @@ static int journal_file_link_data(
int r;
assert(f);
+ assert(f->header);
+ assert(f->data_hash_table);
assert(o);
assert(offset > 0);
@@ -826,6 +839,7 @@ int journal_file_find_field_object_with_hash(
int r;
assert(f);
+ assert(f->header);
assert(field && size > 0);
/* If the field hash table is empty, we can't find anything */
@@ -897,6 +911,7 @@ int journal_file_find_data_object_with_hash(
int r;
assert(f);
+ assert(f->header);
assert(data || size == 0);
/* If there's no data hash table, then there's no entry. */
@@ -1193,6 +1208,7 @@ static int link_entry_into_array(JournalFile *f,
Object *o;
assert(f);
+ assert(f->header);
assert(first);
assert(idx);
assert(p > 0);
@@ -1313,6 +1329,7 @@ static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) {
int r;
assert(f);
+ assert(f->header);
assert(o);
assert(offset > 0);
@@ -1363,6 +1380,7 @@ static int journal_file_append_entry_internal(
int r;
assert(f);
+ assert(f->header);
assert(items || n_items == 0);
assert(ts);
@@ -1507,6 +1525,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
struct dual_timestamp _ts;
assert(f);
+ assert(f->header);
assert(iovec || n_iovec == 0);
if (!ts) {
@@ -2022,6 +2041,8 @@ int journal_file_move_to_entry_by_seqnum(
direction_t direction,
Object **ret,
uint64_t *offset) {
+ assert(f);
+ assert(f->header);
return generic_array_bisect(f,
le64toh(f->header->entry_array_offset),
@@ -2057,6 +2078,8 @@ int journal_file_move_to_entry_by_realtime(
direction_t direction,
Object **ret,
uint64_t *offset) {
+ assert(f);
+ assert(f->header);
return generic_array_bisect(f,
le64toh(f->header->entry_array_offset),
@@ -2149,7 +2172,9 @@ void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) {
int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
assert(af);
+ assert(af->header);
assert(bf);
+ assert(bf->header);
assert(af->location_type == LOCATION_SEEK);
assert(bf->location_type == LOCATION_SEEK);
@@ -2209,6 +2234,7 @@ int journal_file_next_entry(
int r;
assert(f);
+ assert(f->header);
n = le64toh(f->header->n_entries);
if (n <= 0)
@@ -2491,6 +2517,7 @@ void journal_file_dump(JournalFile *f) {
uint64_t p;
assert(f);
+ assert(f->header);
journal_file_print_header(f);
@@ -2575,6 +2602,7 @@ void journal_file_print_header(JournalFile *f) {
char bytes[FORMAT_BYTES_MAX];
assert(f);
+ assert(f->header);
printf("File Path: %s\n"
"File ID: %s\n"
@@ -3180,6 +3208,7 @@ void journal_default_metrics(JournalMetrics *m, int fd) {
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
assert(f);
+ assert(f->header);
assert(from || to);
if (from) {
@@ -3243,6 +3272,7 @@ int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, u
bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) {
assert(f);
+ assert(f->header);
/* If we gained new header fields we gained new features,
* hence suggest a rotation */
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 8ff7ef943b..6a4e3bf249 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -244,7 +244,6 @@ static int open_journal(
int flags,
bool seal,
JournalMetrics *metrics,
- JournalFile *template,
JournalFile **ret) {
int r;
JournalFile *f;
@@ -254,9 +253,9 @@ static int open_journal(
assert(ret);
if (reliably)
- r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
else
- r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
if (r < 0)
return r;
@@ -308,7 +307,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
journal_file_close(f);
}
- r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &f);
+ r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
if (r < 0)
return s->system_journal;
@@ -1000,7 +999,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
(void) mkdir(fn, 0755);
fn = strjoina(fn, "/system.journal");
- r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &s->system_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &s->system_journal);
if (r >= 0) {
server_add_acls(s->system_journal, 0);
(void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
@@ -1023,7 +1022,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
* if it already exists, so that we can flush
* it into the system journal */
- r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, &s->runtime_journal);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to open runtime journal: %m");
@@ -1040,7 +1039,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
(void) mkdir("/run/log/journal", 0755);
(void) mkdir_parents(fn, 0750);
- r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, &s->runtime_journal);
if (r < 0)
return log_error_errno(r, "Failed to open runtime journal: %m");
}
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
index a69672ce21..4636e4b395 100644
--- a/src/journal/mmap-cache.c
+++ b/src/journal/mmap-cache.c
@@ -173,10 +173,11 @@ _pure_ static bool window_matches(Window *w, int fd, int prot, uint64_t offset,
offset + size <= w->offset + w->size;
}
-static Window *window_add(MMapCache *m) {
+static Window *window_add(MMapCache *m, FileDescriptor *fd, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
Window *w;
assert(m);
+ assert(fd);
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
@@ -194,6 +195,15 @@ static Window *window_add(MMapCache *m) {
}
w->cache = m;
+ w->fd = fd;
+ w->prot = prot;
+ w->keep_always = keep_always;
+ w->offset = offset;
+ w->size = size;
+ w->ptr = ptr;
+
+ LIST_PREPEND(by_fd, fd->windows, w);
+
return w;
}
@@ -459,6 +469,33 @@ static int find_mmap(
return 1;
}
+static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags, uint64_t offset, size_t size, void **res) {
+ void *ptr;
+
+ assert(m);
+ assert(fd >= 0);
+ assert(res);
+
+ for (;;) {
+ int r;
+
+ ptr = mmap(addr, size, prot, flags, fd, offset);
+ if (ptr != MAP_FAILED)
+ break;
+ if (errno != ENOMEM)
+ return -errno;
+
+ r = make_room(m);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENOMEM;
+ }
+
+ *res = ptr;
+ return 0;
+}
+
static int add_mmap(
MMapCache *m,
int fd,
@@ -512,19 +549,9 @@ static int add_mmap(
wsize = PAGE_ALIGN(st->st_size - woffset);
}
- for (;;) {
- d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset);
- if (d != MAP_FAILED)
- break;
- if (errno != ENOMEM)
- return -errno;
-
- r = make_room(m);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENOMEM;
- }
+ r = mmap_try_harder(m, NULL, fd, prot, MAP_SHARED, woffset, wsize, &d);
+ if (r < 0)
+ return r;
c = context_add(m, context);
if (!c)
@@ -534,19 +561,10 @@ static int add_mmap(
if (!f)
goto outofmem;
- w = window_add(m);
+ w = window_add(m, f, prot, keep_always, woffset, wsize, d);
if (!w)
goto outofmem;
- w->keep_always = keep_always;
- w->ptr = d;
- w->offset = woffset;
- w->prot = prot;
- w->size = wsize;
- w->fd = f;
-
- LIST_PREPEND(by_fd, f->windows, w);
-
context_detach_window(c);
c->window = w;
LIST_PREPEND(by_window, w->contexts, c);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 7a3aaf0cab..5ff2335efe 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -2638,7 +2638,7 @@ _public_ int sd_journal_enumerate_fields(sd_journal *j, const char **field) {
}
}
- /* We use OBJECT_UNUSED here, so that the iteator below doesn't remove our mmap window */
+ /* We use OBJECT_UNUSED here, so that the iterator below doesn't remove our mmap window */
r = journal_file_move_to_object(f, OBJECT_UNUSED, j->fields_offset, &o);
if (r < 0)
return r;
diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c
index 25980b7744..ae936f6419 100644
--- a/src/journal/test-catalog.c
+++ b/src/journal/test-catalog.c
@@ -46,61 +46,135 @@ static const char *no_catalog_dirs[] = {
NULL
};
-static void test_import(Hashmap *h, struct strbuf *sb,
- const char* contents, ssize_t size, int code) {
+static Hashmap * test_import(const char* contents, ssize_t size, int code) {
int r;
char name[] = "/tmp/test-catalog.XXXXXX";
_cleanup_close_ int fd;
+ Hashmap *h;
+
+ if (size < 0)
+ size = strlen(contents);
+
+ assert_se(h = hashmap_new(&catalog_hash_ops));
fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
assert_se(write(fd, contents, size) == size);
- r = catalog_import_file(h, sb, name);
+ r = catalog_import_file(h, name);
assert_se(r == code);
unlink(name);
-}
-static void test_catalog_importing(void) {
- Hashmap *h;
- struct strbuf *sb;
+ return h;
+}
- assert_se(h = hashmap_new(&catalog_hash_ops));
- assert_se(sb = strbuf_new());
+static void test_catalog_import_invalid(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
-#define BUF "xxx"
- test_import(h, sb, BUF, sizeof(BUF), -EINVAL);
-#undef BUF
+ h = test_import("xxx", -1, -EINVAL);
assert_se(hashmap_isempty(h));
- log_debug("----------------------------------------");
+}
-#define BUF \
+static void test_catalog_import_badid(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ const char *input =
"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \
"Subject: message\n" \
"\n" \
-"payload\n"
- test_import(h, sb, BUF, sizeof(BUF), -EINVAL);
-#undef BUF
+"payload\n";
+ h = test_import(input, -1, -EINVAL);
+}
- log_debug("----------------------------------------");
+static void test_catalog_import_one(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
-#define BUF \
+ const char *input =
"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
"Subject: message\n" \
"\n" \
-"payload\n"
- test_import(h, sb, BUF, sizeof(BUF), 0);
-#undef BUF
+"payload\n";
+ const char *expect =
+"Subject: message\n" \
+"\n" \
+"payload\n";
+ h = test_import(input, -1, 0);
assert_se(hashmap_size(h) == 1);
- log_debug("----------------------------------------");
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(expect, payload));
+ }
+}
- hashmap_free_free(h);
- strbuf_cleanup(sb);
+static void test_catalog_import_merge(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
+
+ const char *input =
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n" \
+"\n" \
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"\n" \
+"override payload\n";
+
+ const char *combined =
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"override payload\n";
+
+ h = test_import(input, -1, 0);
+ assert_se(hashmap_size(h) == 1);
+
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(combined, payload));
+ }
}
+static void test_catalog_import_merge_no_body(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
+
+ const char *input =
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n" \
+"\n" \
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"\n";
+
+ const char *combined =
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n";
+
+ h = test_import(input, -1, 0);
+ assert_se(hashmap_size(h) == 1);
+
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(combined, payload));
+ }
+}
static const char* database = NULL;
@@ -166,7 +240,11 @@ int main(int argc, char *argv[]) {
test_catalog_file_lang();
- test_catalog_importing();
+ test_catalog_import_invalid();
+ test_catalog_import_badid();
+ test_catalog_import_one();
+ test_catalog_import_merge();
+ test_catalog_import_merge_no_body();
test_catalog_update();
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 21cf161494..701b735a5d 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -1248,7 +1248,7 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsResourceRecord *nsec3) {
if (rr->key->type != DNS_TYPE_NSEC3)
return 0;
- /* RFC 5155, Section 8.2 says we MUST ignore NSEC3 RRs with flags != 0 or 1 */
+ /* RFC 5155, Section 8.2 says we MUST ignore NSEC3 RRs with flags != 0 or 1 */
if (!IN_SET(rr->nsec3.flags, 0, 1))
return 0;
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 5cbe20832f..0bf268398c 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -2170,7 +2170,7 @@ int dns_packet_extract(DnsPacket *p) {
}
if (!dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key))) {
- /* If the OPT RR qis not owned by the root domain, then it is bad, let's ignore
+ /* If the OPT RR is not owned by the root domain, then it is bad, let's ignore
* it. */
log_debug("OPT RR is not owned by root domain, ignoring.");
bad_opt = true;
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 783ec7516c..33e6f0014b 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -1450,7 +1450,7 @@ static int dns_resource_record_compare_func(const void *a, const void *b) {
if (dns_resource_record_equal(x, y))
return 0;
- /* This is a bit dirty, we don't implement proper odering, but
+ /* This is a bit dirty, we don't implement proper ordering, but
* the hashtable doesn't need ordering anyway, hence we don't
* care. */
return x < y ? -1 : 1;