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