diff options
Diffstat (limited to 'src/journal/catalog.c')
-rw-r--r-- | src/journal/catalog.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 90ca008064..2be81aa2f7 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -125,7 +125,10 @@ static int finish_item( return log_oom(); i->id = id; - strscpy(i->language, sizeof(i->language), language); + if (language) { + assert(strlen(language) > 1 && strlen(language) < 32); + strcpy(i->language, language); + } i->offset = htole64((uint64_t) offset); r = hashmap_put(h, i, i); @@ -139,12 +142,34 @@ static int finish_item( return 0; } +int catalog_file_lang(const char* filename, char **lang) { + char *beg, *end, *_lang; + + end = endswith(filename, ".catalog"); + if (!end) + return 0; + + beg = end - 1; + while (beg > filename && *beg != '.') + beg --; + + if (beg <= filename || end <= beg + 1 || end - beg > 32) + return 0; + + _lang = strndup(beg + 1, end - beg - 1); + if (!_lang) + return -ENOMEM; + + *lang = _lang; + return 1; +} + int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *payload = NULL; unsigned n = 0; sd_id128_t id; - char language[32]; + _cleanup_free_ char *deflang = NULL, *lang = NULL; bool got_id = false, empty_line = true; int r; @@ -158,6 +183,12 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { return -errno; } + r = catalog_file_lang(path, &deflang); + if (r < 0) + log_error("Failed to determine language for file %s: %m", path); + if (r == 1) + log_debug("File %s has language %s.", path, deflang); + for (;;) { char line[LINE_MAX]; size_t a, b, c; @@ -201,9 +232,12 @@ 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, language, payload); + r = finish_item(h, sb, id, lang ?: deflang, payload); if (r < 0) return r; + + free(lang); + lang = NULL; } if (with_language) { @@ -214,14 +248,21 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { log_error("[%s:%u] Language too short.", path, n); return -EINVAL; } - if (c > sizeof(language) - 1) { + if (c > 31) { log_error("[%s:%u] language too long.", path, n); return -EINVAL; } - strscpy(language, sizeof(language), t); - } else - language[0] = '\0'; + if (deflang) { + log_warning("[%s:%u] language %s", path, n, + streq(t, deflang) ? + "specified unnecessarily" : + "differs from default for file"); + lang = strdup(t); + if (!lang) + return -ENOMEM; + } + } got_id = true; empty_line = false; @@ -264,7 +305,7 @@ int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) { } if (got_id) { - r = finish_item(h, sb, id, language, payload); + r = finish_item(h, sb, id, lang ?: deflang, payload); if (r < 0) return r; } |