journal-upload-journal.c revision c33b329709ebe2755181980a050d02ec7c81ed87
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <stdbool.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <curl/curl.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "util.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "log.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "utf8.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "journal-upload.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/**
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering * Write up to size bytes to buf. Return negative on error, and number of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering * bytes written otherwise. The last case is a kind of an error too.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic ssize_t write_entry(char *buf, size_t size, Uploader *u) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering int r;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering size_t pos = 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(size <= SSIZE_MAX);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
b4bbcaa9c44260e88402cb8f9a5fb8ac7f35e123Thomas Hindoe Paaboel Andersen while (true) {
b4bbcaa9c44260e88402cb8f9a5fb8ac7f35e123Thomas Hindoe Paaboel Andersen
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering switch(u->entry_state) {
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering case ENTRY_CURSOR: {
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering free(u->current_cursor);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->current_cursor = NULL;
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering r = sd_journal_get_cursor(u->journal, &u->current_cursor);
4e731273edfe852a3eee2949cd20f49fd5b4f6d7Lennart Poettering if (r < 0) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering log_error_errno(r, "Failed to get cursor: %m");
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return r;
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = snprintf(buf + pos, size - pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "__CURSOR=%s\n", u->current_cursor);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (pos + r > size)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* not enough space */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (pos + r == size) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* exactly one character short, but we don't need it */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[size - 1] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return size;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_REALTIME: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering usec_t realtime;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_get_realtime_usec(u->journal, &realtime);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to get realtime timestamp: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = snprintf(buf + pos, size - pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos > size)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* not enough space */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos == size) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* exactly one character short, but we don't need it */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[size - 1] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return size;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
39883f622f392d8579f4428fc5a789a102efbb10Lennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek case ENTRY_MONOTONIC: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering usec_t monotonic;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_id128_t boot_id;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to get monotonic timestamp: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = snprintf(buf + pos, size - pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos > size)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* not enough space */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos == size) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* exactly one character short, but we don't need it */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[size - 1] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return size;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_BOOT_ID: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_id128_t boot_id;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char sid[33];
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to get monotonic timestamp: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = snprintf(buf + pos, size - pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid));
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos> size)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* not enough space */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos == size) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* exactly one character short, but we don't need it */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[size - 1] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return size;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_NEW_FIELD: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->field_pos = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_enumerate_data(u->journal,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering &u->field_data,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering &u->field_length);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to move to next field in entry: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else if (r == 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state = ENTRY_OUTRO;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering continue;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!utf8_is_printable_newline(u->field_data,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->field_length, false)) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state = ENTRY_BINARY_FIELD_START;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering continue;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_TEXT_FIELD:
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_BINARY_FIELD: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering bool done;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering size_t tocopy;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering done = size - pos > u->field_length - u->field_pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (done)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tocopy = u->field_length - u->field_pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering else
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tocopy = size - pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering memcpy(buf + pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering (char*) u->field_data + u->field_pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tocopy);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (done) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[pos + tocopy] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += tocopy + 1;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state = ENTRY_NEW_FIELD;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering continue;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->field_pos += tocopy;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return size;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_BINARY_FIELD_START: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *c;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering size_t len;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering c = memchr(u->field_data, '=', u->field_length);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek if (!c || c == u->field_data) {
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek log_error("Invalid field.");
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek return -EINVAL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering len = c - (const char*)u->field_data;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* need space for label + '\n' */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (size - pos < len + 1)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek memcpy(buf + pos, u->field_data, len);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek buf[pos + len] = '\n';
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek pos += len + 1;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->field_pos = len + 1;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state ++;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } /* fall through */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering case ENTRY_BINARY_FIELD_SIZE: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering uint64_t le64;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett /* need space for uint64_t */
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett if (size - pos < 8)
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler return pos;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett le64 = htole64(u->field_length - u->field_pos);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett memcpy(buf + pos, &le64, 8);
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering pos += 8;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->entry_state ++;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett continue;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler }
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt case ENTRY_OUTRO:
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering /* need space for '\n' */
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering if (size - pos < 1)
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering return pos;
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering buf[pos++] = '\n';
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler u->entry_state ++;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->entries_sent ++;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler return pos;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler default:
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler assert_not_reached("WTF?");
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler }
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov }
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov assert_not_reached("WTF?");
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov}
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächlerstatic size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula Uploader *u = userp;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov int r;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler sd_journal *j;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler size_t filled = 0;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett ssize_t w;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett assert(u);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett assert(nmemb <= SSIZE_MAX / size);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov j = u->journal;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov while (j && filled < size * nmemb) {
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov if (u->entry_state == ENTRY_DONE) {
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov r = sd_journal_next(j);
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov if (r < 0) {
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula log_error_errno(r, "Failed to move to next entry in journal: %m");
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return CURL_READFUNC_ABORT;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett } else if (r == 0) {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett if (u->input_event)
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett log_debug("No more entries, waiting for journal.");
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett else {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett log_info("No more entries, closing journal.");
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett close_journal_input(u);
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett }
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula u->uploading = false;
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula break;
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula }
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->entry_state = ENTRY_CURSOR;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett }
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett w = write_entry((char*)buf + filled, size * nmemb - filled, u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (w < 0)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return CURL_READFUNC_ABORT;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek filled += w;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (filled == 0) {
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler log_error("Buffer space is too small to write entry.");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return CURL_READFUNC_ABORT;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering } else if (u->entry_state != ENTRY_DONE)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* This means that all available space was used up */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering break;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_debug("Entry %zu (%s) has been uploaded.",
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->entries_sent, u->current_cursor);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return filled;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringvoid close_journal_input(Uploader *u) {
ef5bfcf668e6029faa78534dfeb2591df854cdefLennart Poettering assert(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt if (u->journal) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek log_debug("Closing journal input.");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering sd_journal_close(u->journal);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->journal = NULL;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek u->timeout = 0;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringstatic int process_journal_input(Uploader *u, int skip) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek r = sd_journal_next_skip(u->journal, skip);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to skip to next entry: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else if (r < skip)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering /* have data */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state = ENTRY_CURSOR;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return start_upload(u, journal_input_callback, u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint check_journal_input(Uploader *u) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (u->input_event) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_process(u->journal);
875c6e1b48f37a07dfbb80d6653c73f205e94260Lennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to process journal: %m");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering close_journal_input(u);
b3267152783d5784c45010615045d4e8ee459da2Zbigniew Jędrzejewski-Szmek return r;
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt }
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r == SD_JOURNAL_NOP)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return 0;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return process_journal_input(u, 1);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler}
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächlerstatic int dispatch_journal_input(sd_event_source *event,
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler int fd,
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler uint32_t revents,
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler void *userp) {
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler Uploader *u = userp;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering assert(u);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (u->uploading) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering log_warning("dispatch_journal_input called when uploading, ignoring.");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return 0;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering log_debug("Detected journal input, checking for new data.");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return check_journal_input(u);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering}
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poetteringint open_journal_for_upload(Uploader *u,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering sd_journal *j,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering const char *cursor,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering bool after_cursor,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering bool follow) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering int fd, r, events;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering u->journal = j;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering sd_journal_set_data_threshold(j, 0);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (follow) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering fd = sd_journal_get_fd(j);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (fd < 0) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek log_error_errno(fd, "sd_journal_get_fd failed: %m");
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return fd;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering events = sd_journal_get_events(j);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_reliable_fd(j);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering assert(r >= 0);
73e231abde39f22097df50542c745e01de879836Jan Engelhardt if (r > 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->timeout = -1;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering else
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl r = sd_event_add_io(u->events, &u->input_event,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering fd, events, dispatch_journal_input, u);
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen if (r < 0) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_error_errno(r, "Failed to register input event: %m");
934ae16baf543af03f3f521277d14524ca772d17Lennart Poettering return r;
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl }
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_debug("Listening for journal events on fd:%d, timeout %d",
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering fd, u->timeout == (uint64_t) -1 ? -1 : (int) u->timeout);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_debug("Not listening for journal events.");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (cursor) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = sd_journal_seek_cursor(j, cursor);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (r < 0) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_error_errno(r, "Failed to seek to cursor %s: %m",
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt cursor);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return r;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen return process_journal_input(u, 1 + !!after_cursor);
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen}
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett