//
// 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/stat.h>
#include <sys/types.h>
#include <unistd.h>

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

#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/clock_interface.h"
#include "update_engine/common/constants.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/prefs_interface.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/payload_consumer/file_descriptor.h"

using base::Time;
using base::TimeDelta;
using std::min;
using std::pair;
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";

// A pointer to a null-terminated string containing the root directory where all
// the temporary files should be created. If null, the system default is used
// instead.
const char* root_temp_dir = nullptr;

// Return true if |disk_name| is an MTD or a UBI device. Note that this test is
// simply based on the name of the device.
bool IsMtdDeviceName(const string& disk_name) {
  return base::StartsWith(disk_name, "/dev/ubi",
                          base::CompareCase::SENSITIVE) ||
         base::StartsWith(disk_name, "/dev/mtd", base::CompareCase::SENSITIVE);
}

// Return the device name for the corresponding partition on a NAND device.
// WARNING: This function returns device names that are not mountable.
string MakeNandPartitionName(int partition_num) {
  switch (partition_num) {
    case 2:
    case 4:
    case 6: {
      return base::StringPrintf("/dev/mtd%d", partition_num);
    }
    default: {
      return base::StringPrintf("/dev/ubi%d_0", partition_num);
    }
  }
}

// Return the device name for the corresponding partition on a NAND device that
// may be mountable (but may not be writable).
string MakeNandPartitionNameForMount(int partition_num) {
  switch (partition_num) {
    case 2:
    case 4:
    case 6: {
      return base::StringPrintf("/dev/mtd%d", partition_num);
    }
    case 3:
    case 5:
    case 7: {
      return base::StringPrintf("/dev/ubiblock%d_0", partition_num);
    }
    default: {
      return base::StringPrintf("/dev/ubi%d_0", partition_num);
    }
  }
}

// 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;
  if (root_temp_dir) {
    temp_dir = base::FilePath(root_temp_dir);
  } else {
#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 {

void SetRootTempDir(const char* new_root_temp_dir) {
  root_temp_dir = new_root_temp_dir;
}

string ParseECVersion(string input_line) {
  base::TrimWhitespaceASCII(input_line, base::TRIM_ALL, &input_line);

  // At this point we want to convert the format key=value pair from mosys to
  // a vector of key value pairs.
  vector<pair<string, string>> kv_pairs;
  if (base::SplitStringIntoKeyValuePairs(input_line, '=', ' ', &kv_pairs)) {
    for (const pair<string, string>& kv_pair : kv_pairs) {
      // Finally match against the fw_verion which may have quotes.
      if (kv_pair.first == "fw_version") {
        string output;
        // Trim any quotes.
        base::TrimString(kv_pair.second, "\"", &output);
        return output;
      }
    }
  }
  LOG(ERROR) << "Unable to parse fwid from ec info.";
  return "";
}

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(const FileDescriptorPtr& 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 PWriteAll(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 PReadAll(const FileDescriptorPtr& 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;
}

// 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;
}

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;
  }

  size_t partition_name_len = string::npos;
  if (partition_name[last_nondigit_pos] == '_') {
    // NAND block devices have weird naming which could be something
    // like "/dev/ubiblock2_0". We discard "_0" in such a case.
    size_t prev_nondigit_pos =
        partition_name.find_last_not_of("0123456789", last_nondigit_pos - 1);
    if (prev_nondigit_pos == string::npos ||
        (prev_nondigit_pos + 1) == last_nondigit_pos) {
      LOG(ERROR) << "Unable to parse partition device name: " << partition_name;
      return false;
    }

    partition_name_len = last_nondigit_pos - prev_nondigit_pos;
    last_nondigit_pos = prev_nondigit_pos;
  }

  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,
                                                 partition_name_len);
    *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();
  }

  if (IsMtdDeviceName(disk_name)) {
    // Special case for UBI block devices.
    //   1. ubiblock is not writable, we need to use plain "ubi".
    //   2. There is a "_0" suffix.
    return MakeNandPartitionName(partition_num);
  }

  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;
}

string MakePartitionNameForMount(const string& part_name) {
  if (IsMtdDeviceName(part_name)) {
    int partition_num;
    if (!SplitPartitionName(part_name, nullptr, &partition_num)) {
      return "";
    }
    return MakeNandPartitionNameForMount(partition_num);
  }
  return part_name;
}

string ErrnoNumberAsString(int err) {
  char buf[100];
  buf[0] = '\0';
  return strerror_r(err, buf, sizeof(buf));
}

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 TryAttachingUbiVolume(int volume_num, int timeout) {
  const string volume_path = base::StringPrintf("/dev/ubi%d_0", volume_num);
  if (FileExists(volume_path.c_str())) {
    return true;
  }

  int exit_code;
  vector<string> cmd = {
      "ubiattach",
      "-m",
      base::StringPrintf("%d", volume_num),
      "-d",
      base::StringPrintf("%d", volume_num)
  };
  TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &exit_code, nullptr));
  TEST_AND_RETURN_FALSE(exit_code == 0);

  cmd = {
      "ubiblock",
      "--create",
      volume_path
  };
  TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &exit_code, nullptr));
  TEST_AND_RETURN_FALSE(exit_code == 0);

  while (timeout > 0 && !FileExists(volume_path.c_str())) {
    sleep(1);
    timeout--;
  }

  return FileExists(volume_path.c_str());
}

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;
  }
  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"};
  } 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 endianess regardless of the host endianess.
  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;
}

Time TimeFromStructTimespec(struct timespec *ts) {
  int64_t us = static_cast<int64_t>(ts->tv_sec) * Time::kMicrosecondsPerSecond +
      static_cast<int64_t>(ts->tv_nsec) / Time::kNanosecondsPerMicrosecond;
  return Time::UnixEpoch() + TimeDelta::FromMicroseconds(us);
}

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 DecodeAndStoreBase64String(const string& base64_encoded,
                                base::FilePath *out_path) {
  brillo::Blob contents;

  out_path->clear();

  if (base64_encoded.size() == 0) {
    LOG(ERROR) << "Can't decode empty string.";
    return false;
  }

  if (!brillo::data_encoding::Base64Decode(base64_encoded, &contents) ||
      contents.size() == 0) {
    LOG(ERROR) << "Error decoding base64.";
    return false;
  }

  FILE *file = base::CreateAndOpenTemporaryFile(out_path);
  if (file == nullptr) {
    LOG(ERROR) << "Error creating temporary file.";
    return false;
  }

  if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
    PLOG(ERROR) << "Error writing to temporary file.";
    if (fclose(file) != 0)
      PLOG(ERROR) << "Error closing temporary file.";
    if (unlink(out_path->value().c_str()) != 0)
      PLOG(ERROR) << "Error unlinking temporary file.";
    out_path->clear();
    return false;
  }

  if (fclose(file) != 0) {
    PLOG(ERROR) << "Error closing temporary file.";
    out_path->clear();
    return false;
  }

  return true;
}

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 string& path, 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;
  int fd = open(path.c_str(), O_RDONLY);
  TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
  ScopedFdCloser fd_closer(&fd);

  for (const Extent& extent : extents) {
    ssize_t bytes_read_this_iteration = 0;
    ssize_t bytes = extent.num_blocks() * block_size;
    TEST_AND_RETURN_FALSE(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 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;
}

}  // namespace utils

}  // namespace chromeos_update_engine
