Blame src/plugins/reporter-kerneloops.c

Packit Service 779887
/*
Packit Service 779887
    Copyright (C) 2010  ABRT team
Packit Service 779887
    Copyright (C) 2010  RedHat Inc
Packit Service 779887
Packit Service 779887
    This program is free software; you can redistribute it and/or modify
Packit Service 779887
    it under the terms of the GNU General Public License as published by
Packit Service 779887
    the Free Software Foundation; either version 2 of the License, or
Packit Service 779887
    (at your option) any later version.
Packit Service 779887
Packit Service 779887
    This program is distributed in the hope that it will be useful,
Packit Service 779887
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 779887
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 779887
    GNU General Public License for more details.
Packit Service 779887
Packit Service 779887
    Authors:
Packit Service 779887
       Anton Arapov <anton@redhat.com>
Packit Service 779887
       Arjan van de Ven <arjan@linux.intel.com>
Packit Service 779887
 */
Packit Service 779887
#include "libreport_curl.h"
Packit Service 779887
#include "internal_libreport.h"
Packit Service 779887
Packit Service 779887
/* helpers */
Packit Service 779887
static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
Packit Service 779887
{
Packit Service 779887
    size *= nmemb;
Packit Service 779887
/*
Packit Service 779887
    char *c, *c1, *c2;
Packit Service 779887
Packit Service 779887
    log_warning("received: '%*.*s'", (int)size, (int)size, (char*)ptr);
Packit Service 779887
    c = (char*)xzalloc(size + 1);
Packit Service 779887
    memcpy(c, ptr, size);
Packit Service 779887
    c1 = strstr(c, "201 ");
Packit Service 779887
    if (c1)
Packit Service 779887
    {
Packit Service 779887
        c1 += 4;
Packit Service 779887
        c2 = strchr(c1, '\n');
Packit Service 779887
        if (c2)
Packit Service 779887
            *c2 = 0;
Packit Service 779887
    }
Packit Service 779887
    free(c);
Packit Service 779887
*/
Packit Service 779887
Packit Service 779887
    return size;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
/* Send oops data to kerneloops.org-style site, using HTTP POST */
Packit Service 779887
/* Returns 0 on success */
Packit Service 779887
static CURLcode http_post_to_kerneloops_site(const char *url, const char *oopsdata)
Packit Service 779887
{
Packit Service 779887
    CURLcode ret;
Packit Service 779887
    CURL *handle;
Packit Service 779887
    struct curl_httppost *post = NULL;
Packit Service 779887
    struct curl_httppost *last = NULL;
Packit Service 779887
    struct curl_slist *headers = NULL;
Packit Service 779887
Packit Service 779887
    handle = curl_easy_init();
Packit Service 779887
    if (!handle)
Packit Service 779887
        error_msg_and_die("Can't create curl handle");
Packit Service 779887
Packit Service 779887
    headers = curl_slist_append(headers, "Accept: */*");
Packit Service 779887
    headers = curl_slist_append(headers, "Expect:");
Packit Service 779887
Packit Service 779887
    curl_easy_setopt(handle, CURLOPT_URL, url);
Packit Service 779887
    curl_easy_setopt(handle, CURLOPT_FAILONERROR, 1L);
Packit Service 779887
    curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
Packit Service 779887
Packit Service 779887
    curl_formadd(&post, &last,
Packit Service 779887
            CURLFORM_COPYNAME, "oopsdata",
Packit Service 779887
            CURLFORM_COPYCONTENTS, oopsdata,
Packit Service 779887
            CURLFORM_END);
Packit Service 779887
    curl_formadd(&post, &last,
Packit Service 779887
            CURLFORM_COPYNAME, "pass_on_allowed",
Packit Service 779887
            CURLFORM_COPYCONTENTS, "yes",
Packit Service 779887
            CURLFORM_END);
Packit Service 779887
Packit Service 779887
    curl_easy_setopt(handle, CURLOPT_HTTPPOST, post);
Packit Service 779887
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writefunction);
Packit Service 779887
Packit Service 779887
    ret = curl_easy_perform_with_proxy(handle, url);
Packit Service 779887
Packit Service 779887
    curl_formfree(post);
Packit Service 779887
    curl_slist_free_all(headers);
Packit Service 779887
    curl_easy_cleanup(handle);
Packit Service 779887
Packit Service 779887
    return ret;
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
static void report_to_kerneloops(
Packit Service 779887
                const char *dump_dir_name,
Packit Service 779887
                map_string_t *settings)
Packit Service 779887
{
Packit Service 779887
    problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
Packit Service 779887
    if (!problem_data)
Packit Service 779887
        xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
Packit Service 779887
Packit Service 779887
    const char *backtrace = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE);
Packit Service 779887
    if (!backtrace)
Packit Service 779887
        error_msg_and_die("Error sending kernel oops due to missing backtrace");
Packit Service 779887
Packit Service 779887
    const char *env = getenv("KerneloopsReporter_SubmitURL");
Packit Service 779887
    const char *submitURL = (env ? env : get_map_string_item_or_empty(settings, "SubmitURL"));
Packit Service 779887
    if (!submitURL[0])
Packit Service 779887
        submitURL = "http://oops.kernel.org/submitoops.php";
Packit Service 779887
Packit Service 779887
    log_warning(_("Submitting oops report to %s"), submitURL);
Packit Service 779887
Packit Service 779887
    CURLcode ret = http_post_to_kerneloops_site(submitURL, backtrace);
Packit Service 779887
    if (ret != CURLE_OK)
Packit Service 779887
        error_msg_and_die("Kernel oops has not been sent due to %s", curl_easy_strerror(ret));
Packit Service 779887
Packit Service 779887
    problem_data_free(problem_data);
Packit Service 779887
Packit Service 779887
    /* Server replies with:
Packit Service 779887
     * 200 thank you for submitting the kernel oops information
Packit Service 779887
     * RemoteIP: 34192fd15e34bf60fac6a5f01bba04ddbd3f0558
Packit Service 779887
     * - no URL or bug ID apparently...
Packit Service 779887
     */
Packit Service 779887
    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
Packit Service 779887
    if (dd)
Packit Service 779887
    {
Packit Service 779887
        report_result_t rr = { .label = (char *)"kerneloops" };
Packit Service 779887
        rr.url = (char *)submitURL;
Packit Service 779887
        add_reported_to_entry(dd, &rr);
Packit Service 779887
        dd_close(dd);
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    log_warning("Kernel oops report was uploaded");
Packit Service 779887
}
Packit Service 779887
Packit Service 779887
int main(int argc, char **argv)
Packit Service 779887
{
Packit Service 779887
    abrt_init(argv);
Packit Service 779887
Packit Service 779887
    /* I18n */
Packit Service 779887
    setlocale(LC_ALL, "");
Packit Service 779887
#if ENABLE_NLS
Packit Service 779887
    bindtextdomain(PACKAGE, LOCALEDIR);
Packit Service 779887
    textdomain(PACKAGE);
Packit Service 779887
#endif
Packit Service 779887
Packit Service 779887
    map_string_t *settings = new_map_string();
Packit Service 779887
    const char *dump_dir_name = ".";
Packit Service 779887
    GList *conf_file = NULL;
Packit Service 779887
Packit Service 779887
    /* Can't keep these strings/structs static: _() doesn't support that */
Packit Service 779887
    const char *program_usage_string = _(
Packit Service 779887
        "& [-v] [-c CONFFILE]... -d DIR\n"
Packit Service 779887
        "\n"
Packit Service 779887
        "Reports kernel oops to kerneloops.org (or similar) site.\n"
Packit Service 779887
        "\n"
Packit Service 779887
        "Files with names listed in $EXCLUDE_FROM_REPORT are not included\n"
Packit Service 779887
        "into the tarball.\n"
Packit Service 779887
        "\n"
Packit Service 779887
        "CONFFILE lines should have 'PARAM = VALUE' format.\n"
Packit Service 779887
        "Recognized string parameter: SubmitURL.\n"
Packit Service 779887
        "Parameter can be overridden via $KerneloopsReporter_SubmitURL."
Packit Service 779887
    );
Packit Service 779887
    enum {
Packit Service 779887
        OPT_v = 1 << 0,
Packit Service 779887
        OPT_d = 1 << 1,
Packit Service 779887
        OPT_c = 1 << 2,
Packit Service 779887
    };
Packit Service 779887
    /* Keep enum above and order of options below in sync! */
Packit Service 779887
    struct options program_options[] = {
Packit Service 779887
        OPT__VERBOSE(&g_verbose),
Packit Service 779887
        OPT_STRING('d', NULL, &dump_dir_name, "DIR" , _("Problem directory")),
Packit Service 779887
        OPT_LIST(  'c', NULL, &conf_file    , "FILE", _("Configuration file")),
Packit Service 779887
        OPT_END()
Packit Service 779887
    };
Packit Service 779887
    /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string);
Packit Service 779887
Packit Service 779887
    export_abrt_envvars(0);
Packit Service 779887
Packit Service 779887
    while (conf_file)
Packit Service 779887
    {
Packit Service 779887
        char *fn = (char *)conf_file->data;
Packit Service 779887
        log_notice("Loading settings from '%s'", fn);
Packit Service 779887
        load_conf_file(fn, settings, /*skip key w/o values:*/ false);
Packit Service 779887
        log_debug("Loaded '%s'", fn);
Packit Service 779887
        conf_file = g_list_remove(conf_file, fn);
Packit Service 779887
    }
Packit Service 779887
Packit Service 779887
    report_to_kerneloops(dump_dir_name, settings);
Packit Service 779887
Packit Service 779887
    free_map_string(settings);
Packit Service 779887
    return 0;
Packit Service 779887
}