//
// Copyright (C) 2012 The Android Open Source Project
//
// 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 "update_engine/common/utils.h"

#include <stdint.h>

#include <dirent.h>
#include <elf.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/resource.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <algorithm>
#include <filesystem>
#include <utility>
#include <vector>

#include <android-base/strings.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/format_macros.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/rand_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/data_encoding.h>

#include "update_engine/common/constants.h"
#include "update_engine/common/subprocess.h"
#ifdef __ANDROID__
#include "update_engine/common/platform_constants.h"
#endif
#include "update_engine/payload_consumer/file_descriptor.h"

using base::Time;
using base::TimeDelta;
using std::min;
using std::numeric_limits;
using std::string;
using std::vector;

namespace chromeos_update_engine {

namespace {

// The following constants control how UnmountFilesystem should retry if
// umount() fails with an errno EBUSY, i.e. retry 5 times over the course of
// one second.
const int kUnmountMaxNumOfRetries = 5;
const int kUnmountRetryIntervalInMicroseconds = 200 * 1000;  // 200 ms

// Number of bytes to read from a file to attempt to detect its contents. Used
// in GetFileFormat.
const int kGetFileFormatMaxHeaderSize = 32;

// The path to the kernel's boot_id.
const char kBootIdPath[] = "/proc/sys/kernel/random/boot_id";

// If |path| is absolute, or explicit relative to the current working directory,
// leaves it as is. Otherwise, uses the system's temp directory, as defined by
// base::GetTempDir() and prepends it to |path|. On success stores the full
// temporary path in |template_path| and returns true.
bool GetTempName(const string& path, base::FilePath* template_path) {
  if (path[0] == '/' ||
      base::StartsWith(path, "./", base::CompareCase::SENSITIVE) ||
      base::StartsWith(path, "../", base::CompareCase::SENSITIVE)) {
    *template_path = base::FilePath(path);
    return true;
  }

  base::FilePath temp_dir;
#ifdef __ANDROID__
  temp_dir = base::FilePath(constants::kNonVolatileDirectory).Append("tmp");
#else
  TEST_AND_RETURN_FALSE(base::GetTempDir(&temp_dir));
#endif  // __ANDROID__
  if (!base::PathExists(temp_dir))
    TEST_AND_RETURN_FALSE(base::CreateDirectory(temp_dir));
  *template_path = temp_dir.Append(path);
  return true;
}

}  // namespace

namespace utils {

bool WriteFile(const char* path, const void* data, size_t data_len) {
  int fd = HANDLE_EINTR(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600));
  TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
  ScopedFdCloser fd_closer(&fd);
  return WriteAll(fd, data, data_len);
}

bool ReadAll(
    int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof) {
  char* c_buf = static_cast<char*>(buf);
  size_t bytes_read = 0;
  *eof = false;
  while (bytes_read < count) {
    ssize_t rc = HANDLE_EINTR(read(fd, c_buf + bytes_read, count - bytes_read));
    if (rc < 0) {
      // EAGAIN and EWOULDBLOCK are normal return values when there's no more
      // input and we are in non-blocking mode.
      if (errno != EWOULDBLOCK && errno != EAGAIN) {
        PLOG(ERROR) << "Error reading fd " << fd;
        *out_bytes_read = bytes_read;
        return false;
      }
      break;
    } else if (rc == 0) {
      // A value of 0 means that we reached EOF and there is nothing else to
      // read from this fd.
      *eof = true;
      break;
    } else {
      bytes_read += rc;
    }
  }
  *out_bytes_read = bytes_read;
  return true;
}

bool WriteAll(int fd, const void* buf, size_t count) {
  const char* c_buf = static_cast<const char*>(buf);
  ssize_t bytes_written = 0;
  while (bytes_written < static_cast<ssize_t>(count)) {
    ssize_t rc = write(fd, c_buf + bytes_written, count - bytes_written);
    TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
    bytes_written += rc;
  }
  return true;
}

bool PWriteAll(int fd, const void* buf, size_t count, off_t offset) {
  const char* c_buf = static_cast<const char*>(buf);
  size_t bytes_written = 0;
  int num_attempts = 0;
  while (bytes_written < count) {
    num_attempts++;
    ssize_t rc = pwrite(fd,
                        c_buf + bytes_written,
                        count - bytes_written,
                        offset + bytes_written);
    // TODO(garnold) for debugging failure in chromium-os:31077; to be removed.
    if (rc < 0) {
      PLOG(ERROR) << "pwrite error; num_attempts=" << num_attempts
                  << " bytes_written=" << bytes_written << " count=" << count
                  << " offset=" << offset;
    }
    TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
    bytes_written += rc;
  }
  return true;
}

bool WriteAll(FileDescriptor* fd, const void* buf, size_t count) {
  const char* c_buf = static_cast<const char*>(buf);
  ssize_t bytes_written = 0;
  while (bytes_written < static_cast<ssize_t>(count)) {
    ssize_t rc = fd->Write(c_buf + bytes_written, count - bytes_written);
    TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
    bytes_written += rc;
  }
  return true;
}

bool WriteAll(const FileDescriptorPtr& fd,
              const void* buf,
              size_t count,
              off_t offset) {
  TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(offset, SEEK_SET) !=
                              static_cast<off_t>(-1));
  return WriteAll(fd, buf, count);
}

bool PReadAll(
    int fd, void* buf, size_t count, off_t offset, ssize_t* out_bytes_read) {
  char* c_buf = static_cast<char*>(buf);
  ssize_t bytes_read = 0;
  while (bytes_read < static_cast<ssize_t>(count)) {
    ssize_t rc =
        pread(fd, c_buf + bytes_read, count - bytes_read, offset + bytes_read);
    TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
    if (rc == 0) {
      break;
    }
    bytes_read += rc;
  }
  *out_bytes_read = bytes_read;
  return true;
}

bool ReadAll(FileDescriptor* fd,
             void* buf,
             size_t count,
             off_t offset,
             ssize_t* out_bytes_read) {
  TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(offset, SEEK_SET) !=
                              static_cast<off_t>(-1));
  char* c_buf = static_cast<char*>(buf);
  ssize_t bytes_read = 0;
  while (bytes_read < static_cast<ssize_t>(count)) {
    ssize_t rc = fd->Read(c_buf + bytes_read, count - bytes_read);
    TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
    if (rc == 0) {
      break;
    }
    bytes_read += rc;
  }
  *out_bytes_read = bytes_read;
  return true;
}

bool PReadAll(FileDescriptor* fd,
              void* buf,
              size_t count,
              off_t offset,
              ssize_t* out_bytes_read) {
  auto old_off = fd->Seek(0, SEEK_CUR);
  TEST_AND_RETURN_FALSE_ERRNO(old_off >= 0);

  auto success = ReadAll(fd, buf, count, offset, out_bytes_read);
  TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(old_off, SEEK_SET) == old_off);
  return success;
}

bool PWriteAll(const FileDescriptorPtr& fd,
               const void* buf,
               size_t count,
               off_t offset) {
  auto old_off = fd->Seek(0, SEEK_CUR);
  TEST_AND_RETURN_FALSE_ERRNO(old_off >= 0);

  auto success = WriteAll(fd, buf, count, offset);
  TEST_AND_RETURN_FALSE_ERRNO(fd->Seek(old_off, SEEK_SET) == old_off);
  return success;
}

// Append |nbytes| of content from |buf| to the vector pointed to by either
// |vec_p| or |str_p|.
static void AppendBytes(const uint8_t* buf,
                        size_t nbytes,
                        brillo::Blob* vec_p) {
  CHECK(buf);
  CHECK(vec_p);
  vec_p->insert(vec_p->end(), buf, buf + nbytes);
}
static void AppendBytes(const uint8_t* buf, size_t nbytes, string* str_p) {
  CHECK(buf);
  CHECK(str_p);
  str_p->append(buf, buf + nbytes);
}

// Reads from an open file |fp|, appending the read content to the container
// pointer to by |out_p|.  Returns true upon successful reading all of the
// file's content, false otherwise. If |size| is not -1, reads up to |size|
// bytes.
template <class T>
static bool Read(FILE* fp, off_t size, T* out_p) {
  CHECK(fp);
  CHECK(size == -1 || size >= 0);
  uint8_t buf[1024];
  while (size == -1 || size > 0) {
    off_t bytes_to_read = sizeof(buf);
    if (size > 0 && bytes_to_read > size) {
      bytes_to_read = size;
    }
    size_t nbytes = fread(buf, 1, bytes_to_read, fp);
    if (!nbytes) {
      break;
    }
    AppendBytes(buf, nbytes, out_p);
    if (size != -1) {
      CHECK(size >= static_cast<off_t>(nbytes));
      size -= nbytes;
    }
  }
  if (ferror(fp)) {
    return false;
  }
  return size == 0 || feof(fp);
}

// Opens a file |path| for reading and appends its the contents to a container
// |out_p|. Starts reading the file from |offset|. If |offset| is beyond the end
// of the file, returns success. If |size| is not -1, reads up to |size| bytes.
template <class T>
static bool ReadFileChunkAndAppend(const string& path,
                                   off_t offset,
                                   off_t size,
                                   T* out_p) {
  CHECK_GE(offset, 0);
  CHECK(size == -1 || size >= 0);
  base::ScopedFILE fp(fopen(path.c_str(), "r"));
  if (!fp.get())
    return false;
  if (offset) {
    // Return success without appending any data if a chunk beyond the end of
    // the file is requested.
    if (offset >= FileSize(path)) {
      return true;
    }
    TEST_AND_RETURN_FALSE_ERRNO(fseek(fp.get(), offset, SEEK_SET) == 0);
  }
  return Read(fp.get(), size, out_p);
}

// TODO(deymo): This is only used in unittest, but requires the private
// Read<string>() defined here. Expose Read<string>() or move to base/ version.
bool ReadPipe(const string& cmd, string* out_p) {
  FILE* fp = popen(cmd.c_str(), "r");
  if (!fp)
    return false;
  bool success = Read(fp, -1, out_p);
  return (success && pclose(fp) >= 0);
}

bool ReadFile(const string& path, brillo::Blob* out_p) {
  return ReadFileChunkAndAppend(path, 0, -1, out_p);
}

bool ReadFile(const string& path, string* out_p) {
  return ReadFileChunkAndAppend(path, 0, -1, out_p);
}

bool ReadFileChunk(const string& path,
                   off_t offset,
                   off_t size,
                   brillo::Blob* out_p) {
  return ReadFileChunkAndAppend(path, offset, size, out_p);
}

off_t BlockDevSize(int fd) {
  uint64_t dev_size{};
  int rc = ioctl(fd, BLKGETSIZE64, &dev_size);
  if (rc == -1) {
    dev_size = -1;
    PLOG(ERROR) << "Error running ioctl(BLKGETSIZE64) on " << fd;
  }
  return dev_size;
}

off_t FileSize(int fd) {
  struct stat stbuf {};
  int rc = fstat(fd, &stbuf);
  CHECK_EQ(rc, 0);
  if (rc < 0) {
    PLOG(ERROR) << "Error stat-ing " << fd;
    return rc;
  }
  if (S_ISREG(stbuf.st_mode))
    return stbuf.st_size;
  if (S_ISBLK(stbuf.st_mode))
    return BlockDevSize(fd);
  LOG(ERROR) << "Couldn't determine the type of " << fd;
  return -1;
}

off_t FileSize(const string& path) {
  int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
  if (fd == -1) {
    PLOG(ERROR) << "Error opening " << path;
    return fd;
  }
  off_t size = FileSize(fd);
  if (size == -1)
    PLOG(ERROR) << "Error getting file size of " << path;
  close(fd);
  return size;
}

bool SendFile(int out_fd, int in_fd, size_t count) {
  off64_t offset = lseek(in_fd, 0, SEEK_CUR);
  TEST_AND_RETURN_FALSE_ERRNO(offset >= 0);
  constexpr size_t BUFFER_SIZE = 4096;
  while (count > 0) {
    const auto bytes_written =
        sendfile(out_fd, in_fd, &offset, std::min(count, BUFFER_SIZE));
    TEST_AND_RETURN_FALSE_ERRNO(bytes_written > 0);
    count -= bytes_written;
  }
  return true;
}

bool DeleteDirectory(const char* dirname) {
  const std::string tmpdir = std::string(dirname) + "_deleted";
  std::filesystem::remove_all(tmpdir);
  if (rename(dirname, tmpdir.c_str()) != 0) {
    PLOG(ERROR) << "Failed to rename " << dirname << " to " << tmpdir;
    return false;
  }
  std::filesystem::remove_all(tmpdir);
  return true;
}

bool FsyncDirectory(const char* dirname) {
  android::base::unique_fd fd(
      TEMP_FAILURE_RETRY(open(dirname, O_RDONLY | O_CLOEXEC)));
  if (fd == -1) {
    PLOG(ERROR) << "Failed to open " << dirname;
    return false;
  }
  if (fsync(fd) == -1) {
    if (errno == EROFS || errno == EINVAL) {
      PLOG(WARNING) << "Skip fsync " << dirname
                    << " on a file system does not support synchronization";
    } else {
      PLOG(ERROR) << "Failed to fsync " << dirname;
      return false;
    }
  }
  return true;
}

bool WriteStringToFileAtomic(const std::string& path,
                             std::string_view content) {
  const std::string tmp_path = path + ".tmp";
  {
    const int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC;
    android::base::unique_fd fd(
        TEMP_FAILURE_RETRY(open(tmp_path.c_str(), flags, 0644)));
    if (fd == -1) {
      PLOG(ERROR) << "Failed to open " << path;
      return false;
    }
    if (!WriteAll(fd.get(), content.data(), content.size())) {
      PLOG(ERROR) << "Failed to write to fd " << fd;
      return false;
    }
    // rename() without fsync() is not safe. Data could still be living on page
    // cache. To ensure atomiticity, call fsync()
    if (fsync(fd) != 0) {
      PLOG(ERROR) << "Failed to fsync " << tmp_path;
    }
  }
  if (rename(tmp_path.c_str(), path.c_str()) == -1) {
    PLOG(ERROR) << "rename failed from " << tmp_path << " to " << path;
    return false;
  }
  return FsyncDirectory(std::filesystem::path(path).parent_path().c_str());
}

void HexDumpArray(const uint8_t* const arr, const size_t length) {
  LOG(INFO) << "Logging array of length: " << length;
  const unsigned int bytes_per_line = 16;
  for (uint32_t i = 0; i < length; i += bytes_per_line) {
    const unsigned int bytes_remaining = length - i;
    const unsigned int bytes_per_this_line =
        min(bytes_per_line, bytes_remaining);
    char header[100];
    int r = snprintf(header, sizeof(header), "0x%08x : ", i);
    TEST_AND_RETURN(r == 13);
    string line = header;
    for (unsigned int j = 0; j < bytes_per_this_line; j++) {
      char buf[20];
      uint8_t c = arr[i + j];
      r = snprintf(buf, sizeof(buf), "%02x ", static_cast<unsigned int>(c));
      TEST_AND_RETURN(r == 3);
      line += buf;
    }
    LOG(INFO) << line;
  }
}

bool SplitPartitionName(const string& partition_name,
                        string* out_disk_name,
                        int* out_partition_num) {
  if (!base::StartsWith(
          partition_name, "/dev/", base::CompareCase::SENSITIVE)) {
    LOG(ERROR) << "Invalid partition device name: " << partition_name;
    return false;
  }

  size_t last_nondigit_pos = partition_name.find_last_not_of("0123456789");
  if (last_nondigit_pos == string::npos ||
      (last_nondigit_pos + 1) == partition_name.size()) {
    LOG(ERROR) << "Unable to parse partition device name: " << partition_name;
    return false;
  }

  if (out_disk_name) {
    // Special case for MMC devices which have the following naming scheme:
    // mmcblk0p2
    size_t disk_name_len = last_nondigit_pos;
    if (partition_name[last_nondigit_pos] != 'p' || last_nondigit_pos == 0 ||
        !isdigit(partition_name[last_nondigit_pos - 1])) {
      disk_name_len++;
    }
    *out_disk_name = partition_name.substr(0, disk_name_len);
  }

  if (out_partition_num) {
    string partition_str = partition_name.substr(last_nondigit_pos + 1);
    *out_partition_num = atoi(partition_str.c_str());
  }
  return true;
}

string MakePartitionName(const string& disk_name, int partition_num) {
  if (partition_num < 1) {
    LOG(ERROR) << "Invalid partition number: " << partition_num;
    return string();
  }

  if (!base::StartsWith(disk_name, "/dev/", base::CompareCase::SENSITIVE)) {
    LOG(ERROR) << "Invalid disk name: " << disk_name;
    return string();
  }

  string partition_name = disk_name;
  if (isdigit(partition_name.back())) {
    // Special case for devices with names ending with a digit.
    // Add "p" to separate the disk name from partition number,
    // e.g. "/dev/loop0p2"
    partition_name += 'p';
  }

  partition_name += std::to_string(partition_num);

  return partition_name;
}

bool FileExists(const char* path) {
  struct stat stbuf {};
  return 0 == lstat(path, &stbuf);
}

bool IsSymlink(const char* path) {
  struct stat stbuf {};
  return lstat(path, &stbuf) == 0 && S_ISLNK(stbuf.st_mode) != 0;
}

bool IsRegFile(const char* path) {
  struct stat stbuf {};
  return lstat(path, &stbuf) == 0 && S_ISREG(stbuf.st_mode) != 0;
}

bool MakeTempFile(const string& base_filename_template,
                  string* filename,
                  int* fd) {
  base::FilePath filename_template;
  TEST_AND_RETURN_FALSE(
      GetTempName(base_filename_template, &filename_template));
  DCHECK(filename || fd);
  vector<char> buf(filename_template.value().size() + 1);
  memcpy(buf.data(),
         filename_template.value().data(),
         filename_template.value().size());
  buf[filename_template.value().size()] = '\0';

  int mkstemp_fd = mkstemp(buf.data());
  TEST_AND_RETURN_FALSE_ERRNO(mkstemp_fd >= 0);
  if (filename) {
    *filename = buf.data();
  }
  if (fd) {
    *fd = mkstemp_fd;
  } else {
    close(mkstemp_fd);
  }
  return true;
}

bool SetBlockDeviceReadOnly(const string& device, bool read_only) {
  int fd = HANDLE_EINTR(open(device.c_str(), O_RDONLY | O_CLOEXEC));
  if (fd < 0) {
    PLOG(ERROR) << "Opening block device " << device;
    return false;
  }
  ScopedFdCloser fd_closer(&fd);
  // We take no action if not needed.
  int read_only_flag{};
  int expected_flag = read_only ? 1 : 0;
  int rc = ioctl(fd, BLKROGET, &read_only_flag);
  // In case of failure reading the setting we will try to set it anyway.
  if (rc == 0 && read_only_flag == expected_flag)
    return true;

  rc = ioctl(fd, BLKROSET, &expected_flag);
  if (rc != 0) {
    PLOG(ERROR) << "Marking block device " << device
                << " as read_only=" << expected_flag;
    return false;
  }

  /*
   * Read back the value to check if it is configured successfully.
   * If fail, use the second method, set the file
   * /sys/block/<partition_name>/force_ro
   * to config the read only property.
   */
  rc = ioctl(fd, BLKROGET, &read_only_flag);
  if (rc != 0) {
    PLOG(ERROR) << "Failed to read back block device read-only value:" << device;
    return false;
  }
  if (read_only_flag == expected_flag) {
    return true;
  }

  std::array<char, PATH_MAX> device_name;
  char *pdevice = realpath(device.c_str(), device_name.data());
  TEST_AND_RETURN_FALSE_ERRNO(pdevice);

  std::string real_path(pdevice);
  std::size_t offset = real_path.find_last_of('/');
  if (offset == std::string::npos){
    LOG(ERROR) << "Could not find partition name from " << real_path;
    return false;
  }
  const std::string partition_name = real_path.substr(offset + 1);

  std::string force_ro_file = "/sys/block/" + partition_name + "/force_ro";
  android::base::unique_fd fd_force_ro {
    HANDLE_EINTR(open(force_ro_file.c_str(), O_WRONLY | O_CLOEXEC))};
  TEST_AND_RETURN_FALSE_ERRNO(fd_force_ro >= 0);

  rc = write(fd_force_ro, expected_flag ? "1" : "0", 1);
  TEST_AND_RETURN_FALSE_ERRNO(rc > 0);

  // Read back again
  rc = ioctl(fd, BLKROGET, &read_only_flag);
  if (rc != 0) {
    PLOG(ERROR) << "Failed to read back block device read-only value:" << device;
    return false;
  }
  if (read_only_flag != expected_flag) {
    LOG(ERROR) << "After modifying force_ro, marking block device " << device
                << " as read_only=" << expected_flag;
    return false;
  }
  return true;
}

bool MountFilesystem(const string& device,
                     const string& mountpoint,
                     unsigned long mountflags,  // NOLINT(runtime/int)
                     const string& type,
                     const string& fs_mount_options) {
  vector<const char*> fstypes;
  if (type.empty()) {
    fstypes = {"ext2", "ext3", "ext4", "squashfs", "erofs"};
  } else {
    fstypes = {type.c_str()};
  }
  for (const char* fstype : fstypes) {
    int rc = mount(device.c_str(),
                   mountpoint.c_str(),
                   fstype,
                   mountflags,
                   fs_mount_options.c_str());
    if (rc == 0)
      return true;

    PLOG(WARNING) << "Unable to mount destination device " << device << " on "
                  << mountpoint << " as " << fstype;
  }
  if (!type.empty()) {
    LOG(ERROR) << "Unable to mount " << device << " with any supported type";
  }
  return false;
}

bool UnmountFilesystem(const string& mountpoint) {
  int num_retries = 1;
  for (;; ++num_retries) {
    if (umount(mountpoint.c_str()) == 0)
      return true;
    if (errno != EBUSY || num_retries >= kUnmountMaxNumOfRetries)
      break;
    usleep(kUnmountRetryIntervalInMicroseconds);
  }
  if (errno == EINVAL) {
    LOG(INFO) << "Not a mountpoint: " << mountpoint;
    return false;
  }
  PLOG(WARNING) << "Error unmounting " << mountpoint << " after " << num_retries
                << " attempts. Lazy unmounting instead, error was";
  if (umount2(mountpoint.c_str(), MNT_DETACH) != 0) {
    PLOG(ERROR) << "Lazy unmount failed";
    return false;
  }
  return true;
}

bool IsMountpoint(const std::string& mountpoint) {
  struct stat stdir {
  }, stparent{};

  // Check whether the passed mountpoint is a directory and the /.. is in the
  // same device or not. If mountpoint/.. is in a different device it means that
  // there is a filesystem mounted there. If it is not, but they both point to
  // the same inode it basically is the special case of /.. pointing to /. This
  // test doesn't play well with bind mount but that's out of the scope of what
  // we want to detect here.
  if (lstat(mountpoint.c_str(), &stdir) != 0) {
    PLOG(ERROR) << "Error stat'ing " << mountpoint;
    return false;
  }
  if (!S_ISDIR(stdir.st_mode))
    return false;

  base::FilePath parent(mountpoint);
  parent = parent.Append("..");
  if (lstat(parent.value().c_str(), &stparent) != 0) {
    PLOG(ERROR) << "Error stat'ing " << parent.value();
    return false;
  }
  return S_ISDIR(stparent.st_mode) &&
         (stparent.st_dev != stdir.st_dev || stparent.st_ino == stdir.st_ino);
}

// Tries to parse the header of an ELF file to obtain a human-readable
// description of it on the |output| string.
static bool GetFileFormatELF(const uint8_t* buffer,
                             size_t size,
                             string* output) {
  // 0x00: EI_MAG - ELF magic header, 4 bytes.
  if (size < SELFMAG || memcmp(buffer, ELFMAG, SELFMAG) != 0)
    return false;
  *output = "ELF";

  // 0x04: EI_CLASS, 1 byte.
  if (size < EI_CLASS + 1)
    return true;
  switch (buffer[EI_CLASS]) {
    case ELFCLASS32:
      *output += " 32-bit";
      break;
    case ELFCLASS64:
      *output += " 64-bit";
      break;
    default:
      *output += " ?-bit";
  }

  // 0x05: EI_DATA, endianness, 1 byte.
  if (size < EI_DATA + 1)
    return true;
  uint8_t ei_data = buffer[EI_DATA];
  switch (ei_data) {
    case ELFDATA2LSB:
      *output += " little-endian";
      break;
    case ELFDATA2MSB:
      *output += " big-endian";
      break;
    default:
      *output += " ?-endian";
      // Don't parse anything after the 0x10 offset if endianness is unknown.
      return true;
  }

  const Elf32_Ehdr* hdr = reinterpret_cast<const Elf32_Ehdr*>(buffer);
  // 0x12: e_machine, 2 byte endianness based on ei_data. The position (0x12)
  // and size is the same for both 32 and 64 bits.
  if (size < offsetof(Elf32_Ehdr, e_machine) + sizeof(hdr->e_machine))
    return true;
  uint16_t e_machine{};
  // Fix endianness regardless of the host endianness.
  if (ei_data == ELFDATA2LSB)
    e_machine = le16toh(hdr->e_machine);
  else
    e_machine = be16toh(hdr->e_machine);

  switch (e_machine) {
    case EM_386:
      *output += " x86";
      break;
    case EM_MIPS:
      *output += " mips";
      break;
    case EM_ARM:
      *output += " arm";
      break;
    case EM_X86_64:
      *output += " x86-64";
      break;
    default:
      *output += " unknown-arch";
  }
  return true;
}

string GetFileFormat(const string& path) {
  brillo::Blob buffer;
  if (!ReadFileChunkAndAppend(path, 0, kGetFileFormatMaxHeaderSize, &buffer))
    return "File not found.";

  string result;
  if (GetFileFormatELF(buffer.data(), buffer.size(), &result))
    return result;

  return "data";
}

int FuzzInt(int value, unsigned int range) {
  int min = value - range / 2;
  int max = value + range - range / 2;
  return base::RandInt(min, max);
}

string FormatSecs(unsigned secs) {
  return FormatTimeDelta(TimeDelta::FromSeconds(secs));
}

string FormatTimeDelta(TimeDelta delta) {
  string str;

  // Handle negative durations by prefixing with a minus.
  if (delta.ToInternalValue() < 0) {
    delta *= -1;
    str = "-";
  }

  // Canonicalize into days, hours, minutes, seconds and microseconds.
  unsigned days = delta.InDays();
  delta -= TimeDelta::FromDays(days);
  unsigned hours = delta.InHours();
  delta -= TimeDelta::FromHours(hours);
  unsigned mins = delta.InMinutes();
  delta -= TimeDelta::FromMinutes(mins);
  unsigned secs = delta.InSeconds();
  delta -= TimeDelta::FromSeconds(secs);
  unsigned usecs = delta.InMicroseconds();

  if (days)
    base::StringAppendF(&str, "%ud", days);
  if (days || hours)
    base::StringAppendF(&str, "%uh", hours);
  if (days || hours || mins)
    base::StringAppendF(&str, "%um", mins);
  base::StringAppendF(&str, "%u", secs);
  if (usecs) {
    int width = 6;
    while ((usecs / 10) * 10 == usecs) {
      usecs /= 10;
      width--;
    }
    base::StringAppendF(&str, ".%0*u", width, usecs);
  }
  base::StringAppendF(&str, "s");
  return str;
}

string ToString(const Time utc_time) {
  Time::Exploded exp_time{};
  utc_time.UTCExplode(&exp_time);
  return base::StringPrintf("%d/%d/%d %d:%02d:%02d GMT",
                            exp_time.month,
                            exp_time.day_of_month,
                            exp_time.year,
                            exp_time.hour,
                            exp_time.minute,
                            exp_time.second);
}

string ToString(bool b) {
  return (b ? "true" : "false");
}

string ToString(DownloadSource source) {
  switch (source) {
    case kDownloadSourceHttpsServer:
      return "HttpsServer";
    case kDownloadSourceHttpServer:
      return "HttpServer";
    case kDownloadSourceHttpPeer:
      return "HttpPeer";
    case kNumDownloadSources:
      return "Unknown";
      // Don't add a default case to let the compiler warn about newly added
      // download sources which should be added here.
  }

  return "Unknown";
}

string ToString(PayloadType payload_type) {
  switch (payload_type) {
    case kPayloadTypeDelta:
      return "Delta";
    case kPayloadTypeFull:
      return "Full";
    case kPayloadTypeForcedFull:
      return "ForcedFull";
    case kNumPayloadTypes:
      return "Unknown";
      // Don't add a default case to let the compiler warn about newly added
      // payload types which should be added here.
  }

  return "Unknown";
}

ErrorCode GetBaseErrorCode(ErrorCode code) {
  // Ignore the higher order bits in the code by applying the mask as
  // we want the enumerations to be in the small contiguous range
  // with values less than ErrorCode::kUmaReportedMax.
  ErrorCode base_code = static_cast<ErrorCode>(
      static_cast<int>(code) & ~static_cast<int>(ErrorCode::kSpecialFlags));

  // Make additional adjustments required for UMA and error classification.
  // TODO(jaysri): Move this logic to UeErrorCode.cc when we fix
  // chromium-os:34369.
  if (base_code >= ErrorCode::kOmahaRequestHTTPResponseBase) {
    // Since we want to keep the enums to a small value, aggregate all HTTP
    // errors into this one bucket for UMA and error classification purposes.
    LOG(INFO) << "Converting error code " << base_code
              << " to ErrorCode::kOmahaErrorInHTTPResponse";
    base_code = ErrorCode::kOmahaErrorInHTTPResponse;
  }

  return base_code;
}

string StringVectorToString(const vector<string>& vec_str) {
  string str = "[";
  for (vector<string>::const_iterator i = vec_str.begin(); i != vec_str.end();
       ++i) {
    if (i != vec_str.begin())
      str += ", ";
    str += '"';
    str += *i;
    str += '"';
  }
  str += "]";
  return str;
}

// The P2P file id should be the same for devices running new version and old
// version so that they can share it with each other. The hash in the response
// was base64 encoded, but now that we switched to use "hash_sha256" field which
// is hex encoded, we have to convert them back to base64 for P2P. However, the
// base64 encoded hash was base64 encoded here again historically for some
// reason, so we keep the same behavior here.
string CalculateP2PFileId(const brillo::Blob& payload_hash,
                          size_t payload_size) {
  string encoded_hash = brillo::data_encoding::Base64Encode(
      brillo::data_encoding::Base64Encode(payload_hash));
  return base::StringPrintf("cros_update_size_%" PRIuS "_hash_%s",
                            payload_size,
                            encoded_hash.c_str());
}

bool ConvertToOmahaInstallDate(Time time, int* out_num_days) {
  time_t unix_time = time.ToTimeT();
  // Output of: date +"%s" --date="Jan 1, 2007 0:00 PST".
  const time_t kOmahaEpoch = 1167638400;
  const int64_t kNumSecondsPerWeek = 7 * 24 * 3600;
  const int64_t kNumDaysPerWeek = 7;

  time_t omaha_time = unix_time - kOmahaEpoch;

  if (omaha_time < 0)
    return false;

  // Note, as per the comment in utils.h we are deliberately not
  // handling DST correctly.

  int64_t num_weeks_since_omaha_epoch = omaha_time / kNumSecondsPerWeek;
  *out_num_days = num_weeks_since_omaha_epoch * kNumDaysPerWeek;

  return true;
}

bool GetMinorVersion(const brillo::KeyValueStore& store,
                     uint32_t* minor_version) {
  string result;
  if (store.GetString("PAYLOAD_MINOR_VERSION", &result)) {
    if (!base::StringToUint(result, minor_version)) {
      LOG(ERROR) << "StringToUint failed when parsing delta minor version.";
      return false;
    }
    return true;
  }
  return false;
}

bool ReadExtents(const std::string& path,
                 const google::protobuf::RepeatedPtrField<Extent>& extents,
                 brillo::Blob* out_data,
                 size_t block_size) {
  return ReadExtents(path,
                     {extents.begin(), extents.end()},
                     out_data,
                     utils::BlocksInExtents(extents) * block_size,
                     block_size);
}

bool WriteExtents(const std::string& path,
                  const google::protobuf::RepeatedPtrField<Extent>& extents,
                  const brillo::Blob& data,
                  size_t block_size) {
  EintrSafeFileDescriptor fd;
  TEST_AND_RETURN_FALSE(fd.Open(path.c_str(), O_RDWR));
  size_t bytes_written = 0;
  for (const auto& ext : extents) {
    TEST_AND_RETURN_FALSE_ERRNO(
        fd.Seek(ext.start_block() * block_size, SEEK_SET));
    TEST_AND_RETURN_FALSE_ERRNO(
        fd.Write(data.data() + bytes_written, ext.num_blocks() * block_size));
    bytes_written += ext.num_blocks() * block_size;
  }
  return true;
}
bool ReadExtents(const std::string& path,
                 const vector<Extent>& extents,
                 brillo::Blob* out_data,
                 ssize_t out_data_size,
                 size_t block_size) {
  FileDescriptorPtr fd = std::make_shared<EintrSafeFileDescriptor>();
  fd->Open(path.c_str(), O_RDONLY);
  return ReadExtents(fd, extents, out_data, out_data_size, block_size);
}

bool ReadExtents(FileDescriptorPtr fd,
                 const google::protobuf::RepeatedPtrField<Extent>& extents,
                 brillo::Blob* out_data,
                 size_t block_size) {
  return ReadExtents(fd,
                     {extents.begin(), extents.end()},
                     out_data,
                     utils::BlocksInExtents(extents) * block_size,
                     block_size);
}

bool ReadExtents(FileDescriptorPtr fd,
                 const vector<Extent>& extents,
                 brillo::Blob* out_data,
                 ssize_t out_data_size,
                 size_t block_size) {
  brillo::Blob data(out_data_size);
  ssize_t bytes_read = 0;

  for (const Extent& extent : extents) {
    ssize_t bytes_read_this_iteration = 0;
    ssize_t bytes = extent.num_blocks() * block_size;
    TEST_LE(bytes_read + bytes, out_data_size);
    TEST_AND_RETURN_FALSE(utils::PReadAll(fd,
                                          &data[bytes_read],
                                          bytes,
                                          extent.start_block() * block_size,
                                          &bytes_read_this_iteration));
    TEST_AND_RETURN_FALSE(bytes_read_this_iteration == bytes);
    bytes_read += bytes_read_this_iteration;
  }
  TEST_AND_RETURN_FALSE(out_data_size == bytes_read);
  *out_data = data;
  return true;
}

bool GetVpdValue(string key, string* result) {
  int exit_code = 0;
  string value, error;
  vector<string> cmd = {"vpd_get_value", key};
  if (!chromeos_update_engine::Subprocess::SynchronousExec(
          cmd, &exit_code, &value, &error) ||
      exit_code) {
    LOG(ERROR) << "Failed to get vpd key for " << value
               << " with exit code: " << exit_code << " and error: " << error;
    return false;
  } else if (!error.empty()) {
    LOG(INFO) << "vpd_get_value succeeded but with following errors: " << error;
  }

  base::TrimWhitespaceASCII(value, base::TRIM_ALL, &value);
  *result = value;
  return true;
}

bool GetBootId(string* boot_id) {
  TEST_AND_RETURN_FALSE(
      base::ReadFileToString(base::FilePath(kBootIdPath), boot_id));
  base::TrimWhitespaceASCII(*boot_id, base::TRIM_TRAILING, boot_id);
  return true;
}

int VersionPrefix(const std::string& version) {
  if (version.empty()) {
    return 0;
  }
  vector<string> tokens = base::SplitString(
      version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  int value{};
  if (tokens.empty() || !base::StringToInt(tokens[0], &value))
    return -1;  // Target version is invalid.
  return value;
}

void ParseRollbackKeyVersion(const string& raw_version,
                             uint16_t* high_version,
                             uint16_t* low_version) {
  DCHECK(high_version);
  DCHECK(low_version);
  *high_version = numeric_limits<uint16_t>::max();
  *low_version = numeric_limits<uint16_t>::max();

  vector<string> parts = base::SplitString(
      raw_version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  if (parts.size() != 2) {
    // The version string must have exactly one period.
    return;
  }

  int high{};
  int low{};
  if (!(base::StringToInt(parts[0], &high) &&
        base::StringToInt(parts[1], &low))) {
    // Both parts of the version could not be parsed correctly.
    return;
  }

  if (high >= 0 && high < numeric_limits<uint16_t>::max() && low >= 0 &&
      low < numeric_limits<uint16_t>::max()) {
    *high_version = static_cast<uint16_t>(high);
    *low_version = static_cast<uint16_t>(low);
  }
}

string GetFilePath(int fd) {
  base::FilePath proc("/proc/self/fd/" + std::to_string(fd));
  base::FilePath file_name;

  if (!base::ReadSymbolicLink(proc, &file_name)) {
    return "not found";
  }
  return file_name.value();
}

string GetTimeAsString(time_t utime) {
  struct tm tm {};
  CHECK_EQ(localtime_r(&utime, &tm), &tm);
  char str[16];
  CHECK_EQ(strftime(str, sizeof(str), "%Y%m%d-%H%M%S", &tm), 15u);
  return str;
}

string GetExclusionName(const string& str_to_convert) {
  return base::NumberToString(base::StringPieceHash()(str_to_convert));
}

static bool ParseTimestamp(std::string_view str, int64_t* out) {
  if (!base::StringToInt64(base::StringPiece(str.data(), str.size()), out)) {
    LOG(WARNING) << "Invalid timestamp: " << str;
    return false;
  }
  return true;
}

ErrorCode IsTimestampNewer(const std::string_view old_version,
                           const std::string_view new_version) {
  if (old_version.empty() || new_version.empty()) {
    LOG(WARNING)
        << "One of old/new timestamp is empty, permit update anyway. Old: "
        << old_version << " New: " << new_version;
    return ErrorCode::kSuccess;
  }
  int64_t old_ver = 0;
  if (!ParseTimestamp(old_version, &old_ver)) {
    return ErrorCode::kError;
  }
  int64_t new_ver = 0;
  if (!ParseTimestamp(new_version, &new_ver)) {
    return ErrorCode::kDownloadManifestParseError;
  }
  if (old_ver > new_ver) {
    return ErrorCode::kPayloadTimestampError;
  }
  return ErrorCode::kSuccess;
}

std::unique_ptr<android::base::MappedFile> GetReadonlyZeroBlock(size_t size) {
  android::base::unique_fd fd{HANDLE_EINTR(open("/dev/zero", O_RDONLY))};
  return android::base::MappedFile::FromFd(fd, 0, size, PROT_READ);
}

std::string_view GetReadonlyZeroString(size_t size) {
  // Reserve 512MB of Virtual Address Space. No actual memory will be used.
  static auto zero_block = GetReadonlyZeroBlock(1024 * 1024 * 512);
  if (size > zero_block->size()) {
    auto larger_block = GetReadonlyZeroBlock(size);
    zero_block = std::move(larger_block);
  }
  return {zero_block->data(), size};
}

}  // namespace utils

std::string HexEncode(const brillo::Blob& blob) noexcept {
  return base::HexEncode(blob.data(), blob.size());
}

std::string HexEncode(const std::string_view blob) noexcept {
  return base::HexEncode(blob.data(), blob.size());
}

[[nodiscard]] std::string_view ToStringView(
    const std::vector<unsigned char>& blob) noexcept {
  return std::string_view{reinterpret_cast<const char*>(blob.data()),
                          blob.size()};
}

[[nodiscard]] std::string_view ToStringView(const void* data,
                                            size_t size) noexcept {
  return std::string_view(reinterpret_cast<const char*>(data), size);
}

}  // namespace chromeos_update_engine
