chiark / gitweb /
journal-upload: verify state file can be saved before uploading
[elogind.git] / src / journal-remote / journal-upload.c
index 3937683790ac20cdddbc8623362836a1357e6bfa..37c12f0e07ca50c7e8405ba644e057271883cdab 100644 (file)
 #include "util.h"
 #include "build.h"
 #include "fileio.h"
+#include "mkdir.h"
 #include "conf-parser.h"
 #include "journal-upload.h"
 
 #define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
 #define CERT_FILE     CERTIFICATE_ROOT "/certs/journal-upload.pem"
 #define TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
+#define DEFAULT_PORT  19532
 
 static const char* arg_url;
 
@@ -92,6 +94,32 @@ static size_t output_callback(char *buf,
         return size * nmemb;
 }
 
+static int check_cursor_updating(Uploader *u) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        if (!u->state_file)
+                return 0;
+
+        r = mkdir_parents(u->state_file, 0755);
+        if (r < 0) {
+                log_error("Cannot create parent directory of state file %s: %s",
+                          u->state_file, strerror(-r));
+                return r;
+        }
+
+        r = fopen_temporary(u->state_file, &f, &temp_path);
+        if (r < 0) {
+                log_error("Cannot save state to %s: %s",
+                          u->state_file, strerror(-r));
+                return r;
+        }
+        unlink(temp_path);
+
+        return 0;
+}
+
 static int update_cursor_state(Uploader *u) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -392,6 +420,7 @@ static int setup_signals(Uploader *u) {
 
 static int setup_uploader(Uploader *u, const char *url, const char *state_file) {
         int r;
+        const char *host, *proto = "";
 
         assert(u);
         assert(url);
@@ -399,10 +428,24 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
         memzero(u, sizeof(Uploader));
         u->input = -1;
 
-        if (!startswith(url, "http://") && !startswith(url, "https://"))
-                url = strappenda("https://", url);
+        if (!(host = startswith(url, "http://")) && !(host = startswith(url, "https://"))) {
+                host = url;
+                proto = "https://";
+        }
+
+        if (strchr(host, ':'))
+                u->url = strjoin(proto, url, "/upload", NULL);
+        else {
+                char *t;
+                size_t x;
+
+                t = strdupa(url);
+                x = strlen(t);
+                while (x > 0 && t[x - 1] == '/')
+                        t[x - 1] = '\0';
 
-        u->url = strappend(url, "/upload");
+                u->url = strjoin(proto, t, ":" STRINGIFY(DEFAULT_PORT), "/upload", NULL);
+        }
         if (!u->url)
                 return log_oom();
 
@@ -505,7 +548,8 @@ static void help(void) {
                "Upload journal events to a remote server.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n"
-               "  -u --url=URL              Upload to this address\n"
+               "  -u --url=URL              Upload to this address (default port "
+                                            STRINGIFY(DEFAULT_PORT) ")\n"
                "     --key=FILENAME         Specify key in PEM format (default:\n"
                "                            \"" PRIV_KEY_FILE "\")\n"
                "     --cert=FILENAME        Specify certificate in PEM format (default:\n"
@@ -762,6 +806,10 @@ int main(int argc, char **argv) {
 
         sd_event_set_watchdog(u.events, true);
 
+        r = check_cursor_updating(&u);
+        if (r < 0)
+                goto cleanup;
+
         log_debug("%s running as pid "PID_FMT,
                   program_invocation_short_name, getpid());