summaryrefslogtreecommitdiffstats
path: root/lib/Plugins/SOSreport.cpp
blob: fa10f813b200a3f69af3f971a7f9f6fee121f63f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
    SOSreport.cpp

    Copyright (C) 2009  RedHat inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    */

#include "SOSreport.h"

#include <stdio.h>
#include <string.h>
#include <ext/stdio_filebuf.h>

#include <fstream>
#include <sstream>

#include "DebugDump.h"
#include "ABRTException.h"
#include "CommLayerInner.h"


void CActionSOSreport::CopyFile(const std::string& pSourceName, const std::string& pDestName)
{
    std::ifstream source(pSourceName.c_str(), std::fstream::binary);

    if (!source)
    {
        throw CABRTException(EXCEP_PLUGIN, "CActionSOSreport::CopyFile(): could not open input sosreport filename:" + pSourceName);
    }
    std::ofstream dest(pDestName.c_str(),std::fstream::trunc|std::fstream::binary);
    if (!dest)
    {
        throw CABRTException(EXCEP_PLUGIN, "CActionSOSreport::CopyFile(): could not open output sosreport filename:" + pDestName);
    }
    dest << source.rdbuf();
}

void CActionSOSreport::ErrorCheck(const index_type pI)
{
    if (pI == std::string::npos)
    {
        throw CABRTException(EXCEP_PLUGIN, std::string("CActionSOSreport::ErrorCheck(): could not find filename in sosreport output"));
    }
}

std::string CActionSOSreport::ParseFilename(const std::string& pOutput)
{
    /*
    the sosreport's filename is embedded in sosreport's output.
    It appears on the line after the string in 'sosreport_filename_marker',
    it has leading spaces, and a trailing newline.  This function trims
    any leading and trailing whitespace from the filename.
    */
    static const char sosreport_filename_marker[] =
          "Your sosreport has been generated and saved in:";

    index_type p = pOutput.find(sosreport_filename_marker);
    ErrorCheck(p);

    p += strlen(sosreport_filename_marker);

    index_type filename_start = pOutput.find_first_not_of(" \n\t", p);
    ErrorCheck(p);

    index_type line_end = pOutput.find_first_of('\n',filename_start);
    ErrorCheck(p);

    index_type filename_end = pOutput.find_last_not_of(" \n\t",line_end);
    ErrorCheck(p);

    return pOutput.substr(filename_start,(filename_end-filename_start)+1);
}

void CActionSOSreport::Run(const std::string& pActionDir,
                           const std::string& pArgs)
{
    update_client("Executing SOSreportAction plugin...");

    const char command[] = "sosreport --batch --no-progressbar -k rpm.rpmva=off 2>&1";

    FILE *fp = popen(command, "r");
    if (fp == NULL)
    {
        throw CABRTException(EXCEP_PLUGIN, std::string("CActionSOSreport::Run(): cannot execute ") + command);
    }

    std::ostringstream output_stream;
    __gnu_cxx::stdio_filebuf<char> command_output_buffer(fp, std::ios_base::in);

    output_stream << std::string(command) << std::endl;
    output_stream << &command_output_buffer;

    pclose(fp);

    std::string output = output_stream.str();
    std::string sosreport_filename = ParseFilename(output);
    std::string sosreport_dd_filename = pActionDir + "/sosreport.tar.bz2";

    CDebugDump dd;
    dd.Open(pActionDir);
    CopyFile(sosreport_filename,sosreport_dd_filename);
    dd.Close();
}

PLUGIN_INFO(ACTION,
            CActionSOSreport,
            "SOSreport",
            "0.0.2",
            "Run sosreport, save the output in the crash dump",
            "gavin@redhat.com",
            "https://fedorahosted.org/abrt/wiki",
            "");