journal-upload.c revision 3d090cc6f34e5970765dd1e7ee5e648a056d180d
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 "journal-upload.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic const char* arg_url;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic void close_fd_input(Uploader *u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#define easy_setopt(curl, opt, value, level, cmd) \
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering { \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering code = curl_easy_setopt(curl, opt, value); \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering if (code) { \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering log_full(level, \
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering "curl_easy_setopt " #opt " failed: %s", \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering curl_easy_strerror(code)); \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering cmd; \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering } \
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering }
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringint start_upload(Uploader *u,
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier size_t (*input_callback)(void *ptr,
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering size_t size,
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering size_t nmemb,
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering void *userdata),
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering void *data) {
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering CURLcode code;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering assert(u);
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering assert(input_callback);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!u->header) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct curl_slist *h;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering h = curl_slist_append(NULL, "Content-Type: application/vnd.fdo.journal");
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (!h)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering h = curl_slist_append(h, "Transfer-Encoding: chunked");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!h) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering curl_slist_free_all(h);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_oom();
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering }
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering h = curl_slist_append(h, "Accept: text/plain");
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (!h) {
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering curl_slist_free_all(h);
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return log_oom();
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering }
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering
c454426c54c9beb274f415a80c64a4f1580700e7Lennart Poettering u->header = h;
c454426c54c9beb274f415a80c64a4f1580700e7Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!u->easy) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering CURL *curl;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering curl = curl_easy_init();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!curl) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Call to curl_easy_init failed.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOSR;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering /* tell it to POST to the URL */
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering easy_setopt(curl, CURLOPT_POST, 1L,
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering LOG_ERR, return -EXFULL);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering /* set where to read from */
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering easy_setopt(curl, CURLOPT_READFUNCTION, input_callback,
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering LOG_ERR, return -EXFULL);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering easy_setopt(curl, CURLOPT_READDATA, data,
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering LOG_ERR, return -EXFULL);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering /* use our special own mime type and chunked transfer */
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering easy_setopt(curl, CURLOPT_HTTPHEADER, u->header,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering LOG_ERR, return -EXFULL);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering /* enable verbose for easier tracing */
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering easy_setopt(curl, CURLOPT_VERBOSE, 1L, LOG_WARNING, );
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering easy_setopt(curl, CURLOPT_USERAGENT,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering "systemd-journal-upload " PACKAGE_STRING,
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering LOG_WARNING, );
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering u->easy = curl;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* upload to this place */
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering code = curl_easy_setopt(u->easy, CURLOPT_URL, u->url);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (code) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering log_error("curl_easy_setopt CURLOPT_URL failed: %s",
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering curl_easy_strerror(code));
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EXFULL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering u->uploading = true;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poetteringstatic size_t fd_input_callback(void *buf, size_t size, size_t nmemb, void *userp) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen Uploader *u = userp;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering ssize_t r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(u);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(nmemb <= SSIZE_MAX / size);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (u->input < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = read(u->input, buf, size * nmemb);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_debug("%s: allowed %zu, read %zu", __func__, size*nmemb, r);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r > 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen u->uploading = false;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering if (r == 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_debug("Reached EOF");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen close_fd_input(u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Aborting transfer after read error on input: %m.");
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return CURL_READFUNC_ABORT;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic void close_fd_input(Uploader *u) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(u);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering if (u->input >= 0)
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering close_nointr(u->input);
fee6d013d859bc66f5c993530898fece53fab06dLennart Poettering u->input = -1;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int dispatch_fd_input(sd_event_source *event,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int fd,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering uint32_t revents,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering void *userp) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering Uploader *u = userp;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(u);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(revents & EPOLLIN);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering assert(fd >= 0);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (u->uploading) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering log_warning("dispatch_fd_input called when uploading, ignoring.");
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return start_upload(u, fd_input_callback, u);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int open_file_for_upload(Uploader *u, const char *filename) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen int fd, r;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (streq(filename, "-"))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen fd = STDIN_FILENO;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen else {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (fd < 0) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering log_error("Failed to open %s: %m", filename);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -errno;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering u->input = fd;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = sd_event_add_io(u->events, &u->input_event,
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering fd, EPOLLIN, dispatch_fd_input, u);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (r < 0) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (r != -EPERM) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering log_error("Failed to register input event: %s", strerror(-r));
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* Normal files should just be consumed without polling. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = start_upload(u, fd_input_callback, u);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic int setup_uploader(Uploader *u, const char *url) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(u);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(url);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering memzero(u, sizeof(Uploader));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u->input = -1;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u->url = url;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_event_default(&u->events);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("sd_event_default failed: %s", strerror(-r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic void destroy_uploader(Uploader *u) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(u);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering curl_easy_cleanup(u->easy);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering curl_slist_free_all(u->header);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering u->input_event = sd_event_source_unref(u->input_event);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering close_fd_input(u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering sd_event_unref(u->events);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic void help(void) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("%s -u URL {FILE|-}...\n\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "Upload journal events to a remote server.\n\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "Options:\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering " --url=URL Upload to this address\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering " -h --help Show this help and exit\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering " --version Print version string and exit\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering , program_invocation_short_name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering enum {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering ARG_VERSION = 0x100,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering };
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering static const struct option options[] = {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering { "help", no_argument, NULL, 'h' },
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "url", required_argument, NULL, 'u' },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering {}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering };
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int c;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(argc >= 0);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(argv);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering opterr = 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering while ((c = getopt_long(argc, argv, "hu:", options, NULL)) >= 0)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering switch(c) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering case 'h':
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering help();
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0 /* done */;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering case ARG_VERSION:
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering puts(PACKAGE_STRING);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering puts(SYSTEMD_FEATURES);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0 /* done */;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering case 'u':
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (arg_url) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering log_error("cannot use more than one --url");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return -EINVAL;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering arg_url = optarg;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering case '?':
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering log_error("Unknown option %s.", argv[optind-1]);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case ':':
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering log_error("Missing argument to %s.", argv[optind-1]);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -EINVAL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering default:
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert_not_reached("Unhandled option code.");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!arg_url) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Required --url/-u option missing.");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (optind >= argc) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Input argument missing.");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 1;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringint main(int argc, char **argv) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering Uploader u;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering log_show_color(true);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering log_parse_environment();
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = parse_argv(argc, argv);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r <= 0)
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering goto finish;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering r = setup_uploader(&u, arg_url);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto cleanup;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_debug("%s running as pid "PID_FMT,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering program_invocation_short_name, getpid());
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering sd_notify(false,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "READY=1\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "STATUS=Processing input...");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering while (true) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (u.input < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (optind >= argc)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering break;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering log_debug("Using %s as input.", argv[optind]);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = open_file_for_upload(&u, argv[optind++]);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering goto cleanup;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = sd_event_get_state(u.events);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering break;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r == SD_EVENT_FINISHED)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering break;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (u.uploading) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering CURLcode code;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
21b735e798c580e7af8c33ace9f8565860b7f8dfLennart Poettering assert(u.easy);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering code = curl_easy_perform(u.easy);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (code) {
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering log_error("Upload to %s failed: %s",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering u.url, curl_easy_strerror(code));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = -EIO;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering break;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering } else
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_debug("Upload finished successfully.");
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering }
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering r = sd_event_run(u.events, u.input >= 0 ? -1 : 0);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0) {
6f883237f1b8a96ec0ea354866e033b6fcea9506Lennart Poettering log_error("Failed to run event loop: %s", strerror(-r));
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering break;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringcleanup:
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering sd_notify(false, "STATUS=Shutting down...");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering destroy_uploader(&u);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringfinish:
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering