blob: 4cfa6e515dbb1da6377226bfc0f04108ca278447 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/forensics/utils/previous_boot_file.h"
#include <lib/syslog/cpp/macros.h>
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/fxl/strings/split_string.h"
namespace forensics {
PreviousBootFile PreviousBootFile::FromData(const bool is_first_instance, const std::string& file) {
return PreviousBootFile(is_first_instance, files::JoinPath("/tmp", file),
files::JoinPath("/data", file));
}
PreviousBootFile PreviousBootFile::FromCache(const bool is_first_instance,
const std::string& file) {
return PreviousBootFile(is_first_instance, files::JoinPath("/tmp", file),
files::JoinPath("/cache", file));
}
PreviousBootFile::PreviousBootFile(const bool is_first_instance, const std::string& to,
const std::string& from)
: current_boot_path_(from), previous_boot_path_(to) {
if (!is_first_instance) {
return;
}
// Bail if the file doesn't exist.
if (!files::IsFile(current_boot_path_)) {
return;
}
// Bail if the file can't be read.
std::string content;
if (!files::ReadFileToString(current_boot_path_, &content)) {
FX_LOGS(ERROR) << "Failed to read file " << current_boot_path_;
return;
}
// Create the directory in /tmp the file is in.
auto split_previous_boot_path =
fxl::SplitStringCopy(previous_boot_path_, "/", fxl::WhiteSpaceHandling::kKeepWhitespace,
fxl::SplitResult::kSplitWantNonEmpty);
// Drop the file name from the path.
if (!split_previous_boot_path.empty()) {
split_previous_boot_path.pop_back();
}
// Create the directory.
if (!split_previous_boot_path.empty()) {
files::CreateDirectory(fxl::JoinStrings(split_previous_boot_path, "/"));
}
// Copy the file content – we cannot move as the two files are under different namespaces.
if (!files::WriteFile(previous_boot_path_, content.c_str(), content.size())) {
FX_LOGS(ERROR) << "Failed to write file " << previous_boot_path_;
return;
}
// Delete the original file.
if (!files::DeletePath(current_boot_path_, /*recursive=*/true)) {
FX_LOGS(ERROR) << "Failed to delete " << current_boot_path_;
}
}
} // namespace forensics