blob: ab22f6fa15ca277e26eada76dba65b1ca415988b [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "syzygy/poirot/poirot_app.h"
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
namespace poirot {
namespace {
const char kUsageFormatStr[] =
"Usage: %ls [options]\n"
"\n"
" Read a minidump and extract the Kasko protobuf that is in it.\n"
"\n"
"Required parameters\n"
" --input-minidump=<image file>\n"
" The minidump to process.\n"
"Optional parameters\n"
" --output-file=<output file>\n"
" Optionally provide the name or path to the output file. If not\n"
" provided, output will be to standard out.\n";
} // namespace
void PoirotApp::PrintUsage(const base::FilePath& program,
const base::StringPiece& message) {
if (!message.empty()) {
::fwrite(message.data(), 1, message.length(), out());
::fprintf(out(), "\n\n");
}
::fprintf(out(), kUsageFormatStr, program.BaseName().value().c_str());
}
bool PoirotApp::ParseCommandLine(const base::CommandLine* cmd_line) {
DCHECK_NE(static_cast<const base::CommandLine*>(nullptr), cmd_line);
if (cmd_line->HasSwitch("help")) {
PrintUsage(cmd_line->GetProgram(), "");
return false;
}
input_minidump_ = cmd_line->GetSwitchValuePath("input-minidump");
if (input_minidump_.empty()) {
PrintUsage(cmd_line->GetProgram(),
"Must specify '--input-minidump' parameter!");
return false;
}
// If no output file is specified stdout will be used.
output_file_ = cmd_line->GetSwitchValuePath("output-file");
return true;
}
int PoirotApp::Run() {
// Output defaults to STDOUT.
FILE* output_file = stdout;
// If an output file is specified, make sure we close it on exit.
base::ScopedFILE scoped_file;
// Open the output file, if one is provided. This is done early so as to fail
// fast on problems with the output file or path.
if (!output_file_.empty()) {
scoped_file.reset(base::OpenFile(output_file_, "w"));
if (!scoped_file.get()) {
LOG(ERROR) << "Unable to open output file '" << output_file_.value()
<< "'.";
return 1;
}
output_file = scoped_file.get();
}
// Do the processing.
MinidumpProcessor processor(input_minidump_);
if (!processor.ProcessDump())
return 1;
// And write the output file.
if (!processor.GenerateJsonOutput(output_file))
return 1;
return 0;
}
} // namespace poirot