journal-upload.c revision 1af719edc5958c01c19204fb68d6fc45c9eea85c
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2014 Zbigniew Jędrzejewski-Szmek
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <stdio.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <curl/curl.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <sys/stat.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <fcntl.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <getopt.h>
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "sd-daemon.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "log.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "build.h"
eef46c372f64f40dd75415b2c504c73138719c8dLennart Poettering#include "fileio.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "conf-parser.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "journal-upload.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define CERT_FILE CERTIFICATE_ROOT "/certs/journal-upload.pem"
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#define TRUST_FILE CERTIFICATE_ROOT "/ca/trusted.pem"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char* arg_url;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringstatic void close_fd_input(Uploader *u);
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poetteringstatic const char *arg_key = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char *arg_cert = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char *arg_trust = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char *arg_directory = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic char **arg_file = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char *arg_cursor = NULL;
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalierstatic bool arg_after_cursor = false;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic int arg_journal_type = 0;
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poetteringstatic const char *arg_machine = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic bool arg_merge = false;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic int arg_follow = -1;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char *arg_save_state = NULL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#define SERVER_ANSWER_KEEP 2048
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define STATE_FILE "/var/lib/systemd/journal-upload/state"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define easy_setopt(curl, opt, value, level, cmd) \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering code = curl_easy_setopt(curl, opt, value); \
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (code) { \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_full(level, \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "curl_easy_setopt " #opt " failed: %s", \
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering curl_easy_strerror(code)); \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering cmd; \
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering } \
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic size_t output_callback(char *buf,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering size_t size,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering size_t nmemb,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering void *userp) {
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering Uploader *u = userp;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering assert(u);
c454426c54c9beb274f415a80c64a4f1580700e7Lennart Poettering
c454426c54c9beb274f415a80c64a4f1580700e7Lennart Poettering log_debug("The server answers (%zu bytes): %.*s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size*nmemb, (int)(size*nmemb), buf);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (nmemb && !u->answer) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering u->answer = strndup(buf, size*nmemb);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!u->answer)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning("Failed to store server answer (%zu bytes): %s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size*nmemb, strerror(ENOMEM));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering return size * nmemb;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering}
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringstatic int update_cursor_state(Uploader *u) {
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering _cleanup_free_ char *temp_path = NULL;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering _cleanup_fclose_ FILE *f = NULL;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering int r;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (!u->state_file || !u->last_cursor)
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering return 0;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering r = fopen_temporary(u->state_file, &f, &temp_path);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering if (r < 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering goto finish;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fprintf(f,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "# This is private data. Do not parse.\n"
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "LAST_CURSOR=%s\n",
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering u->last_cursor);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering fflush(f);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (ferror(f) || rename(temp_path, u->state_file) < 0) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = -errno;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering unlink(u->state_file);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering unlink(temp_path);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringfinish:
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (r < 0)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering log_error("Failed to save state %s: %s", u->state_file, strerror(-r));
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int load_cursor_state(Uploader *u) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!u->state_file)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = parse_env_file(u->state_file, NEWLINE,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "LAST_CURSOR", &u->last_cursor,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0 && r != -ENOENT) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Failed to read state file %s: %s",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering u->state_file, strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenint start_upload(Uploader *u,
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering size_t (*input_callback)(void *ptr,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen size_t size,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen size_t nmemb,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *userdata),
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *data) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering CURLcode code;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen assert(u);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(input_callback);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (!u->header) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct curl_slist *h;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering h = curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering if (!h)
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering return log_oom();
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering h = curl_slist_append(h, "Transfer-Encoding: chunked");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!h) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering curl_slist_free_all(h);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return log_oom();
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering h = curl_slist_append(h, "Accept: text/plain");
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!h) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering curl_slist_free_all(h);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return log_oom();
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering u->header = h;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!u->easy) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering CURL *curl;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering curl = curl_easy_init();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!curl) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Call to curl_easy_init failed.");
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return -ENOSR;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen /* tell it to POST to the URL */
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering easy_setopt(curl, CURLOPT_POST, 1L,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LOG_ERR, return -EXFULL);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering easy_setopt(curl, CURLOPT_ERRORBUFFER, u->error,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering LOG_ERR, return -EXFULL);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* set where to write to */
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering easy_setopt(curl, CURLOPT_WRITEFUNCTION, output_callback,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering LOG_ERR, return -EXFULL);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering easy_setopt(curl, CURLOPT_WRITEDATA, data,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering LOG_ERR, return -EXFULL);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* set where to read from */
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering easy_setopt(curl, CURLOPT_READFUNCTION, input_callback,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering LOG_ERR, return -EXFULL);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering easy_setopt(curl, CURLOPT_READDATA, data,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LOG_ERR, return -EXFULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* use our special own mime type and chunked transfer */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering easy_setopt(curl, CURLOPT_HTTPHEADER, u->header,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LOG_ERR, return -EXFULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* enable verbose for easier tracing */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering easy_setopt(curl, CURLOPT_VERBOSE, 1L, LOG_WARNING, );
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering easy_setopt(curl, CURLOPT_USERAGENT,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering "systemd-journal-upload " PACKAGE_STRING,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LOG_WARNING, );
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_key || startswith(u->url, "https://")) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering easy_setopt(curl, CURLOPT_SSLKEY, arg_key ?: PRIV_KEY_FILE,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LOG_ERR, return -EXFULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering easy_setopt(curl, CURLOPT_SSLCERT, arg_cert ?: CERT_FILE,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LOG_ERR, return -EXFULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_trust || startswith(u->url, "https://"))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering easy_setopt(curl, CURLOPT_CAINFO, arg_trust ?: TRUST_FILE,
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering LOG_ERR, return -EXFULL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_key || arg_trust)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering LOG_WARNING, );
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering u->easy = curl;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering } else {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* truncate the potential old error message */
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering u->error[0] = '\0';
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering free(u->answer);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u->answer = 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* upload to this place */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering code = curl_easy_setopt(u->easy, CURLOPT_URL, u->url);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (code) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("curl_easy_setopt CURLOPT_URL failed: %s",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering curl_easy_strerror(code));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EXFULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u->uploading = true;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic size_t fd_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering Uploader *u = userp;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering ssize_t r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(nmemb <= SSIZE_MAX / size);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (u->input < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = read(u->input, buf, size * nmemb);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_debug("%s: allowed %zu, read %zu", __func__, size*nmemb, r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r > 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering u->uploading = false;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r == 0) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering log_debug("Reached EOF");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering close_fd_input(u);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering } else {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Aborting transfer after read error on input: %m.");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return CURL_READFUNC_ABORT;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringstatic void close_fd_input(Uploader *u) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(u);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (u->input >= 0)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering close_nointr(u->input);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering u->input = -1;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering u->timeout = 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringstatic int dispatch_fd_input(sd_event_source *event,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering int fd,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering uint32_t revents,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering void *userp) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering Uploader *u = userp;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(u);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(fd >= 0);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (revents & EPOLLHUP) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_debug("Received HUP");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering close_fd_input(u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!(revents & EPOLLIN)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_warning("Unexpected poll event %"PRIu32".", revents);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (u->uploading) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering log_warning("dispatch_fd_input called when uploading, ignoring.");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering return start_upload(u, fd_input_callback, u);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic int open_file_for_upload(Uploader *u, const char *filename) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int fd, r = 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (streq(filename, "-"))
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering fd = STDIN_FILENO;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering else {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering if (fd < 0) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering log_error("Failed to open %s: %m", filename);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -errno;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u->input = fd;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_follow) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_event_add_io(u->events, &u->input_event,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering fd, EPOLLIN, dispatch_fd_input, u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r != -EPERM || arg_follow > 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to register input event: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering /* Normal files should just be consumed without polling. */
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = start_upload(u, fd_input_callback, u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int dispatch_sigterm(sd_event_source *event,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const struct signalfd_siginfo *si,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering void *userdata) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering Uploader *u = userdata;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering assert(u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_received_signal(LOG_INFO, si);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
21b735e798c580e7af8c33ace9f8565860b7f8dfLennart Poettering close_fd_input(u);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering close_journal_input(u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen sd_event_exit(u->events, 0);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int setup_signals(Uploader *u) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering sigset_t mask;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int r;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(u);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert_se(sigemptyset(&mask) == 0);
6f883237f1b8a96ec0ea354866e033b6fcea9506Lennart Poettering sigset_add_many(&mask, SIGINT, SIGTERM, -1);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = sd_event_add_signal(u->events, &u->sigterm_event, SIGTERM, dispatch_sigterm, u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = sd_event_add_signal(u->events, &u->sigint_event, SIGINT, dispatch_sigterm, u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int setup_uploader(Uploader *u, const char *url, const char *state_file) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(url);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering memzero(u, sizeof(Uploader));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering u->input = -1;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!startswith(url, "http://") && !startswith(url, "https://"))
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering url = strappenda("https://", url);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering u->url = strappend(url, "/upload");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!u->url)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return log_oom();
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering u->state_file = state_file;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_event_default(&u->events);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("sd_event_default failed: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = setup_signals(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Failed to set up signals: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return load_cursor_state(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic void destroy_uploader(Uploader *u) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering curl_easy_cleanup(u->easy);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering curl_slist_free_all(u->header);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering free(u->answer);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering free(u->last_cursor);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering free(u->current_cursor);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering free(u->url);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering u->input_event = sd_event_source_unref(u->input_event);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering close_fd_input(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering close_journal_input(u);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering sd_event_source_unref(u->sigterm_event);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering sd_event_source_unref(u->sigint_event);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering sd_event_unref(u->events);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int perform_upload(Uploader *u) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering CURLcode code;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering long status;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering code = curl_easy_perform(u->easy);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (code) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Upload to %s failed: %.*s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->url,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->error[0] ? (int) sizeof(u->error) : INT_MAX,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->error[0] ? u->error : curl_easy_strerror(code));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -EIO;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering code = curl_easy_getinfo(u->easy, CURLINFO_RESPONSE_CODE, &status);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (code) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Failed to retrieve response code: %s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering curl_easy_strerror(code));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -EUCLEAN;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (status >= 300) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Upload to %s failed with code %lu: %s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->url, status, strna(u->answer));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -EIO;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering } else if (status < 200) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Upload to %s finished with unexpected code %lu: %s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->url, status, strna(u->answer));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -EIO;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering } else
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_debug("Upload finished successfully with code %lu: %s",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering status, strna(u->answer));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering free(u->last_cursor);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->last_cursor = u->current_cursor;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering u->current_cursor = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return update_cursor_state(u);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int parse_config(void) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering const ConfigTableItem items[] = {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering { "Upload", "URL", config_parse_string, 0, &arg_url },
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering { "Upload", "ServerKeyFile", config_parse_path, 0, &arg_key },
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering { "Upload", "ServerCertificateFile", config_parse_path, 0, &arg_cert },
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering { "Upload", "TrustedCertificateFile", config_parse_path, 0, &arg_trust },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering {}};
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return config_parse(NULL, PKGSYSCONFDIR "/journal-upload.conf", NULL,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "Upload\0",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers config_item_table_lookup, items,
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering false, false, true, NULL);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic void help(void) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("%s -u URL {FILE|-}...\n\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "Upload journal events to a remote server.\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -h --help Show this help\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --version Show package version\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " -u --url=URL Upload to this address\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " --key=FILENAME Specify key in PEM format (default:\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " \"" PRIV_KEY_FILE "\")\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " --cert=FILENAME Specify certificate in PEM format (default:\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " \"" CERT_FILE "\")\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " --trust=FILENAME|all Specify CA certificate or disable checking (default:\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " \"" TRUST_FILE "\")\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " --system Use the system journal\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " --user Use the user journal for the current user\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " -m --merge Use all available journals\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " -M --machine=CONTAINER Operate on local container\n"
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann " -D --directory=PATH Use journal files from directory\n"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen " --file=PATH Use this journal file\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --cursor=CURSOR Start at the specified cursor\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --after-cursor=CURSOR Start after the specified cursor\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering " --follow[=BOOL] Do [not] wait for input\n"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering " --save-state[=FILE] Save uploaded cursors (default \n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " " STATE_FILE ")\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -h --help Show this help and exit\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --version Print version string and exit\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering , program_invocation_short_name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering enum {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_VERSION = 0x100,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_KEY,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering ARG_CERT,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering ARG_TRUST,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_USER,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_SYSTEM,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_FILE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_CURSOR,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_AFTER_CURSOR,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_FOLLOW,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_SAVE_STATE,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct option options[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "help", no_argument, NULL, 'h' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "url", required_argument, NULL, 'u' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "key", required_argument, NULL, ARG_KEY },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "cert", required_argument, NULL, ARG_CERT },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "trust", required_argument, NULL, ARG_TRUST },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "system", no_argument, NULL, ARG_SYSTEM },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "user", no_argument, NULL, ARG_USER },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "merge", no_argument, NULL, 'm' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "machine", required_argument, NULL, 'M' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "directory", required_argument, NULL, 'D' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "file", required_argument, NULL, ARG_FILE },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "cursor", required_argument, NULL, ARG_CURSOR },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "follow", optional_argument, NULL, ARG_FOLLOW },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "save-state", optional_argument, NULL, ARG_SAVE_STATE },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering {}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int c, r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(argc >= 0);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(argv);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering opterr = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering while ((c = getopt_long(argc, argv, "hu:mM:D:", options, NULL)) >= 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering switch(c) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case 'h':
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering help();
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 0 /* done */;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case ARG_VERSION:
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering puts(PACKAGE_STRING);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering puts(SYSTEMD_FEATURES);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 0 /* done */;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case 'u':
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (arg_url) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_error("cannot use more than one --url");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -EINVAL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering arg_url = optarg;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering break;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering case ARG_KEY:
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (arg_key) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("cannot use more than one --key");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return -EINVAL;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering arg_key = optarg;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering break;
ece174c5439021e32ebcc858842de9586072c006Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering case ARG_CERT:
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (arg_cert) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering log_error("cannot use more than one --cert");
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return -EINVAL;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering arg_cert = optarg;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering break;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering case ARG_TRUST:
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (arg_trust) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering log_error("cannot use more than one --trust");
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_trust = optarg;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering break;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case ARG_SYSTEM:
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering arg_journal_type |= SD_JOURNAL_SYSTEM;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering break;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case ARG_USER:
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering arg_journal_type |= SD_JOURNAL_CURRENT_USER;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering break;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek case 'm':
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek arg_merge = true;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering break;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering case 'M':
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (arg_machine) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_error("cannot use more than one --machine/-M");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -EINVAL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering arg_machine = optarg;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case 'D':
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (arg_directory) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering log_error("cannot use more than one --directory/-D");
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return -EINVAL;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering }
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering arg_directory = optarg;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering break;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering case ARG_FILE:
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering r = glob_extend(&arg_file, optarg);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Failed to add paths: %s", strerror(-r));
a6c616024db23fef34152c1432892824a07799ccLennart Poettering return r;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann };
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen break;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering case ARG_CURSOR:
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (arg_cursor) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("cannot use more than one --cursor/--after-cursor");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers arg_cursor = optarg;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers break;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case ARG_AFTER_CURSOR:
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (arg_cursor) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt log_error("cannot use more than one --cursor/--after-cursor");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_cursor = optarg;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_after_cursor = true;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers case ARG_FOLLOW:
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (optarg) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = parse_boolean(optarg);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Failed to parse --follow= parameter.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering arg_follow = !!r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering } else
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers arg_follow = true;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen case ARG_SAVE_STATE:
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters arg_save_state = optarg ?: STATE_FILE;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen break;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case '?':
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering log_error("Unknown option %s.", argv[optind-1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case ':':
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Missing argument to %s.", argv[optind-1]);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers default:
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert_not_reached("Unhandled option code.");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!arg_url) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Required --url/-u option missing.");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!!arg_key != !!arg_cert) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Options --key and --cert must be used together.");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return -EINVAL;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (optind < argc && (arg_directory || arg_file || arg_machine || arg_journal_type)) {
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni log_error("Input arguments make no sense with journal input.");
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int open_journal(sd_journal **j) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen int r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (arg_directory)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_journal_open_directory(j, arg_directory, arg_journal_type);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen else if (arg_file)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_journal_open_files(j, (const char**) arg_file, 0);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen else if (arg_machine)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_journal_open_container(j, arg_machine, 0);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen else
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_journal_open(j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to open %s: %s",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen arg_directory ? arg_directory : arg_file ? "files" : "journal",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen strerror(-r));
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return r;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversint main(int argc, char **argv) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering Uploader u;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bool use_journal;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_show_color(true);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_parse_environment();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = parse_config();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering goto finish;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = parse_argv(argc, argv);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r <= 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering goto finish;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering r = setup_uploader(&u, arg_url, arg_save_state);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0)
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering goto cleanup;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_event_set_watchdog(u.events, true);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann log_debug("%s running as pid "PID_FMT,
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann program_invocation_short_name, getpid());
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann use_journal = optind >= argc;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann if (use_journal) {
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann sd_journal *j;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann r = open_journal(&j);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann if (r < 0)
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann goto finish;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = open_journal_for_upload(&u, j,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_cursor ?: u.last_cursor,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_cursor ? arg_after_cursor : true,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering !!arg_follow);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering goto finish;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_notify(false,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "READY=1\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "STATUS=Processing input...");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering while (true) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (use_journal) {
9a14fb6285bdb089d4fc195410de3362cb4f586fThomas Hindoe Paaboel Andersen if (!u.journal)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = check_journal_input(&u);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } else if (u.input < 0 && !use_journal) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (optind >= argc)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_debug("Using %s as input.", argv[optind]);
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering r = open_file_for_upload(&u, argv[optind++]);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering goto cleanup;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = sd_event_get_state(u.events);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r == SD_EVENT_FINISHED)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (u.uploading) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = perform_upload(&u);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering r = sd_event_run(u.events, u.timeout);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0) {
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering log_error("Failed to run event loop: %s", strerror(-r));
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringcleanup:
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering sd_notify(false,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering "STOPPING=1\n"
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering "STATUS=Shutting down...");
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering destroy_uploader(&u);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
160e3793adf2da2bd9ae3fe6b8881bb937e6e71bLennart Poetteringfinish:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering