catalog.c revision 4b8268f843b0da1cfe1995d93a0b1f95faccc454
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering/***
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering This file is part of systemd.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Copyright 2012 Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering systemd is free software; you can redistribute it and/or modify it
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering under the terms of the GNU Lesser General Public License as published by
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (at your option) any later version.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering systemd is distributed in the hope that it will be useful, but
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Lesser General Public License for more details.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering You should have received a copy of the GNU Lesser General Public License
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering***/
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <fcntl.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <stdio.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <unistd.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <errno.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <string.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <sys/mman.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include <locale.h>
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek#include <libgen.h>
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "util.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "log.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "sparse-endian.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "sd-id128.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "hashmap.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "strv.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "strbuf.h"
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek#include "strxcpyx.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "conf-files.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "mkdir.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#include "catalog.h"
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekconst char * const catalog_file_dirs[] = {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering "/usr/local/lib/systemd/catalog/",
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering "/usr/lib/systemd/catalog/",
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering NULL
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering};
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define CATALOG_SIGNATURE (uint8_t[]) { 'R', 'H', 'H', 'H', 'K', 'S', 'L', 'P' }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringtypedef struct CatalogHeader {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering uint8_t signature[8]; /* "RHHHKSLP" */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering le32_t compatible_flags;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering le32_t incompatible_flags;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64_t header_size;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64_t n_items;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64_t catalog_item_size;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering} CatalogHeader;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringtypedef struct CatalogItem {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_t id;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char language[32];
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64_t offset;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering} CatalogItem;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekunsigned catalog_hash_func(const void *p) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogItem *i = p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert_cc(sizeof(unsigned) == sizeof(uint8_t)*4);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return (((unsigned) i->id.bytes[0] << 24) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[1] << 16) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[2] << 8) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[3])) ^
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (((unsigned) i->id.bytes[4] << 24) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[5] << 16) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[6] << 8) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[7])) ^
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (((unsigned) i->id.bytes[8] << 24) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[9] << 16) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[10] << 8) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[11])) ^
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (((unsigned) i->id.bytes[12] << 24) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[13] << 16) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[14] << 8) |
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ((unsigned) i->id.bytes[15])) ^
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering string_hash_func(i->language);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_compare_func(const void *a, const void *b) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogItem *i = a, *j = b;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering unsigned k;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering for (k = 0; k < ELEMENTSOF(j->id.bytes); k++) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (i->id.bytes[k] < j->id.bytes[k])
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (i->id.bytes[k] > j->id.bytes[k])
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek return strcmp(i->language, j->language);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic int finish_item(
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Hashmap *h,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct strbuf *sb,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_t id,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *language,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *payload) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ssize_t offset;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering CatalogItem *i;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering int r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(h);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(sb);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(payload);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering offset = strbuf_add_string(sb, payload, strlen(payload));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (offset < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return log_oom();
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering i = new0(CatalogItem, 1);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!i)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return log_oom();
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering i->id = id;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (language) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek assert(strlen(language) > 1 && strlen(language) < 32);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek strcpy(i->language, language);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek }
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering i->offset = htole64((uint64_t) offset);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = hashmap_put(h, i, i);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r == EEXIST) {
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.",
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek SD_ID128_FORMAT_VAL(id), language ? language : "C");
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering free(i);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmekint catalog_file_lang(const char* filename, char **lang) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek char *beg, *end, *_lang;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek end = endswith(filename, ".catalog");
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (!end)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return 0;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek beg = end - 1;
4b8268f843b0da1cfe1995d93a0b1f95faccc454Zbigniew Jędrzejewski-Szmek while (beg > filename && *beg != '.' && *beg != '/' && end - beg < 32)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek beg --;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
4b8268f843b0da1cfe1995d93a0b1f95faccc454Zbigniew Jędrzejewski-Szmek if (*beg != '.' || end <= beg + 1)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return 0;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek _lang = strndup(beg + 1, end - beg - 1);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (!_lang)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return -ENOMEM;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek *lang = _lang;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return 1;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek}
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_free_ char *payload = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering unsigned n = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_t id;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *deflang = NULL, *lang = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering bool got_id = false, empty_line = true;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering int r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(h);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(sb);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering f = fopen(path, "re");
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!f) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("Failed to open file %s: %m", path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -errno;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek r = catalog_file_lang(path, &deflang);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (r < 0)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek log_error("Failed to determine language for file %s: %m", path);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (r == 1)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek log_debug("File %s has language %s.", path, deflang);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering for (;;) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char line[LINE_MAX];
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering size_t a, b, c;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char *t;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!fgets(line, sizeof(line), f)) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (feof(f))
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering break;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("Failed to read file %s: %m", path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -errno;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering n++;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering truncate_nl(line);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (line[0] == 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering empty_line = true;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering continue;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d3b6d0c21ea5a0d15ec6dbd8b8d179138b7463bcZbigniew Jędrzejewski-Szmek if (strchr(COMMENTS "\n", line[0]))
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering continue;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (empty_line &&
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering strlen(line) >= 2+1+32 &&
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering line[0] == '-' &&
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering line[1] == '-' &&
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering line[2] == ' ' &&
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek (line[2+1+32] == ' ' || line[2+1+32] == '\0')) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering bool with_language;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_t jd;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* New entry */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek with_language = line[2+1+32] != '\0';
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek line[2+1+32] = '\0';
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (got_id) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek r = finish_item(h, sb, id, lang ?: deflang, payload);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return r;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek free(lang);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek lang = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (with_language) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t = strstrip(line + 2 + 1 + 32 + 1);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering c = strlen(t);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (c <= 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("[%s:%u] Language too short.", path, n);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -EINVAL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (c > 31) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("[%s:%u] language too long.", path, n);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -EINVAL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (deflang) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek log_warning("[%s:%u] language %s", path, n,
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek streq(t, deflang) ?
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek "specified unnecessarily" :
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek "differs from default for file");
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek lang = strdup(t);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek if (!lang)
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return -ENOMEM;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek }
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering got_id = true;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering empty_line = false;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering id = jd;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (payload)
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek payload[0] = '\0';
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering continue;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* Payload */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!got_id) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("[%s:%u] Got payload before ID.", path, n);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -EINVAL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering a = payload ? strlen(payload) : 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering b = strlen(line);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering c = a + (empty_line ? 1 : 0) + b + 1 + 1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t = realloc(payload, c);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!t)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return log_oom();
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (empty_line) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t[a] = '\n';
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering memcpy(t + a + 1, line, b);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t[a+b+1] = '\n';
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t[a+b+2] = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering } else {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering memcpy(t + a, line, b);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t[a+b] = '\n';
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering t[a+b+1] = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering payload = t;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering empty_line = false;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (got_id) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek r = finish_item(h, sb, id, lang ?: deflang, payload);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekstatic long write_catalog(const char *database, Hashmap *h, struct strbuf *sb,
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek CatalogItem *items, size_t n) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek CatalogHeader header;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *w = NULL;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek int r;
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer _cleanup_free_ char *d, *p = NULL;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek size_t k;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek d = dirname_malloc(database);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (!d)
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return log_oom();
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = mkdir_p(d, 0775);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (r < 0) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("Recursive mkdir %s: %s", d, strerror(-r));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return r;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = fopen_temporary(database, &w, &p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (r < 0) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("Failed to open database for writing: %s: %s",
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek database, strerror(-r));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return r;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek zero(header);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek memcpy(header.signature, CATALOG_SIGNATURE, sizeof(header.signature));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek header.header_size = htole64(ALIGN_TO(sizeof(CatalogHeader), 8));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek header.catalog_item_size = htole64(sizeof(CatalogItem));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek header.n_items = htole64(hashmap_size(h));
80343dc19a9bcd703275ad2ad88f43e5310559d6Zbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = -EIO;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek k = fwrite(&header, 1, sizeof(header), w);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (k != sizeof(header)) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("%s: failed to write header.", p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek goto error;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek k = fwrite(items, 1, n * sizeof(CatalogItem), w);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (k != n * sizeof(CatalogItem)) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("%s: failed to write database.", p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek goto error;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek k = fwrite(sb->buf, 1, sb->len, w);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (k != sb->len) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("%s: failed to write strings.", p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek goto error;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek fflush(w);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (ferror(w)) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("%s: failed to write database.", p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek goto error;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek fchmod(fileno(w), 0644);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (rename(p, database) < 0) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("rename (%s -> %s) failed: %m", p, database);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = -errno;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek goto error;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek }
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return ftell(w);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekerror:
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek unlink(p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return r;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek}
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_update(const char* database, const char* root, const char* const* dirs) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_strv_free_ char **files = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char **f;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Hashmap *h;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct strbuf *sb = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_free_ CatalogItem *items = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering CatalogItem *i;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Iterator j;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering unsigned n;
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek long r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering h = hashmap_new(catalog_hash_func, catalog_compare_func);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sb = strbuf_new();
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (!h || !sb) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = log_oom();
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = conf_files_list_strv(&files, ".catalog", root, dirs);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r < 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error("Failed to get catalog files: %s", strerror(-r));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering STRV_FOREACH(f, files) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_debug("reading file '%s'", *f);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek catalog_import_file(h, sb, *f);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (hashmap_size(h) <= 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_info("No items in catalog.");
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
80343dc19a9bcd703275ad2ad88f43e5310559d6Zbigniew Jędrzejewski-Szmek } else
80343dc19a9bcd703275ad2ad88f43e5310559d6Zbigniew Jędrzejewski-Szmek log_debug("Found %u items in catalog.", hashmap_size(h));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering strbuf_complete(sb);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering items = new(CatalogItem, hashmap_size(h));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!items) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = log_oom();
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering n = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering HASHMAP_FOREACH(i, h, j) {
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek log_debug("Found " SD_ID128_FORMAT_STR ", language %s",
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek SD_ID128_FORMAT_VAL(i->id),
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek isempty(i->language) ? "C" : i->language);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering items[n++] = *i;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(n == hashmap_size(h));
7ff7394d9e4e9189c30fd018235e6b1728c6f2d0Zbigniew Jędrzejewski-Szmek qsort_safe(items, n, sizeof(CatalogItem), catalog_compare_func);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = write_catalog(database, h, sb, items, n);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (r < 0)
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error("Failed to write %s: %s", database, strerror(-r));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek else
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_debug("%s: wrote %u items, with %zu bytes of strings, %ld total size.",
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek database, n, sb->len, r);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringfinish:
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (h)
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek hashmap_free_free(h);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (sb)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering strbuf_cleanup(sb);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek return r < 0 ? r : 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekstatic int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogHeader *h;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering int fd;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering void *p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct stat st;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(_fd);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(_st);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(_p);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek fd = open(database, O_RDONLY|O_CLOEXEC);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (fd < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -errno;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (fstat(fd, &st) < 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering close_nointr_nofail(fd);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -errno;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (st.st_size < (off_t) sizeof(CatalogHeader)) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering close_nointr_nofail(fd);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -EINVAL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering p = mmap(NULL, PAGE_ALIGN(st.st_size), PROT_READ, MAP_SHARED, fd, 0);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (p == MAP_FAILED) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering close_nointr_nofail(fd);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -errno;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering h = p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (memcmp(h->signature, CATALOG_SIGNATURE, sizeof(h->signature)) != 0 ||
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(h->header_size) < sizeof(CatalogHeader) ||
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(h->catalog_item_size) < sizeof(CatalogItem) ||
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering h->incompatible_flags != 0 ||
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(h->n_items) <= 0 ||
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering st.st_size < (off_t) (le64toh(h->header_size) + le64toh(h->catalog_item_size) * le64toh(h->n_items))) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering close_nointr_nofail(fd);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering munmap(p, st.st_size);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return -EBADMSG;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering *_fd = fd;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering *_st = st;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering *_p = p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic const char *find_id(void *p, sd_id128_t id) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering CatalogItem key, *f = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogHeader *h = p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *loc;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering zero(key);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering key.id = id;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering loc = setlocale(LC_MESSAGES, NULL);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (loc && loc[0] && !streq(loc, "C") && !streq(loc, "POSIX")) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering strncpy(key.language, loc, sizeof(key.language));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering key.language[strcspn(key.language, ".@")] = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!f) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char *e;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering e = strchr(key.language, '_');
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (e) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering *e = 0;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!f) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering zero(key.language);
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering f = bsearch(&key, (const uint8_t*) p + le64toh(h->header_size), le64toh(h->n_items), le64toh(h->catalog_item_size), catalog_compare_func);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!f)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return (const char*) p +
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(h->header_size) +
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(h->n_items) * le64toh(h->catalog_item_size) +
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering le64toh(f->offset);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_get(const char* database, sd_id128_t id, char **_text) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_close_ int fd = -1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering void *p = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct stat st;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char *text = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering int r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *s;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(_text);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = open_mmap(database, &fd, &st, &p);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering s = find_id(p, id);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!s) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = -ENOENT;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering text = strdup(s);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!text) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = -ENOMEM;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering goto finish;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering *_text = text;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringfinish:
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (p)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering munmap(p, st.st_size);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic char *find_header(const char *s, const char *header) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering for (;;) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *v, *e;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering v = startswith(s, header);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (v) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering v += strspn(v, WHITESPACE);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return strndup(v, strcspn(v, NEWLINE));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* End of text */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering e = strchr(s, '\n');
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!e)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* End of header */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (e == s)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering s = e + 1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmekstatic void dump_catalog_entry(FILE *f, sd_id128_t id, const char *s, bool oneline) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek if (oneline) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *subject = NULL, *defined_by = NULL;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek subject = find_header(s, "Subject:");
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek defined_by = find_header(s, "Defined-By:");
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek fprintf(f, SD_ID128_FORMAT_STR " %s: %s\n",
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek SD_ID128_FORMAT_VAL(id),
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek strna(defined_by), strna(subject));
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek } else
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek fprintf(f, "-- " SD_ID128_FORMAT_STR "\n%s\n",
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek SD_ID128_FORMAT_VAL(id), s);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek}
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_list(FILE *f, const char *database, bool oneline) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering _cleanup_close_ int fd = -1;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering void *p = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct stat st;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogHeader *h;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const CatalogItem *items;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering int r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering unsigned n;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_t last_id;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering bool last_id_set = false;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = open_mmap(database, &fd, &st, &p);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (r < 0)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return r;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering h = p;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering items = (const CatalogItem*) ((const uint8_t*) p + le64toh(h->header_size));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering for (n = 0; n < le64toh(h->n_items); n++) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *s;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (last_id_set && sd_id128_equal(last_id, items[n].id))
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering continue;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert_se(s = find_id(p, items[n].id));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek dump_catalog_entry(f, items[n].id, s, oneline);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering last_id_set = true;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering last_id = items[n].id;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering }
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering munmap(p, st.st_size);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return 0;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering}
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint catalog_list_items(FILE *f, const char *database, bool oneline, char **items) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek char **item;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek int r = 0;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek STRV_FOREACH(item, items) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sd_id128_t id;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek int k;
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer _cleanup_free_ char *msg = NULL;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek k = sd_id128_from_string(*item, &id);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek if (k < 0) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek log_error("Failed to parse id128 '%s': %s",
2e8fb7026d3c560194cfe9f83935ce0b16263da0Lukas Nykryn *item, strerror(-k));
464264ac5a35b655065c5d95b8d8ffbbc7ff3bcfLukas Nykryn if (r == 0)
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = k;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek continue;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek }
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek k = catalog_get(database, id, &msg);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek if (k < 0) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek log_full(k == -ENOENT ? LOG_NOTICE : LOG_ERR,
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek "Failed to retrieve catalog entry for '%s': %s",
2e8fb7026d3c560194cfe9f83935ce0b16263da0Lukas Nykryn *item, strerror(-k));
464264ac5a35b655065c5d95b8d8ffbbc7ff3bcfLukas Nykryn if (r == 0)
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = k;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek continue;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek }
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek dump_catalog_entry(f, id, msg, oneline);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek }
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek return r;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek}