Beispiel #1
0
int add_reported_to_data(char **reported_to, const char *line)
{
    if (*reported_to)
    {
        unsigned len_line = strlen(line);
        char *p = *reported_to;
        while (*p)
        {
            if (strncmp(p, line, len_line) == 0 && (p[len_line] == '\n' || p[len_line] == '\0'))
                return 0;
            p = strchrnul(p, '\n');
            if (!*p)
                break;
            p++;
        }
        if (p != *reported_to && p[-1] != '\n')
            *reported_to = append_to_malloced_string(*reported_to, "\n");
        *reported_to = append_to_malloced_string(*reported_to, line);
        *reported_to = append_to_malloced_string(*reported_to, "\n");
    }
    else
        *reported_to = xasprintf("%s\n", line);

    return 1;
}
Beispiel #2
0
static int create_and_upload_archive(
                const char *dump_dir_name,
                const char *url,
                map_string_t *settings,
                char **remote_name)
{
    int result = 1; /* error */
    char* tempfile = NULL;

    /* Create a child gzip which will compress the data */
    /* SELinux guys are not happy with /tmp, using /var/run/abrt */
    /* Reverted back to /tmp for ABRT2 */
    /* Changed again to /var/tmp because of Fedora feature tmp-on-tmpfs */
    tempfile = concat_path_basename(LARGE_DATA_TMP_DIR, dump_dir_name);
    tempfile = append_to_malloced_string(tempfile, ".tar.gz");

    string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements();

    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
    if (!dd)
        xfunc_die(); /* error msg is already logged by dd_opendir */

    /* Compressing e.g. 0.5gig coredump takes a while. Let client know what we are doing */
    log_warning(_("Compressing data"));
    if (dd_create_archive(dd, tempfile, (const_string_vector_const_ptr_t)exclude_from_report, 0) != 0)
    {
        log_error("Can't create temporary file in %s", LARGE_DATA_TMP_DIR);
        goto ret;
    }

    dd_close(dd);
    dd = NULL;

    /* Upload the archive */
    /* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */
    if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0)
        result = interactive_upload_file(url, tempfile, settings, remote_name);
    else
    {
        result = 0; /* success */
        log_warning(_("Archive is created: '%s'"), tempfile);
        *remote_name = tempfile;
        tempfile = NULL;
    }

 ret:
    dd_close(dd);

    if (tempfile)
    {
        unlink(tempfile);
        free(tempfile);
    }

    return result;
}
Beispiel #3
0
static
GList* load_bzrep_conf_file(const char *path)
{
    FILE *fp = stdin;
    if (strcmp(path, "-") != 0)
    {
        fp = fopen(path, "r");
        if (!fp)
            return NULL;
    }

    GList *sections = NULL;

    char *line;
    while ((line = xmalloc_fgetline(fp)) != NULL)
    {
        /* Skip comments */
        char first = *skip_whitespace(line);
        if (first == '#')
            goto free_line;

        /* Handle trailing backslash continuation */
 check_continuation: ;
        unsigned len = strlen(line);
        if (len && line[len-1] == '\\')
        {
            line[len-1] = '\0';
            char *next_line = xmalloc_fgetline(fp);
            if (next_line)
            {
                line = append_to_malloced_string(line, next_line);
                free(next_line);
                goto check_continuation;
            }
        }

        /* We are reusing line buffer to form temporary
         * "key\0values\0..." in its beginning
         */
        bool summary_line = false;
        char *value = NULL;
        char *src;
        char *dst;
        for (src = dst = line; *src; src++)
        {
            char c = *src;
            /* did we reach the value list? */
            if (!value && c == ':' && src[1] == ':')
            {
                *dst++ = '\0'; /* terminate key */
                src += 2;
                value = dst; /* remember where value starts */
                summary_line = (strcmp(line, "%summary") == 0);
                if (summary_line)
                {
                    value = src;
                    break;
                }
                continue;
            }
            /* skip whitespace in value list */
            if (value && isspace(c))
                continue;
            *dst++ = c; /* store next key or value char */
        }

        GList *item_list = NULL;
        if (summary_line)
        {
            /* %summary is special */
            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
        }
        else
        {
            *dst = '\0'; /* terminate value (or key) */
            if (value)
                item_list = split_string_on_char(value, ',');
        }

        section_t *sec = xzalloc(sizeof(*sec));
        sec->name = xstrdup(line);
        sec->items = item_list;
        sections = g_list_prepend(sections, sec);

 free_line:
        free(line);
    }

    if (fp != stdin)
        fclose(fp);

    return g_list_reverse(sections);
}
static int create_and_upload_archive(
                const char *dump_dir_name,
                map_string_t *settings)
{
    int result = 1; /* error */

    pid_t child;
    TAR* tar = NULL;
    const char* errmsg = NULL;
    char* tempfile = NULL;

    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
    if (!dd)
        xfunc_die(); /* error msg is already logged by dd_opendir */

    /* Gzipping e.g. 0.5gig coredump takes a while. Let client know what we are doing */
    log(_("Compressing data"));

//TODO:
//Encrypt = yes
//ArchiveType = .tar.bz2
//ExcludeFiles = foo,bar*,b*z
    const char* opt = getenv("Upload_URL");
    if (!opt)
        opt = get_map_string_item_or_empty(settings, "URL");
    char *url = opt[0] != '\0' ? xstrdup(opt) : ask_url(_("Please enter a URL (scp, ftp, etc.) where the problem data is to be exported:"));

    /* Create a child gzip which will compress the data */
    /* SELinux guys are not happy with /tmp, using /var/run/abrt */
    /* Reverted back to /tmp for ABRT2 */
    /* Changed again to /var/tmp because of Fedora feature tmp-on-tmpfs */
    tempfile = concat_path_basename(LARGE_DATA_TMP_DIR, dump_dir_name);
    tempfile = append_to_malloced_string(tempfile, ".tar.gz");

    int pipe_from_parent_to_child[2];
    xpipe(pipe_from_parent_to_child);
    child = vfork();
    if (child == 0)
    {
        /* child */
        close(pipe_from_parent_to_child[1]);
        xmove_fd(pipe_from_parent_to_child[0], 0);
        xmove_fd(xopen3(tempfile, O_WRONLY | O_CREAT | O_EXCL, 0600), 1);
        execlp("gzip", "gzip", NULL);
        perror_msg_and_die("Can't execute '%s'", "gzip");
    }
    close(pipe_from_parent_to_child[0]);

    /* If child died (say, in xopen), then parent might get SIGPIPE.
     * We want to properly unlock dd, therefore we must not die on SIGPIPE:
     */
    signal(SIGPIPE, SIG_IGN);

    /* Create tar writer object */
    if (tar_fdopen(&tar, pipe_from_parent_to_child[1], tempfile,
                /*fileops:(standard)*/ NULL, O_WRONLY | O_CREAT, 0644, TAR_GNU) != 0)
    {
        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
        goto ret;
    }

    /* Write data to the tarball */
    {
        string_vector_ptr_t exclude_from_report = get_global_always_excluded_elements();
        dd_init_next_file(dd);
        char *short_name, *full_name;
        while (dd_get_next_file(dd, &short_name, &full_name))
        {
            if (exclude_from_report && is_in_string_list(short_name, (const_string_vector_const_ptr_t)exclude_from_report))
                goto next;

            // dd_get_next_file guarantees that it's a REG:
            //struct stat stbuf;
            //if (stat(full_name, &stbuf) != 0)
            // || !S_ISREG(stbuf.st_mode)
            //) {
            //     goto next;
            //}
            if (tar_append_file(tar, full_name, short_name) != 0)
            {
                errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
                free(short_name);
                free(full_name);
                goto ret;
            }
 next:
            free(short_name);
            free(full_name);
        }
    }
    dd_close(dd);
    dd = NULL;

    /* Close tar writer... */
    if (tar_append_eof(tar) != 0 || tar_close(tar) != 0)
    {
        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
        goto ret;
    }
    tar = NULL;
    /* ...and check that gzip child finished successfully */
    int status;
    safe_waitpid(child, &status, 0);
    child = -1;
    if (status != 0)
    {
        /* We assume the error was out-of-disk-space or out-of-quota */
        errmsg = "Can't create temporary file in "LARGE_DATA_TMP_DIR;
        goto ret;
    }

    /* Upload the tarball */
    /* Upload from /tmp to /tmp + deletion -> BAD, exclude this possibility */
    if (url && url[0] && strcmp(url, "file://"LARGE_DATA_TMP_DIR"/") != 0)
    {
        post_state_t *state = new_post_state(POST_WANT_ERROR_MSG);
        state->username = getenv("Upload_Username");
        char *password_inp = NULL;
        if (state->username != NULL && state->username[0] != '\0')
        {
            /* Load Password only if Username is configured, it doesn't make */
            /* much sense to load Password without Username. */
            state->password = getenv("Upload_Password");
            if (state->password == NULL)
            {
                /* Be permissive and nice, ask only once and don't check */
                /* the result. User can dismiss this prompt but the upload */
                /* may work somehow??? */
                char *msg = xasprintf(_("Please enter password for uploading:"), state->username);
                state->password = password_inp = ask_password(msg);
                free(msg);
            }
        }

        char *remote_name = upload_file_ext(state, url, tempfile, UPLOAD_FILE_HANDLE_ACCESS_DENIALS);

        result = (remote_name == NULL); /* error if NULL */
        free(remote_name);
        free(password_inp);
        free_post_state(state);
        /* cleanup code will delete tempfile */
    }
    else
    {
        result = 0; /* success */
        log(_("Archive is created: '%s'"), tempfile);
        free(tempfile);
        tempfile = NULL;
    }

 ret:
    free(url);
    dd_close(dd);
    if (tar)
        tar_close(tar);
    /* close(pipe_from_parent_to_child[1]); - tar_close() does it itself */
    if (child > 0)
        safe_waitpid(child, NULL, 0);
    if (tempfile)
    {
        unlink(tempfile);
        free(tempfile);
    }
    if (errmsg)
        error_msg_and_die("%s", errmsg);

    return result;
}
Beispiel #5
0
static GList*
load_stream(FILE *fp)
{
    assert(fp);

    GList *sections = NULL;
    section_t *master = section_new("%description");
    section_t *sec = NULL;

    sections = g_list_append(sections, master);

    char *line;
    while ((line = xmalloc_fgetline(fp)) != NULL)
    {
        /* Skip comments */
        char first = *skip_whitespace(line);
        if (first == '#')
            goto free_line;

        /* Handle trailing backslash continuation */
 check_continuation: ;
        unsigned len = strlen(line);
        if (len && line[len-1] == '\\')
        {
            line[len-1] = '\0';
            char *next_line = xmalloc_fgetline(fp);
            if (next_line)
            {
                line = append_to_malloced_string(line, next_line);
                free(next_line);
                goto check_continuation;
            }
        }

        /* We are reusing line buffer to form temporary
         * "key\0values\0..." in its beginning
         */
        bool summary_line = false;
        char *value = NULL;
        char *src;
        char *dst;
        for (src = dst = line; *src; src++)
        {
            char c = *src;
            /* did we reach the value list? */
            if (!value && c == ':' && src[1] == ':')
            {
                *dst++ = '\0'; /* terminate key */
                src += 1;
                value = dst; /* remember where value starts */
                summary_line = (strcmp(line, "%summary") == 0);
                if (summary_line)
                {
                    value = (src + 1);
                    break;
                }
                continue;
            }
            /* skip whitespace in value list */
            if (value && isspace(c))
                continue;
            *dst++ = c; /* store next key or value char */
        }

        GList *item_list = NULL;
        if (summary_line)
        {
            /* %summary is special */
            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
        }
        else
        {
            *dst = '\0'; /* terminate value (or key) */
            if (value)
                item_list = split_string_on_char(value, ',');
        }

        sec = section_new(line);
        sec->items = item_list;

        if (sec->name[0] == '%')
        {
            if (!summary_line && strcmp(sec->name, "%attach") != 0)
            {
                master->children = g_list_reverse(master->children);
                master = sec;
            }

            sections = g_list_prepend(sections, sec);
        }
        else
            master->children = g_list_prepend(master->children, sec);

 free_line:
        free(line);
    }

    /* If master equals sec, then master's children list was not yet reversed.
     *
     * %description is the default section (i.e is not explicitly mentioned)
     * and %summary nor %attach cause its children list to reverse.
     */
    if (master == sec || strcmp(master->name, "%description") == 0)
        master->children = g_list_reverse(master->children);

    return sections;
}