journal-upload-journal.c revision 8a3db16df40c1bbcb1d1debc80fbf92339503235
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2014 Zbigniew Jędrzejewski-Szmek
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include <curl/curl.h>
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include <stdbool.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens#include "alloc-util.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "journal-upload.h"
51323288fc628a5cac50914df915545d685b793eLennart Poettering#include "log.h"
3abaabdab73bd0f3e4f68284dc3cb00902b8e1c6Lennart Poettering#include "utf8.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "util.h"
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering/**
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering * Write up to size bytes to buf. Return negative on error, and number of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * bytes written otherwise. The last case is a kind of an error too.
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering */
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poetteringstatic ssize_t write_entry(char *buf, size_t size, Uploader *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering size_t pos = 0;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(size <= SSIZE_MAX);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering for (;;) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering switch(u->entry_state) {
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering case ENTRY_CURSOR: {
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering u->current_cursor = mfree(u->current_cursor);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_journal_get_cursor(u->journal, &u->current_cursor);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering return log_error_errno(r, "Failed to get cursor: %m");
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = snprintf(buf + pos, size - pos,
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering "__CURSOR=%s\n", u->current_cursor);
a761c1ca851a9397b5a207ef600e077d0f7f4534Lennart Poettering if (pos + r > size)
019036a47fcd10fcf0286800d144c706f3773e2fLennart Poettering /* not enough space */
547973dea7abd6c124ff6c79fe2bbe322a7314aeLennart Poettering return pos;
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering u->entry_state ++;
b2b796b8ab5565fbe60b544d2579e2bfca31bf6aLennart Poettering
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering if (pos + r == size) {
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering /* exactly one character short, but we don't need it */
91adc4db33f69606aabd332813a5d7d5751c859fLennart Poettering buf[size - 1] = '\n';
edbcc1fdd94355c5cf22263ba2c1cfa4ec2eb010Lennart Poettering return size;
edbcc1fdd94355c5cf22263ba2c1cfa4ec2eb010Lennart Poettering }
edbcc1fdd94355c5cf22263ba2c1cfa4ec2eb010Lennart Poettering
3bbdc31df37a23b5134a115c01d15e7ff870b3ccLennart Poettering pos += r;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering } /* fall through */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering case ENTRY_REALTIME: {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering usec_t realtime;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_journal_get_realtime_usec(u->journal, &realtime);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to get realtime timestamp: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = snprintf(buf + pos, size - pos,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r + pos > size)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* not enough space */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return pos;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering u->entry_state ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r + pos == size) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering /* exactly one character short, but we don't need it */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering buf[size - 1] = '\n';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return size;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ef9fb66c0b292d3543c16bfce99ad677bef0f401Lennart Poettering pos += r;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering } /* fall through */
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering case ENTRY_MONOTONIC: {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering usec_t monotonic;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering sd_id128_t boot_id;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return log_error_errno(r, "Failed to get monotonic timestamp: %m");
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = snprintf(buf + pos, size - pos,
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r + pos > size)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* not enough space */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return pos;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering u->entry_state ++;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r + pos == size) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering /* exactly one character short, but we don't need it */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering buf[size - 1] = '\n';
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return size;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering }
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering pos += r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering } /* fall through */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering case ENTRY_BOOT_ID: {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering sd_id128_t boot_id;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering char sid[33];
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return log_error_errno(r, "Failed to get monotonic timestamp: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering r = snprintf(buf + pos, size - pos,
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r + pos > size)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering /* not enough space */
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return pos;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering u->entry_state ++;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r + pos == size) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering /* exactly one character short, but we don't need it */
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering buf[size - 1] = '\n';
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return size;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering pos += r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering } /* fall through */
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case ENTRY_NEW_FIELD: {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering u->field_pos = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = sd_journal_enumerate_data(u->journal,
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering &u->field_data,
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering &u->field_length);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to move to next field in entry: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering else if (r == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->entry_state = ENTRY_OUTRO;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!utf8_is_printable_newline(u->field_data,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->field_length, false)) {
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen u->entry_state = ENTRY_BINARY_FIELD_START;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering u->entry_state ++;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering } /* fall through */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering case ENTRY_TEXT_FIELD:
51323288fc628a5cac50914df915545d685b793eLennart Poettering case ENTRY_BINARY_FIELD: {
51323288fc628a5cac50914df915545d685b793eLennart Poettering bool done;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering size_t tocopy;
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering done = size - pos > u->field_length - u->field_pos;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (done)
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering tocopy = u->field_length - u->field_pos;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering else
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering tocopy = size - pos;
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering memcpy(buf + pos,
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering (char*) u->field_data + u->field_pos,
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering tocopy);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering if (done) {
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering buf[pos + tocopy] = '\n';
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering pos += tocopy + 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->entry_state = ENTRY_NEW_FIELD;
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering continue;
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering } else {
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering u->field_pos += tocopy;
ce736ace37399f3dc45e6981852881a6f2448de2Lennart Poettering return size;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering case ENTRY_BINARY_FIELD_START: {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering const char *c;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t len;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering c = memchr(u->field_data, '=', u->field_length);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (!c || c == u->field_data) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_error("Invalid field.");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return -EINVAL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering len = c - (const char*)u->field_data;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* need space for label + '\n' */
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering if (size - pos < len + 1)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return pos;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering memcpy(buf + pos, u->field_data, len);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering buf[pos + len] = '\n';
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering pos += len + 1;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering u->field_pos = len + 1;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt u->entry_state ++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering } /* fall through */
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case ENTRY_BINARY_FIELD_SIZE: {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint64_t le64;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* need space for uint64_t */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (size - pos < 8)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return pos;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering le64 = htole64(u->field_length - u->field_pos);
51323288fc628a5cac50914df915545d685b793eLennart Poettering memcpy(buf + pos, &le64, 8);
51323288fc628a5cac50914df915545d685b793eLennart Poettering pos += 8;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering u->entry_state ++;
51323288fc628a5cac50914df915545d685b793eLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering case ENTRY_OUTRO:
51323288fc628a5cac50914df915545d685b793eLennart Poettering /* need space for '\n' */
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (size - pos < 1)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return pos;
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering buf[pos++] = '\n';
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->entry_state ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->entries_sent ++;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering return pos;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering default:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_not_reached("WTF?");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_not_reached("WTF?");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poetteringstatic size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Uploader *u = userp;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_journal *j;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t filled = 0;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering ssize_t w;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(u);
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering assert(nmemb <= SSIZE_MAX / size);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering j = u->journal;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering while (j && filled < size * nmemb) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering if (u->entry_state == ENTRY_DONE) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_journal_next(j);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering log_error_errno(r, "Failed to move to next entry in journal: %m");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return CURL_READFUNC_ABORT;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering } else if (r == 0) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (u->input_event)
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering log_debug("No more entries, waiting for journal.");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering else {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_info("No more entries, closing journal.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering close_journal_input(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->uploading = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering break;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->entry_state = ENTRY_CURSOR;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
966c66e34940001a40806142ecebaae61b478444Lennart Poettering
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering w = write_entry((char*)buf + filled, size * nmemb - filled, u);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (w < 0)
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering return CURL_READFUNC_ABORT;
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering filled += w;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (filled == 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Buffer space is too small to write entry.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return CURL_READFUNC_ABORT;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering } else if (u->entry_state != ENTRY_DONE)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This means that all available space was used up */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Entry %zu (%s) has been uploaded.",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->entries_sent, u->current_cursor);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return filled;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringvoid close_journal_input(Uploader *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (u->journal) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering log_debug("Closing journal input.");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering sd_journal_close(u->journal);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering u->journal = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen u->timeout = 0;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen}
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersenstatic int process_journal_input(Uploader *u, int skip) {
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen int r;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen if (u->uploading)
7588460aaf6bd33f6c9bd5645916cfd8a862e9c4Tom Gundersen return 0;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_journal_next_skip(u->journal, skip);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return log_error_errno(r, "Failed to skip to next entry: %m");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering else if (r < skip)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering /* have data */
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering u->entry_state = ENTRY_CURSOR;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return start_upload(u, journal_input_callback, u);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poetteringint check_journal_input(Uploader *u) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (u->input_event) {
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering int r;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering r = sd_journal_process(u->journal);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error_errno(r, "Failed to process journal: %m");
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering close_journal_input(u);
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering return r;
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering }
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering
23b298bce75a0d1f4f15f34458af9678b4a30c3aLennart Poettering if (r == SD_JOURNAL_NOP)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return process_journal_input(u, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int dispatch_journal_input(sd_event_source *event,
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering int fd,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering uint32_t revents,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering void *userp) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering Uploader *u = userp;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering assert(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
931851e8e492a4d2715e22dcde50a5e7ccef4b49Lennart Poettering if (u->uploading)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return 0;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering log_debug("Detected journal input, checking for new data.");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return check_journal_input(u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringint open_journal_for_upload(Uploader *u,
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt sd_journal *j,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering const char *cursor,
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering bool after_cursor,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering bool follow) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int fd, r, events;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering u->journal = j;
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering sd_journal_set_data_threshold(j, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (follow) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering fd = sd_journal_get_fd(j);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (fd < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(fd, "sd_journal_get_fd failed: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering events = sd_journal_get_events(j);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_journal_reliable_fd(j);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(r >= 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r > 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering u->timeout = -1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering else
51323288fc628a5cac50914df915545d685b793eLennart Poettering u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_event_add_io(u->events, &u->input_event,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fd, events, dispatch_journal_input, u);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return log_error_errno(r, "Failed to register input event: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Listening for journal events on fd:%d, timeout %d",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Not listening for journal events.");
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (cursor) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_journal_seek_cursor(j, cursor);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return log_error_errno(r, "Failed to seek to cursor %s: %m",
51323288fc628a5cac50914df915545d685b793eLennart Poettering cursor);
51323288fc628a5cac50914df915545d685b793eLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return process_journal_input(u, 1 + !!after_cursor);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering}
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering