Blame SOURCES/0167-uploader-use-shared-dd_create_archive-function.patch

2c83a8
From 072e3f9847e3c5bf42175aa0f837e1a6445cdbc8 Mon Sep 17 00:00:00 2001
2c83a8
From: Matej Habrnal <mhabrnal@redhat.com>
2c83a8
Date: Fri, 12 Feb 2016 13:58:09 +0100
2c83a8
Subject: [PATCH] uploader: use shared dd_create_archive function
2c83a8
2c83a8
Use the test function instead of own untested one.
2c83a8
2c83a8
Signed-off-by: Jakub Filak <jfilak@redhat.com>
2c83a8
Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
2c83a8
2c83a8
Conflicts:
2c83a8
	src/plugins/reporter-upload.c
2c83a8
---
2c83a8
 src/plugins/reporter-upload.c | 184 ++++++++++++++----------------------------
2c83a8
 1 file changed, 60 insertions(+), 124 deletions(-)
2c83a8
2c83a8
diff --git a/src/plugins/reporter-upload.c b/src/plugins/reporter-upload.c
2c83a8
index 6d83d2f..b148d95 100644
2c83a8
--- a/src/plugins/reporter-upload.c
2c83a8
+++ b/src/plugins/reporter-upload.c
2c83a8
@@ -16,7 +16,6 @@
2c83a8
     with this program; if not, write to the Free Software Foundation, Inc.,
2c83a8
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2c83a8
 */
2c83a8
-#include <libtar.h>
2c83a8
 #include "libreport_curl.h"
2c83a8
 #include "internal_libreport.h"
2c83a8
 #include "client.h"
2c83a8
@@ -33,33 +32,45 @@ static char *ask_url(const char *message)
2c83a8
     return url;
2c83a8
 }
2c83a8
 
2c83a8
+static int interactive_upload_file(const char *url, const char *file_name)
2c83a8
+{
2c83a8
+    post_state_t *state = new_post_state(POST_WANT_ERROR_MSG);
2c83a8
+    state->username = getenv("Upload_Username");
2c83a8
+    char *password_inp = NULL;
2c83a8
+    if (state->username != NULL && state->username[0] != '\0')
2c83a8
+    {
2c83a8
+        /* Load Password only if Username is configured, it doesn't make */
2c83a8
+        /* much sense to load Password without Username. */
2c83a8
+        state->password = getenv("Upload_Password");
2c83a8
+        if (state->password == NULL)
2c83a8
+        {
2c83a8
+            /* Be permissive and nice, ask only once and don't check */
2c83a8
+            /* the result. User can dismiss this prompt but the upload */
2c83a8
+            /* may work somehow??? */
2c83a8
+            char *msg = xasprintf(_("Please enter password for uploading:"), state->username);
2c83a8
+            state->password = password_inp = ask_password(msg);
2c83a8
+            free(msg);
2c83a8
+        }
2c83a8
+    }
2c83a8
+
2c83a8
+    char *remote_name = upload_file_ext(state, url, file_name, UPLOAD_FILE_HANDLE_ACCESS_DENIALS);
2c83a8
+    int result = (remote_name == NULL); /* error if NULL */
2c83a8
+
2c83a8
+    free(remote_name);
2c83a8
+    free(password_inp);
2c83a8
+    free_post_state(state);
2c83a8
+
2c83a8
+    return result;
2c83a8
+}
2c83a8
+
2c83a8
 static int create_and_upload_archive(
2c83a8
                 const char *dump_dir_name,
2c83a8
                 map_string_t *settings)
2c83a8
 {
2c83a8
     int result = 1; /* error */
2c83a8
 
2c83a8
-    pid_t child;
2c83a8
-    TAR* tar = NULL;
2c83a8
-    const char* errmsg = NULL;
2c83a8
     char* tempfile = NULL;
2c83a8
 
2c83a8
-    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
2c83a8
-    if (!dd)
2c83a8
-        xfunc_die(); /* error msg is already logged by dd_opendir */
2c83a8
-
2c83a8
-    /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */
2c83a8
-    log(_("Compressing data"));
2c83a8
-
2c83a8
-//TODO:
2c83a8
-//Encrypt = yes
2c83a8
-//ArchiveType = .tar.bz2
2c83a8
-//ExcludeFiles = foo,bar*,b*z
2c83a8
-    const char* opt = getenv("Upload_URL");
2c83a8
-    if (!opt)
2c83a8
-        opt = get_map_string_item_or_empty(settings, "URL");
2c83a8
-    char *url = opt[0] != '\0' ? xstrdup(opt) : ask_url(_("Upload URL is not provided by configuration. Please enter upload URL:"));
2c83a8
-
2c83a8
     /* Create a child gzip which will compress the data */
2c83a8
     /* SELinux guys are not happy with /tmp, using /var/run/abrt */
2c83a8
     /* Reverted back to /tmp for ABRT2 */
2c83a8
@@ -67,114 +78,31 @@ static int create_and_upload_archive(
2c83a8
     tempfile = concat_path_basename(LARGE_DATA_TMP_DIR, dump_dir_name);
2c83a8
     tempfile = append_to_malloced_string(tempfile, ".tar.gz");
2c83a8
 
2c83a8
-    int pipe_from_parent_to_child[2];
2c83a8
-    xpipe(pipe_from_parent_to_child);
2c83a8
-    child = vfork();
2c83a8
-    if (child == 0)
2c83a8
-    {
2c83a8
-        /* child */
2c83a8
-        close(pipe_from_parent_to_child[1]);
2c83a8
-        xmove_fd(pipe_from_parent_to_child[0], 0);
2c83a8
-        xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1);
2c83a8
-        execlp("gzip", "gzip", NULL);
2c83a8
-        perror_msg_and_die("Can't execute '%s'", "gzip");
2c83a8
-    }
2c83a8
-    close(pipe_from_parent_to_child[0]);
2c83a8
+    const char* opt = getenv("Upload_URL");
2c83a8
+    if (!opt)
2c83a8
+        opt = get_map_string_item_or_empty(settings, "URL");
2c83a8
+    char *url = opt[0] != '\0' ? xstrdup(opt) : ask_url(_("Please enter a URL (scp, ftp, etc.) where the problem data is to be exported:"));
2c83a8
 
2c83a8
-    /* If child died (say, in xopen), then parent might get SIGPIPE.
2c83a8
-     * We want to properly unlock dd, therefore we must not die on SIGPIPE:
2c83a8
-     */
2c83a8
-    signal(SIGPIPE, SIG_IGN);
2c83a8
+    string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements();
2c83a8
+    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
2c83a8
+    if (!dd)
2c83a8
+        xfunc_die(); /* error msg is already logged by dd_opendir */
2c83a8
 
2c83a8
-    /* Create tar writer object */
2c83a8
-    if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile,
2c83a8
-                /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0)
2c83a8
+    /* Compressing e.g. 0.5gig coredump takes a while. Let client know what we are doing */
2c83a8
+    log(_("Compressing data"));
2c83a8
+    if (dd_create_archive(dd, tempfile, (const char * const*)exclude_from_report, 0) != 0)
2c83a8
     {
2c83a8
-        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
2c83a8
+        log_error("Can't create temporary file in %s", LARGE_DATA_TMP_DIR);
2c83a8
         goto ret;
2c83a8
     }
2c83a8
 
2c83a8
-    /* Write data to the tarball */
2c83a8
-    {
2c83a8
-        string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements();
2c83a8
-        dd_init_next_file(dd);
2c83a8
-        char *short_name, *full_name;
2c83a8
-        while (dd_get_next_file(dd, &short_name, &full_name))
2c83a8
-        {
2c83a8
-            if (exclude_from_report && is_in_string_list(short_name, (const_string_vector_const_ptr_t)exclude_from_report))
2c83a8
-                goto next;
2c83a8
-
2c83a8
-            // dd_get_next_file guarantees that it's a REG:
2c83a8
-            //struct stat stbuf;
2c83a8
-            //if (stat(full_name, &stbuf) != 0)
2c83a8
-            // || !S_ISREG(stbuf.st_mode)
2c83a8
-            //) {
2c83a8
-            //     goto next;
2c83a8
-            //}
2c83a8
-            if (tar_append_file(tar, full_name, short_name) != 0)
2c83a8
-            {
2c83a8
-                errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
2c83a8
-                free(short_name);
2c83a8
-                free(full_name);
2c83a8
-                goto ret;
2c83a8
-            }
2c83a8
- next:
2c83a8
-            free(short_name);
2c83a8
-            free(full_name);
2c83a8
-        }
2c83a8
-    }
2c83a8
     dd_close(dd);
2c83a8
     dd = NULL;
2c83a8
 
2c83a8
-    /* Close tar writer... */
2c83a8
-    if (tar_append_eof(tar) != 0 || tar_close(tar) != 0)
2c83a8
-    {
2c83a8
-        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
2c83a8
-        goto ret;
2c83a8
-    }
2c83a8
-    tar = NULL;
2c83a8
-    /* ...and check that gzip child finished successfully */
2c83a8
-    int status;
2c83a8
-    safe_waitpid(child, &status, 0);
2c83a8
-    child = -1;
2c83a8
-    if (status != 0)
2c83a8
-    {
2c83a8
-        /* We assume the error was out-of-disk-space or out-of-quota */
2c83a8
-        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
2c83a8
-        goto ret;
2c83a8
-    }
2c83a8
-
2c83a8
-    /* Upload the tarball */
2c83a8
+    /* Upload the archive */
2c83a8
     /* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */
2c83a8
     if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0)
2c83a8
-    {
2c83a8
-        post_state_t *state = new_post_state(POST_WANT_ERROR_MSG);
2c83a8
-        state->username = getenv("Upload_Username");
2c83a8
-        char *password_inp = NULL;
2c83a8
-        if (state->username != NULL && state->username[0] != '\0')
2c83a8
-        {
2c83a8
-            /* Load Password only if Username is configured, it doesn't make */
2c83a8
-            /* much sense to load Password without Username. */
2c83a8
-            state->password = getenv("Upload_Password");
2c83a8
-            if (state->password == NULL)
2c83a8
-            {
2c83a8
-                /* Be permissive and nice, ask only once and don't check */
2c83a8
-                /* the result. User can dismiss this prompt but the upload */
2c83a8
-                /* may work somehow??? */
2c83a8
-                char *msg = xasprintf(_("Please enter password for uploading:"), state->username);
2c83a8
-                state->password = password_inp = ask_password(msg);
2c83a8
-                free(msg);
2c83a8
-            }
2c83a8
-        }
2c83a8
-
2c83a8
-        char *remote_name = upload_file_ext(state, url, tempfile, UPLOAD_FILE_HANDLE_ACCESS_DENIALS);
2c83a8
-
2c83a8
-        result = (remote_name == NULL); /* error if NULL */
2c83a8
-        free(remote_name);
2c83a8
-        free(password_inp);
2c83a8
-        free_post_state(state);
2c83a8
-        /* cleanup code will delete tempfile */
2c83a8
-    }
2c83a8
+        result = interactive_upload_file(url, tempfile);
2c83a8
     else
2c83a8
     {
2c83a8
         result = 0; /* success */
2c83a8
@@ -186,18 +114,12 @@ static int create_and_upload_archive(
2c83a8
  ret:
2c83a8
     free(url);
2c83a8
     dd_close(dd);
2c83a8
-    if (tar)
2c83a8
-        tar_close(tar);
2c83a8
-    /* close(pipe_from_parent_to_child[1]); - tar_close() does it itself */
2c83a8
-    if (child > 0)
2c83a8
-        safe_waitpid(child, NULL, 0);
2c83a8
+
2c83a8
     if (tempfile)
2c83a8
     {
2c83a8
         unlink(tempfile);
2c83a8
         free(tempfile);
2c83a8
     }
2c83a8
-    if (errmsg)
2c83a8
-        error_msg_and_die("%s", errmsg);
2c83a8
 
2c83a8
     return result;
2c83a8
 }
2c83a8
@@ -206,6 +128,9 @@ int main(int argc, char **argv)
2c83a8
 {
2c83a8
     abrt_init(argv);
2c83a8
 
2c83a8
+    if (!load_global_configuration())
2c83a8
+        error_msg_and_die("Cannot continue without libreport global configuration.");
2c83a8
+
2c83a8
     /* I18n */
2c83a8
     setlocale(LC_ALL, "");
2c83a8
 #if ENABLE_NLS
2c83a8
@@ -255,6 +180,17 @@ int main(int argc, char **argv)
2c83a8
 
2c83a8
     export_abrt_envvars(0);
2c83a8
 
2c83a8
+    // 2015-10-16 (jfilak):
2c83a8
+    //   It looks like there is no demand for encryption and other archive
2c83a8
+    //   types. Configurable ExcludeFiles sounds reasonable to me, I am
2c83a8
+    //   not sure about globbing though.
2c83a8
+    //
2c83a8
+    //Encrypt = yes
2c83a8
+    //ArchiveType = .tar.bz2
2c83a8
+    //
2c83a8
+    //TODO:
2c83a8
+    //ExcludeFiles = foo,bar*,b*z
2c83a8
+
2c83a8
     map_string_t *settings = new_map_string();
2c83a8
     if (url)
2c83a8
         replace_map_string_item(settings, xstrdup("URL"), xstrdup(url));
2c83a8
-- 
2c83a8
1.8.3.1
2c83a8