// Copyright (c) 2010 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.
//
// Simple wrapper and basic configuration of Google breakpad.  We try
// to avoid using any unnecessary code (like libbase) to make it as
// non-intrusive as possible to link in this library.

#include <errno.h>
#include <pwd.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "client/linux/handler/exception_handler.h"
#include "common/linux/linux_libc_support.h"
#include "common/linux/linux_syscall_support.h"
#include "crash/crash_dumper.h"

// Define sys_mkdir (sys_open passes mode_t as int, so we do too).
LSS_INLINE _syscall2(int, mkdir, const char *, pathname, int, mode);

static const char kDefaultUser[] = "chronos";
static const char kSystemCrashParentPath[] = "/var/spool";
static const char kSystemCrashPath[] = "/var/spool/crash";
static const char kUserCrashParentPath[] = "/home/chronos/user";
static const char kUserCrashPath[] = "/home/chronos/user/crash";

// Pointers to paths, set when crash dumping is enabled.
static const char *s_crash_path;
static const char *s_crash_parent_path;
static mode_t s_dump_directory_mode;

static bool s_any_crashes_occurred = false;
static google_breakpad::ExceptionHandler *s_breakpad_handler;

static bool s_enabled = false;

#define CHECK_CONDITION(_cond, _message) \
  do { if (!(_cond)) { fputs(_message"\n", stderr); abort(); } } while(false)

// This static object will cause anything that links in this object to get
// crash handling for the duration of this file's scope.
static CrashDumper g_crash_dumper;


// Prepare the crash path.  Must avoid allocating memory.
static bool PrepareCrashPath() {
  struct kernel_stat buf;
  if (sys_stat(s_crash_path, &buf) < 0) {
    // Dump directory does not exist, so create it and its parent now,
    // at the time of the crash.
    sys_mkdir(s_crash_parent_path, 755);
    sys_mkdir(s_crash_path, s_dump_directory_mode);
  }
  return sys_stat(s_crash_path, &buf) == 0;
}

// Use FilterCallback to avoid recursive crashing.
// TODO(kmixter): Also use it to avoid enqueuing too many crash dumps
// system wide - if we get in a crash/restart loop we don't want the entire
// stateful partition to be filled up.
static bool FilterCallback(void *) {
  // This function runs in a compromised context - a crash has already
  // occurred so memory allocation and libc should be avoided.
  bool old_any_crashes_occured = s_any_crashes_occurred;
  s_any_crashes_occurred = true;
  // The crash path may have been removed or mounted-over, so make sure
  // there is a container directory.  If it fails, not much we can do.
  PrepareCrashPath();
  return !old_any_crashes_occured;
}

static bool GetEffectiveUser(std::string *result) {
  char storage[256];
  struct passwd passwd_storage;
  struct passwd *passwd_result = NULL;

  if (getpwuid_r(geteuid(), &passwd_storage, storage, sizeof(storage),
                 &passwd_result) != 0 || passwd_result == NULL) {
    return false;
  }

  *result = passwd_result->pw_name;
  return true;
}

void CrashDumper::Enable() {
  CHECK_CONDITION(!s_enabled, "Crash handling already enabled");

  std::string name;
  CHECK_CONDITION(GetEffectiveUser(&name),
                  "getpwuid_r failed, cannot enable crash reporting");

  if (name == kDefaultUser) {
    // Crashes as "chronos" when the user is not yet logged in will
    // still be recorded to /home/chronos/user/crash in the
    // stateful partition (outside cryptohome).  These will eventually
    // be uploaded when no user is logged in.
    s_crash_path = kUserCrashPath;
    s_crash_parent_path = kUserCrashParentPath;
    s_dump_directory_mode = 0755;
  } else {
    s_crash_path = kSystemCrashPath;
    s_crash_parent_path = kSystemCrashParentPath;
    // Make the dump directory sticky so any UID can write to
    // it but not remove another UID's crashes.
    s_dump_directory_mode = 01777;
  }

  CHECK_CONDITION(PrepareCrashPath(), "Unable to create crash path");

  // Begin collecting crashes
  s_breakpad_handler = new google_breakpad::ExceptionHandler(
      s_crash_path,
      FilterCallback,
      NULL,  // No minidump callback - sending happens asynchronously to writing
      NULL,  // No callback context necessary
      true);  // Install handler now.

  s_enabled = true;
}

bool CrashDumper::IsEnabled() {
  return s_enabled;
}

void CrashDumper::Disable() {
  CHECK_CONDITION(s_enabled, "Crash handling was not enabled");
  delete s_breakpad_handler;
  s_breakpad_handler = NULL;
  s_crash_path = NULL;
  s_crash_parent_path = NULL;
  s_enabled = false;
}
