journal-upload-journal.c revision b5efdb8af40ea759a1ea584c1bc44ecc81dd00ce
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/***
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen This file is part of systemd.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Copyright 2014 Zbigniew Jędrzejewski-Szmek
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is free software; you can redistribute it and/or modify it
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen under the terms of the GNU Lesser General Public License as published by
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen (at your option) any later version.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen systemd is distributed in the hope that it will be useful, but
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Lesser General Public License for more details.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen You should have received a copy of the GNU Lesser General Public License
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen***/
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include <stdbool.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include <curl/curl.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "alloc-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "journal-upload.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "log.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "utf8.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen#include "util.h"
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen/**
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen * Write up to size bytes to buf. Return negative on error, and number of
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering * bytes written otherwise. The last case is a kind of an error too.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering */
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic ssize_t write_entry(char *buf, size_t size, Uploader *u) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen size_t pos = 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(size <= SSIZE_MAX);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen for (;;) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen switch(u->entry_state) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_CURSOR: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->current_cursor = mfree(u->current_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_cursor(u->journal, &u->current_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get cursor: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = snprintf(buf + pos, size - pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "__CURSOR=%s\n", u->current_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (pos + r > size)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (pos + r == size) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[size - 1] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return size;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_REALTIME: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen usec_t realtime;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_realtime_usec(u->journal, &realtime);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get realtime timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = snprintf(buf + pos, size - pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos > size)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos == size) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[size - 1] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return size;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_MONOTONIC: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen usec_t monotonic;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_id128_t boot_id;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get monotonic timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = snprintf(buf + pos, size - pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos > size)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos == size) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[size - 1] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return size;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_BOOT_ID: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_id128_t boot_id;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen char sid[33];
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to get monotonic timestamp: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = snprintf(buf + pos, size - pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos > size)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* not enough space */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r + pos == size) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* exactly one character short, but we don't need it */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[size - 1] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return size;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_NEW_FIELD: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->field_pos = 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_enumerate_data(u->journal,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen &u->field_data,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen &u->field_length);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to move to next field in entry: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else if (r == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state = ENTRY_OUTRO;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen continue;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!utf8_is_printable_newline(u->field_data,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->field_length, false)) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state = ENTRY_BINARY_FIELD_START;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen continue;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_TEXT_FIELD:
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_BINARY_FIELD: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen bool done;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen size_t tocopy;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen done = size - pos > u->field_length - u->field_pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (done)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen tocopy = u->field_length - u->field_pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen tocopy = size - pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen memcpy(buf + pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen (char*) u->field_data + u->field_pos,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen tocopy);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (done) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[pos + tocopy] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += tocopy + 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state = ENTRY_NEW_FIELD;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen continue;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->field_pos += tocopy;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return size;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_BINARY_FIELD_START: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *c;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen size_t len;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen c = memchr(u->field_data, '=', u->field_length);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (!c || c == u->field_data) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error("Invalid field.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return -EINVAL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen len = c - (const char*)u->field_data;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for label + '\n' */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (size - pos < len + 1)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen memcpy(buf + pos, u->field_data, len);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[pos + len] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += len + 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->field_pos = len + 1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } /* fall through */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_BINARY_FIELD_SIZE: {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen uint64_t le64;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for uint64_t */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (size - pos < 8)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen le64 = htole64(u->field_length - u->field_pos);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen memcpy(buf + pos, &le64, 8);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen pos += 8;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen continue;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen case ENTRY_OUTRO:
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* need space for '\n' */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (size - pos < 1)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen buf[pos++] = '\n';
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entries_sent ++;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return pos;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen default:
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert_not_reached("WTF?");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert_not_reached("WTF?");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Uploader *u = userp;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_journal *j;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen size_t filled = 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen ssize_t w;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(nmemb <= SSIZE_MAX / size);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen j = u->journal;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen while (j && filled < size * nmemb) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (u->entry_state == ENTRY_DONE) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_next(j);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error_errno(r, "Failed to move to next entry in journal: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return CURL_READFUNC_ABORT;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else if (r == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (u->input_event)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("No more entries, waiting for journal.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_info("No more entries, closing journal.");
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering close_journal_input(u);
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering }
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->uploading = false;
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen break;
52efd56a6369e19c2400a42981a197cd2eef924aLennart Poettering }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state = ENTRY_CURSOR;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen w = write_entry((char*)buf + filled, size * nmemb - filled, u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (w < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return CURL_READFUNC_ABORT;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen filled += w;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (filled == 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error("Buffer space is too small to write entry.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return CURL_READFUNC_ABORT;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else if (u->entry_state != ENTRY_DONE)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* This means that all available space was used up */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen break;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Entry %zu (%s) has been uploaded.",
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entries_sent, u->current_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return filled;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenvoid close_journal_input(Uploader *u) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (u->journal) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Closing journal input.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_journal_close(u->journal);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->journal = NULL;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->timeout = 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int process_journal_input(Uploader *u, int skip) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_next_skip(u->journal, skip);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to skip to next entry: %m");
7e518afab9fb55b8052f68888210927259275560Thomas Hindoe Paaboel Andersen else if (r < skip)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen /* have data */
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->entry_state = ENTRY_CURSOR;
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek return start_upload(u, journal_input_callback, u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint check_journal_input(Uploader *u) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (u->input_event) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_process(u->journal);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_error_errno(r, "Failed to process journal: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen close_journal_input(u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return r;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r == SD_JOURNAL_NOP)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return process_journal_input(u, 1);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
f0c4b1c3fd827b429ba36aa45fd39e0a023cbf2cTom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenstatic int dispatch_journal_input(sd_event_source *event,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int fd,
74ca738f6a01fb5fc19c5c3899f5cb1fdc1d7f68Lennart Poettering uint32_t revents,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen void *userp) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen Uploader *u = userp;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (u->uploading) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_warning("dispatch_journal_input called when uploading, ignoring.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return 0;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Detected journal input, checking for new data.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return check_journal_input(u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersenint open_journal_for_upload(Uploader *u,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_journal *j,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen const char *cursor,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen bool after_cursor,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen bool follow) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen int fd, r, events;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->journal = j;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen sd_journal_set_data_threshold(j, 0);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (follow) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd = sd_journal_get_fd(j);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (fd < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(fd, "sd_journal_get_fd failed: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen events = sd_journal_get_events(j);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_reliable_fd(j);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen assert(r >= 0);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r > 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->timeout = -1;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen else
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_event_add_io(u->events, &u->input_event,
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd, events, dispatch_journal_input, u);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to register input event: %m");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Listening for journal events on fd:%d, timeout %d",
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen } else
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen log_debug("Not listening for journal events.");
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (cursor) {
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen r = sd_journal_seek_cursor(j, cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen if (r < 0)
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return log_error_errno(r, "Failed to seek to cursor %s: %m",
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen }
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen return process_journal_input(u, 1 + !!after_cursor);
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen}
23fbe14f503c1e98292efc4ba1238adb7dc38d80Tom Gundersen