// Copyright 2014 The Chromium OS 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 "brillo/file_utils.h"

#include <fcntl.h>
#include <unistd.h>

#include <limits>
#include <utility>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/rand_util.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>

namespace brillo {

namespace {

// Log sync(), fsync(), etc. calls that take this many seconds or longer.
constexpr const base::TimeDelta kLongSync = base::TimeDelta::FromSeconds(10);

enum {
  kPermissions600 = S_IRUSR | S_IWUSR,
  kPermissions777 = S_IRWXU | S_IRWXG | S_IRWXO,
  kPermissions755 = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
};

// Verify that base file permission enums are compatible with S_Ixxx. If these
// asserts ever fail, we'll need to ensure that users of these functions switch
// away from using base permission enums and add a note to the function comments
// indicating that base enums can not be used.
static_assert(base::FILE_PERMISSION_READ_BY_USER == S_IRUSR,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_WRITE_BY_USER == S_IWUSR,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_EXECUTE_BY_USER == S_IXUSR,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_READ_BY_GROUP == S_IRGRP,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_WRITE_BY_GROUP == S_IWGRP,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_EXECUTE_BY_GROUP == S_IXGRP,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_READ_BY_OTHERS == S_IROTH,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_WRITE_BY_OTHERS == S_IWOTH,
              "base file permissions don't match unistd.h permissions");
static_assert(base::FILE_PERMISSION_EXECUTE_BY_OTHERS == S_IXOTH,
              "base file permissions don't match unistd.h permissions");

enum RegularFileOrDeleteResult {
  kFailure = 0,      // Failed to delete whatever was at the path.
  kRegularFile = 1,  // Regular file existed and was unchanged.
  kEmpty = 2         // Anything that was at the path has been deleted.
};

// Checks if a regular file owned by |uid| and |gid| exists at |path|, otherwise
// deletes anything that might be at |path|. Returns a RegularFileOrDeleteResult
// enum indicating what is at |path| after the function finishes.
RegularFileOrDeleteResult RegularFileOrDelete(const base::FilePath& path,
                                              uid_t uid,
                                              gid_t gid) {
  // Check for symlinks by setting O_NOFOLLOW and checking for ELOOP. This lets
  // us use the safer fstat() instead of having to use lstat().
  base::ScopedFD scoped_fd(HANDLE_EINTR(openat(
      AT_FDCWD, path.value().c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)));
  bool path_not_empty = (errno == ELOOP || scoped_fd != -1);

  // If there is a file/directory at |path|, see if it matches our criteria.
  if (scoped_fd != -1) {
    struct stat file_stat;
    if (fstat(scoped_fd.get(), &file_stat) != -1 &&
        S_ISREG(file_stat.st_mode) && file_stat.st_uid == uid &&
        file_stat.st_gid == gid) {
      return kRegularFile;
    }
  }

  // If we get here and anything was at |path|, try to delete it so we can put
  // our file there.
  if (path_not_empty) {
    if (!base::DeleteFile(path, true)) {
      PLOG(WARNING) << "Failed to delete entity at \"" << path.value() << '"';
      return kFailure;
    }
  }

  return kEmpty;
}

// Handles common touch functionality but also provides an optional |fd_out|
// so that any further modifications to the file (e.g. permissions) can safely
// use the fd rather than the path. |fd_out| will only be set if a new file
// is created, otherwise it will be unchanged.
// If |fd_out| is null, this function will close the file, otherwise it's
// expected that |fd_out| will close the file when it goes out of scope.
bool TouchFileInternal(const base::FilePath& path,
                       uid_t uid,
                       gid_t gid,
                       base::ScopedFD* fd_out) {
  RegularFileOrDeleteResult result = RegularFileOrDelete(path, uid, gid);
  switch (result) {
    case kFailure:
      return false;
    case kRegularFile:
      return true;
    case kEmpty:
      break;
  }

  // base::CreateDirectory() returns true if the directory already existed.
  if (!base::CreateDirectory(path.DirName())) {
    PLOG(WARNING) << "Failed to create directory for \"" << path.value() << '"';
    return false;
  }

  // Create the file as owner-only initially.
  base::ScopedFD scoped_fd(HANDLE_EINTR(openat(
      AT_FDCWD, path.value().c_str(),
      O_RDONLY | O_NOFOLLOW | O_CREAT | O_EXCL | O_CLOEXEC, kPermissions600)));
  if (scoped_fd == -1) {
    PLOG(WARNING) << "Failed to create file \"" << path.value() << '"';
    return false;
  }

  if (fd_out) {
    fd_out->swap(scoped_fd);
  }
  return true;
}

std::string GetRandomSuffix() {
  const int kBufferSize = 6;
  unsigned char buffer[kBufferSize];
  base::RandBytes(buffer, base::size(buffer));
  std::string suffix;
  for (int i = 0; i < kBufferSize; ++i) {
    int random_value = buffer[i] % (2 * 26 + 10);
    if (random_value < 26) {
      suffix.push_back('a' + random_value);
    } else if (random_value < 2 * 26) {
      suffix.push_back('A' + random_value - 26);
    } else {
      suffix.push_back('0' + random_value - 2 * 26);
    }
  }
  return suffix;
}

base::ScopedFD OpenPathComponentInternal(int parent_fd,
                                         const std::string& file,
                                         int flags,
                                         mode_t mode) {
  DCHECK(file == "/" || file.find("/") == std::string::npos);
  base::ScopedFD fd;

  // O_NONBLOCK is used to avoid hanging on edge cases (e.g. a serial port with
  // flow control, or a FIFO without a writer).
  if (parent_fd >= 0 || parent_fd == AT_FDCWD) {
    fd.reset(HANDLE_EINTR(openat(parent_fd, file.c_str(),
                                 flags | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC,
                                 mode)));
  } else if (file == "/") {
    fd.reset(HANDLE_EINTR(open(
        file.c_str(),
        flags | O_RDONLY | O_DIRECTORY | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC,
        mode)));
  }

  if (!fd.is_valid()) {
    // open(2) fails with ELOOP when the last component of the |path| is a
    // symlink. It fails with ENXIO when |path| is a FIFO and |flags| is for
    // writing because of the O_NONBLOCK flag added above.
    if (errno == ELOOP || errno == ENXIO) {
      PLOG(WARNING) << "Failed to open " << file << " safely.";
    } else {
      PLOG(WARNING) << "Failed to open " << file << ".";
    }
    return base::ScopedFD();
  }

  // Remove the O_NONBLOCK flag unless the original |flags| have it.
  if ((flags & O_NONBLOCK) == 0) {
    flags = fcntl(fd.get(), F_GETFL);
    if (flags == -1) {
      PLOG(ERROR) << "Failed to get fd flags for " << file;
      return base::ScopedFD();
    }
    if (fcntl(fd.get(), F_SETFL, flags & ~O_NONBLOCK)) {
      PLOG(ERROR) << "Failed to set fd flags for " << file;
      return base::ScopedFD();
    }
  }

  return fd;
}

base::ScopedFD OpenSafelyInternal(int parent_fd,
                                  const base::FilePath& path,
                                  int flags,
                                  mode_t mode) {
  std::vector<std::string> components;
  path.GetComponents(&components);

  auto itr = components.begin();
  if (itr == components.end()) {
    LOG(ERROR) << "A path is required.";
    return base::ScopedFD();  // This is an invalid fd.
  }

  base::ScopedFD child_fd;
  int parent_flags = flags | O_NONBLOCK | O_RDONLY | O_DIRECTORY | O_PATH;
  for (; itr + 1 != components.end(); ++itr) {
    child_fd = OpenPathComponentInternal(parent_fd, *itr, parent_flags, 0);
    if (!child_fd.is_valid()) {
      return base::ScopedFD();
    }
    parent_fd = child_fd.get();
  }

  return OpenPathComponentInternal(parent_fd, *itr, flags, mode);
}

}  // namespace

bool TouchFile(const base::FilePath& path,
               int new_file_permissions,
               uid_t uid,
               gid_t gid) {
  // Make sure |permissions| doesn't have any out-of-range bits.
  if (new_file_permissions & ~kPermissions777) {
    LOG(WARNING) << "Illegal permissions: " << new_file_permissions;
    return false;
  }

  base::ScopedFD scoped_fd;
  if (!TouchFileInternal(path, uid, gid, &scoped_fd)) {
    return false;
  }

  // scoped_fd is valid only if a new file was created.
  if (scoped_fd != -1 &&
      HANDLE_EINTR(fchmod(scoped_fd.get(), new_file_permissions)) == -1) {
    PLOG(WARNING) << "Failed to set permissions for \"" << path.value() << '"';
    base::DeleteFile(path, false);
    return false;
  }

  return true;
}

bool TouchFile(const base::FilePath& path) {
  // Use TouchFile() instead of TouchFileInternal() to explicitly set
  // permissions to 600 in case umask is set strangely.
  return TouchFile(path, kPermissions600, geteuid(), getegid());
}

base::ScopedFD OpenSafely(const base::FilePath& path, int flags, mode_t mode) {
  if (!path.IsAbsolute()) {
    LOG(ERROR) << "An absolute path is required.";
    return base::ScopedFD();  // This is an invalid fd.
  }

  base::ScopedFD fd(OpenSafelyInternal(-1, path, flags, mode));
  if (!fd.is_valid())
    return base::ScopedFD();

  // Ensure the opened file is a regular file or directory.
  struct stat st;
  if (fstat(fd.get(), &st) < 0) {
    PLOG(ERROR) << "Failed to fstat " << path.value();
    return base::ScopedFD();
  }

  // This detects a FIFO opened for reading, for example.
  if (flags & O_DIRECTORY) {
    if (!S_ISDIR(st.st_mode)) {
      LOG(ERROR) << path.value() << " is not a directory: " << st.st_mode;
      return base::ScopedFD();
    }
  } else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
    LOG(ERROR) << path.value()
               << " is not a regular file or directory: " << st.st_mode;
    return base::ScopedFD();
  }

  return fd;
}

base::ScopedFD OpenAtSafely(int parent_fd,
                            const base::FilePath& path,
                            int flags,
                            mode_t mode) {
  base::ScopedFD fd(OpenSafelyInternal(parent_fd, path, flags, mode));
  if (!fd.is_valid())
    return base::ScopedFD();

  // Ensure the opened file is a regular file or directory.
  struct stat st;
  if (fstat(fd.get(), &st) < 0) {
    PLOG(ERROR) << "Failed to fstat " << path.value();
    return base::ScopedFD();
  }

  // This detects a FIFO opened for reading, for example.
  if (flags & O_DIRECTORY) {
    if (!S_ISDIR(st.st_mode)) {
      LOG(ERROR) << path.value() << " is not a directory: " << st.st_mode;
      return base::ScopedFD();
    }
  } else if (!S_ISREG(st.st_mode)) {
    LOG(ERROR) << path.value() << " is not a regular file: " << st.st_mode;
    return base::ScopedFD();
  }

  return fd;
}

base::ScopedFD OpenFifoSafely(const base::FilePath& path,
                              int flags,
                              mode_t mode) {
  if (!path.IsAbsolute()) {
    LOG(ERROR) << "An absolute path is required.";
    return base::ScopedFD();  // This is an invalid fd.
  }

  base::ScopedFD fd(OpenSafelyInternal(-1, path, flags, mode));
  if (!fd.is_valid())
    return base::ScopedFD();

  // Ensure the opened file is a FIFO.
  struct stat st;
  if (fstat(fd.get(), &st) < 0) {
    PLOG(ERROR) << "Failed to fstat " << path.value();
    return base::ScopedFD();
  }

  if (!S_ISFIFO(st.st_mode)) {
    LOG(ERROR) << path.value() << " is not a FIFO: " << st.st_mode;
    return base::ScopedFD();
  }

  return fd;
}

base::ScopedFD MkdirRecursively(const base::FilePath& full_path, mode_t mode) {
  std::vector<std::string> components;
  full_path.GetComponents(&components);

  auto itr = components.begin();
  if (!full_path.IsAbsolute() || itr == components.end()) {
    LOG(ERROR) << "An absolute path is required.";
    return base::ScopedFD();  // This is an invalid fd.
  }

  base::ScopedFD parent_fd;
  int parent_flags = O_NONBLOCK | O_RDONLY | O_DIRECTORY | O_PATH;
  while (itr + 1 != components.end()) {
    base::ScopedFD child(
        OpenPathComponentInternal(parent_fd.get(), *itr, parent_flags, 0));
    if (!child.is_valid()) {
      return base::ScopedFD();
    }
    parent_fd = std::move(child);

    ++itr;

    // Try to create the directory. Note that Chromium's MkdirRecursively() uses
    // 0700, but we use 0755.
    if (mkdirat(parent_fd.get(), itr->c_str(), mode) != 0) {
      if (errno != EEXIST) {
        PLOG(ERROR) << "Failed to mkdirat " << *itr
                    << ": full_path=" << full_path.value();
        return base::ScopedFD();
      }
    }
  }

  return OpenPathComponentInternal(parent_fd.get(), *itr,
                                   O_RDONLY | O_DIRECTORY, 0);
}

bool WriteStringToFile(const base::FilePath& path, const std::string& data) {
  return WriteToFile(path, data.data(), data.size());
}

bool WriteToFile(const base::FilePath& path, const char* data, size_t size) {
  if (!base::DirectoryExists(path.DirName())) {
    if (!base::CreateDirectory(path.DirName())) {
      LOG(ERROR) << "Cannot create directory: " << path.DirName().value();
      return false;
    }
  }
  // base::WriteFile takes an int size.
  if (size > std::numeric_limits<int>::max()) {
    LOG(ERROR) << "Cannot write to " << path.value()
               << ". Data is too large: " << size << " bytes.";
    return false;
  }

  int data_written = base::WriteFile(path, data, size);
  return data_written == static_cast<int>(size);
}

bool SyncFileOrDirectory(const base::FilePath& path,
                         bool is_directory,
                         bool data_sync) {
  const base::TimeTicks start = base::TimeTicks::Now();
  data_sync = data_sync && !is_directory;

  int flags = (is_directory ? O_RDONLY | O_DIRECTORY : O_WRONLY);
  int fd = HANDLE_EINTR(open(path.value().c_str(), flags));
  if (fd < 0) {
    PLOG(WARNING) << "Could not open " << path.value() << " for syncing";
    return false;
  }
  // POSIX specifies EINTR as a possible return value of fsync() but not for
  // fdatasync().  To be on the safe side, it is handled in both cases.
  int result =
      (data_sync ? HANDLE_EINTR(fdatasync(fd)) : HANDLE_EINTR(fsync(fd)));
  if (result < 0) {
    PLOG(WARNING) << "Failed to sync " << path.value();
    close(fd);
    return false;
  }
  // close() may not be retried on error.
  result = IGNORE_EINTR(close(fd));
  if (result < 0) {
    PLOG(WARNING) << "Failed to close after sync " << path.value();
    return false;
  }

  const base::TimeDelta delta = base::TimeTicks::Now() - start;
  if (delta > kLongSync) {
    LOG(WARNING) << "Long " << (data_sync ? "fdatasync" : "fsync") << "() of "
                 << path.value() << ": " << delta.InSeconds() << " seconds";
  }

  return true;
}

bool WriteToFileAtomic(const base::FilePath& path,
                       const char* data,
                       size_t size,
                       mode_t mode) {
  if (!base::DirectoryExists(path.DirName())) {
    if (!base::CreateDirectory(path.DirName())) {
      LOG(ERROR) << "Cannot create directory: " << path.DirName().value();
      return false;
    }
  }
  std::string random_suffix = GetRandomSuffix();
  if (random_suffix.empty()) {
    PLOG(WARNING) << "Could not compute random suffix";
    return false;
  }
  std::string temp_name = path.AddExtension(random_suffix).value();
  int fd =
      HANDLE_EINTR(open(temp_name.c_str(), O_CREAT | O_EXCL | O_WRONLY, mode));
  if (fd < 0) {
    PLOG(WARNING) << "Could not open " << temp_name << " for atomic write";
    unlink(temp_name.c_str());
    return false;
  }

  size_t position = 0;
  while (position < size) {
    ssize_t bytes_written =
        HANDLE_EINTR(write(fd, data + position, size - position));
    if (bytes_written < 0) {
      PLOG(WARNING) << "Could not write " << temp_name;
      close(fd);
      unlink(temp_name.c_str());
      return false;
    }
    position += bytes_written;
  }

  if (HANDLE_EINTR(fdatasync(fd)) < 0) {
    PLOG(WARNING) << "Could not fsync " << temp_name;
    close(fd);
    unlink(temp_name.c_str());
    return false;
  }
  if (close(fd) < 0) {
    PLOG(WARNING) << "Could not close " << temp_name;
    unlink(temp_name.c_str());
    return false;
  }

  if (rename(temp_name.c_str(), path.value().c_str()) < 0) {
    PLOG(WARNING) << "Could not close " << temp_name;
    unlink(temp_name.c_str());
    return false;
  }

  return true;
}

int64_t ComputeDirectoryDiskUsage(const base::FilePath& root_path) {
  int64_t running_blocks = 0;
  base::FileEnumerator file_iter(root_path, true,
                                 base::FileEnumerator::FILES |
                                     base::FileEnumerator::DIRECTORIES |
                                     base::FileEnumerator::SHOW_SYM_LINKS);
  while (!file_iter.Next().empty()) {
    // st_blocks in struct stat is the number of S_BLKSIZE (512) bytes sized
    // blocks occupied by this file.
    running_blocks += file_iter.GetInfo().stat().st_blocks;
  }
  // Each block is S_BLKSIZE (512) bytes so *S_BLKSIZE.
  return running_blocks * S_BLKSIZE;
}

}  // namespace brillo
