X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fcatalog.c;h=3735ad9213d041712a7da91a56baf98b2ba4b799;hb=80701564cdd020318064f55c3f7c447df0b2cd24;hp=7be0d20f42a3c5a6ed387a2c906eb2ef0dad7823;hpb=d4205751d4643c272059a3728045929dd0e5e800;p=elogind.git diff --git a/src/journal/catalog.c b/src/journal/catalog.c index 7be0d20f4..3735ad921 100644 --- a/src/journal/catalog.c +++ b/src/journal/catalog.c @@ -50,14 +50,15 @@ typedef struct CatalogHeader { uint8_t signature[8]; /* "RHHHKSLP" */ le32_t compatible_flags; le32_t incompatible_flags; - le32_t header_size; - le32_t n_items; + le64_t header_size; + le64_t n_items; + le64_t catalog_item_size; } CatalogHeader; typedef struct CatalogItem { sd_id128_t id; char language[32]; - le32_t offset; + le64_t offset; } CatalogItem; static unsigned catalog_hash_func(const void *p) { @@ -117,18 +118,13 @@ static int finish_item( if (offset < 0) return log_oom(); - if (offset > 0xFFFFFFFF) { - log_error("Too many catalog entries."); - return -E2BIG; - } - i = new0(CatalogItem, 1); if (!i) return log_oom(); i->id = id; strncpy(i->language, language, sizeof(i->language)); - i->offset = htole32((uint32_t) offset); + i->offset = htole64((uint64_t) offset); r = hashmap_put(h, i, i); if (r == EEXIST) { @@ -273,6 +269,8 @@ static int import_file(Hashmap *h, struct strbuf *sb, const char *path) { return 0; } +#define CATALOG_DATABASE CATALOG_PATH "/database" + int catalog_update(void) { _cleanup_strv_free_ char **files = NULL; _cleanup_fclose_ FILE *w = NULL; @@ -313,7 +311,8 @@ int catalog_update(void) { log_info("No items in catalog."); r = 0; goto finish; - } + } else + log_debug("Found %u items in catalog.", hashmap_size(h)); strbuf_complete(sb); @@ -332,52 +331,61 @@ int catalog_update(void) { assert(n == hashmap_size(h)); qsort(items, n, sizeof(CatalogItem), catalog_compare_func); - mkdir_p("/var/lib/systemd/catalog", 0775); + r = mkdir_p(CATALOG_PATH, 0775); + if (r < 0) { + log_error("Recursive mkdir %s: %s", CATALOG_PATH, strerror(-r)); + goto finish; + } - r = fopen_temporary("/var/lib/systemd/catalog/database", &w, &p); + r = fopen_temporary(CATALOG_DATABASE, &w, &p); if (r < 0) { - log_error("Failed to open database for writing: %s", strerror(-r)); + log_error("Failed to open database for writing: %s: %s", + CATALOG_DATABASE, strerror(-r)); goto finish; } zero(header); memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature)); - header.header_size = htole32(ALIGN_TO(sizeof(CatalogHeader), 8)); - header.n_items = htole32(hashmap_size(h)); + header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8)); + header.catalog_item_size = htole64(sizeof(CatalogItem)); + header.n_items = htole64(hashmap_size(h)); k = fwrite(&header, 1, sizeof(header), w); if (k != sizeof(header)) { - log_error("Failed to write header."); + log_error("%s: failed to write header.", p); goto finish; } k = fwrite(items, 1, n * sizeof(CatalogItem), w); if (k != n * sizeof(CatalogItem)) { - log_error("Failed to write database."); + log_error("%s: failed to write database.", p); goto finish; } k = fwrite(sb->buf, 1, sb->len, w); if (k != sb->len) { - log_error("Failed to write strings."); + log_error("%s: failed to write strings.", p); goto finish; } fflush(w); if (ferror(w)) { - log_error("Failed to write database."); + log_error("%s: failed to write database.", p); goto finish; } fchmod(fileno(w), 0644); - if (rename(p, "/var/lib/systemd/catalog/database") < 0) { - log_error("rename() failed: %m"); + if (rename(p, CATALOG_DATABASE) < 0) { + log_error("rename (%s -> %s) failed: %m", p, CATALOG_DATABASE); r = -errno; goto finish; } + log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.", + CATALOG_DATABASE, n, sb->len, ftell(w)); + free(p); p = NULL; @@ -405,7 +413,7 @@ static int open_mmap(int *_fd, struct stat *_st, void **_p) { assert(_st); assert(_p); - fd = open("/var/lib/systemd/catalog/database", O_RDONLY|O_CLOEXEC); + fd = open(CATALOG_DATABASE, O_RDONLY|O_CLOEXEC); if (fd < 0) return -errno; @@ -427,10 +435,11 @@ static int open_mmap(int *_fd, struct stat *_st, void **_p) { h = p; if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 || - le32toh(h->header_size) < sizeof(CatalogHeader) || + le64toh(h->header_size) < sizeof(CatalogHeader) || + le64toh(h->catalog_item_size) < sizeof(CatalogItem) || h->incompatible_flags != 0 || - le32toh(h->n_items) <= 0 || - st.st_size < (off_t) (le32toh(h->header_size) + sizeof(CatalogItem) * le32toh(h->n_items))) { + le64toh(h->n_items) <= 0 || + st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) { close_nointr_nofail(fd); munmap(p, st.st_size); return -EBADMSG; @@ -456,30 +465,30 @@ static const char *find_id(void *p, sd_id128_t id) { strncpy(key.language, loc, sizeof(key.language)); key.language[strcspn(key.language, ".@")] = 0; - f = bsearch(&key, (const uint8_t*) p + le32toh(h->header_size), le32toh(h->n_items), sizeof(CatalogItem), catalog_compare_func); + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); if (!f) { char *e; e = strchr(key.language, '_'); if (e) { *e = 0; - f = bsearch(&key, (const uint8_t*) p + le32toh(h->header_size), le32toh(h->n_items), sizeof(CatalogItem), catalog_compare_func); + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); } } } if (!f) { zero(key.language); - f = bsearch(&key, (const uint8_t*) p + le32toh(h->header_size), le32toh(h->n_items), sizeof(CatalogItem), catalog_compare_func); + f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func); } if (!f) return NULL; return (const char*) p + - le32toh(h->header_size) + - le32toh(h->n_items) * sizeof(CatalogItem) + - le32toh(f->offset); + le64toh(h->header_size) + + le64toh(h->n_items) * le64toh(h->catalog_item_size) + + le64toh(f->offset); } int catalog_get(sd_id128_t id, char **_text) { @@ -558,9 +567,9 @@ int catalog_list(FILE *f) { return r; h = p; - items = (const CatalogItem*) ((const uint8_t*) p + le32toh(h->header_size)); + items = (const CatalogItem*) ((const uint8_t*) p + le64toh(h->header_size)); - for (n = 0; n < le32toh(h->n_items); n++) { + for (n = 0; n < le64toh(h->n_items); n++) { const char *s; _cleanup_free_ char *subject = NULL, *defined_by = NULL;