journal-upload-journal.c revision 5ffa8c818120e35c89becd938d160235c069dd12
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 return log_error_errno(r, "Failed to get cursor: %m");
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering r = snprintf(buf + pos, size - pos,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart 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 return log_error_errno(r, "Failed to get realtime timestamp: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = snprintf(buf + pos, size - pos,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r + pos > size)
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek /* 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
39883f622f392d8579f4428fc5a789a102efbb10Lennart Poettering case ENTRY_MONOTONIC: {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering usec_t monotonic;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_id128_t boot_id;
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return log_error_errno(r, "Failed to get monotonic timestamp: %m");
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 return log_error_errno(r, "Failed to get monotonic timestamp: %m");
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 return log_error_errno(r, "Failed to move to next field in entry: %m");
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);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!c || c == u->field_data) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error("Invalid field.");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering 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)
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek return pos;
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek memcpy(buf + pos, u->field_data, len);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering buf[pos + len] = '\n';
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering 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: {
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek uint64_t le64;
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek /* need space for uint64_t */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (size - pos < 8)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return pos;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering le64 = htole64(u->field_length - u->field_pos);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering memcpy(buf + pos, &le64, 8);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering pos += 8;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler u->entry_state ++;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett continue;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett }
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett case ENTRY_OUTRO:
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett /* need space for '\n' */
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett if (size - pos < 1)
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering return pos;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett buf[pos++] = '\n';
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->entry_state ++;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler u->entries_sent ++;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return pos;
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering default:
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering assert_not_reached("WTF?");
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering }
c7fdf44d08e1217d40dc092fb90a65978a0f541fLennart Poettering }
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler assert_not_reached("WTF?");
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett}
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächlerstatic size_t journal_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler Uploader *u = userp;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler int r;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler sd_journal *j;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler size_t filled = 0;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov ssize_t w;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov assert(u);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler assert(nmemb <= SSIZE_MAX / size);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula j = u->journal;
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler while (j && filled < size * nmemb) {
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler if (u->entry_state == ENTRY_DONE) {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett r = sd_journal_next(j);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt if (r < 0) {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett 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) {
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov if (u->input_event)
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov log_debug("No more entries, waiting for journal.");
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov else {
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov log_info("No more entries, closing journal.");
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov close_journal_input(u);
4cd2b2cf8ca585d15ebc859701b346658262b5bbDenis Tikhomirov }
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->uploading = false;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett break;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett }
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett u->entry_state = ENTRY_CURSOR;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett }
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett w = write_entry((char*)buf + filled, size * nmemb - filled, u);
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula if (w < 0)
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula return CURL_READFUNC_ABORT;
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula filled += w;
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula
0c9d8f1d4b5018199cb5a9b57580dc1480a7f915Jani Nikula if (filled == 0) {
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett log_error("Buffer space is too small to write entry.");
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett return CURL_READFUNC_ABORT;
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett } else if (u->entry_state != ENTRY_DONE)
7b909d7407965c03caaba30daae7aee113627a83Josh Triplett /* This means that all available space was used up */
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering break;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek log_debug("Entry %zu (%s) has been uploaded.",
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering u->entries_sent, u->current_cursor);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return filled;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringvoid close_journal_input(Uploader *u) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (u->journal) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_debug("Closing journal input.");
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering sd_journal_close(u->journal);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->journal = NULL;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->timeout = 0;
ef5bfcf668e6029faa78534dfeb2591df854cdefLennart Poettering}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidtstatic int process_journal_input(Uploader *u, int skip) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek int r;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering r = sd_journal_next_skip(u->journal, skip);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (r < 0)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return log_error_errno(r, "Failed to skip to next entry: %m");
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek else if (r < skip)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering /* have data */
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering u->entry_state = ENTRY_CURSOR;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return start_upload(u, journal_input_callback, u);
938d2699d2e818bd996614e89ea3d668200ad2a8Zbigniew Jędrzejewski-Szmek}
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);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error_errno(r, "Failed to process journal: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering close_journal_input(u);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r == SD_JOURNAL_NOP)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
875c6e1b48f37a07dfbb80d6653c73f205e94260Lennart Poettering return process_journal_input(u, 1);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
b3267152783d5784c45010615045d4e8ee459da2Zbigniew Jędrzejewski-Szmekstatic int dispatch_journal_input(sd_event_source *event,
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt int fd,
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek uint32_t revents,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering void *userp) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Uploader *u = userp;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler if (u->uploading) {
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler log_warning("dispatch_journal_input called when uploading, ignoring.");
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler return 0;
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler }
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler log_debug("Detected journal input, checking for new data.");
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler return check_journal_input(u);
3cadce7d33e263ec7a6a83c00c11144930258b22Thomas Bächler}
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);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (fd < 0)
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return log_error_errno(fd, "sd_journal_get_fd failed: %m");
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering events = sd_journal_get_events(j);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering r = sd_journal_reliable_fd(j);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering assert(r >= 0);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (r > 0)
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering u->timeout = -1;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering else
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering u->timeout = JOURNAL_UPLOAD_POLL_TIMEOUT;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = sd_event_add_io(u->events, &u->input_event,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering fd, events, dispatch_journal_input, u);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (r < 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return log_error_errno(r, "Failed to register input event: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
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);
73e231abde39f22097df50542c745e01de879836Jan Engelhardt } else
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_debug("Not listening for journal events.");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (cursor) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_journal_seek_cursor(j, cursor);
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl if (r < 0) {
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return log_error_errno(r, "Failed to seek to cursor %s: %m",
bca81be7755d15e7369d764bfa94a7ca6c595c76Topi Miettinen cursor);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
934ae16baf543af03f3f521277d14524ca772d17Lennart Poettering }
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl
b76388e123e8d73ded1fd53937d816b314948517Michael Biebl return process_journal_input(u, 1 + !!after_cursor);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering