#!/bin/sh

# 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.

set -e

# Product ID in crash report
CHROMEOS_PRODUCT=ChromeOS

# File whose existence implies crash reports may be sent, and whose
# contents includes our machine's anonymized guid.
CONSENT_ID="/home/chronos/Consent To Send Stats"

# Path to find which is required for computing the crash rate.
FIND="/usr/bin/find"

# Send up to 8 crashes per day.
MAX_CRASH_RATE=8

# File whose existence mocks crash sending.  If empty we pretend the
# crash sending was successful, otherwise unsuccessful.
MOCK_CRASH_SENDING="/tmp/mock-crash-sending"

# File whose existence causes crash sending to be delayed (for testing).
# Must be stateful to enable testing kernel crashes.
PAUSE_CRASH_SENDING="/var/lib/crash_sender_paused"

# URL to send non-official build crash reports to.
REPORT_UPLOAD_STAGING_URL="http://clients2.google.com/cr/staging_report"

# URL to send official build crash reports to.
REPORT_UPLOAD_PROD_URL="http://clients2.google.com/cr/report"

# File whose existence implies we're running and not to start again.
RUN_FILE="/var/run/crash_sender.pid"

# Maximum time to sleep between sends.
SECONDS_SEND_SPREAD=${SECONDS_SEND_SPREAD:-600}

# The syslog tag for all logging we emit.
TAG="$(basename $0)[$$]"

# Directory to store timestamp files indicating the uploads in the past 24
# hours.
TIMESTAMPS_DIR="/var/lib/crash_sender"

lecho() {
  logger -t "${TAG}" "$@"
}

cleanup_tmp_dir() {
  rm -rf "${TMP_DIR}"
}

cleanup_run_file_and_tmp_dir() {
  rm -f "${RUN_FILE}"
  cleanup_tmp_dir
}

check_not_already_running() {
  if [ ! -f "${RUN_FILE}" ]; then
    return
  fi
  local last_pid=$(cat "${RUN_FILE}")
  if [ ! -f "/proc/${last_pid}/cmdline" ]; then
    trap cleanup_run_file_and_tmp_dir EXIT INT
    echo $$ > "${RUN_FILE}"
    return
  fi
  # This could just be an unrelated process, but it's ok to be conservative.
  lecho "Already running.  Exiting now."
  exit 1
}

get_version() {
  grep ^CHROMEOS_RELEASE_VERSION /etc/lsb-release | cut -d = -f 2-
}

is_official() {
  grep ^CHROMEOS_RELEASE_DESCRIPTION /etc/lsb-release | cut -d = -f 2- | \
      grep Official
}

# Generate a uniform random number in 0..max-1.
generate_uniform_random() {
  local max=$1
  local random="$(od -An -N4 -tu /dev/urandom)"
  echo $((random % max))
}

is_feedback_disabled() {
  [ -r "${CONSENT_ID}" ] && return 1
  return 0
}

is_on_3g() {
  # See crosbug.com/3304.
  return 1
}

# Check if sending a crash now does not exceed the maximum 24hr rate and
# commit to doing so, if not.
check_rate() {
  mkdir -p ${TIMESTAMPS_DIR}
  # Only consider minidumps written in the past 24 hours by removing all older.
  ${FIND} "${TIMESTAMPS_DIR}" -mindepth 1 -mmin +$((24 * 60)) -exec rm '{}' ';'
  local sends_in_24hrs=$(echo "${TIMESTAMPS_DIR}"/* | wc -w)
  lecho "Current send rate: ${sends_in_24hrs}sends/24hrs"
  if [ ${sends_in_24hrs} -ge ${MAX_CRASH_RATE} ]; then
    lecho "Cannot send more crashes:"
    lecho "  current ${sends_in_24hrs}send/24hrs >= " \
          "max ${MAX_CRASH_RATE}send/24hrs"
    return 1
  fi
  mktemp "${TIMESTAMPS_DIR}"/XXXX > /dev/null
  return 0
}

# Return if $1 is a .core file
get_kind() {
  local kind="${1##*.}"
  if [ "${kind}" = "dmp" ]; then
    kind="minidump"
  fi
  echo ${kind}
}

get_exec_name() {
  local filename=$(basename "$1")
  echo "${filename%%.*}"
}

send_crash() {
  local report_path="$1"
  local kind=$(get_kind "${report_path}")
  local exec_name=$(get_exec_name "${report_path}")
  local sleep_time=$(generate_uniform_random $SECONDS_SEND_SPREAD)
  local url="${REPORT_UPLOAD_STAGING_URL}"
  if is_official; then
    url="${REPORT_UPLOAD_PROD_URL}"
  fi
  lecho "Sending crash:"
  lecho "  Scheduled to send in ${sleep_time}s"
  lecho "  Report: ${report_path} (${kind})"
  lecho "  URL: ${url}"
  lecho "  Product: ${CHROMEOS_PRODUCT}"
  lecho "  Version: ${chromeos_version}"
  lecho "  Exec name: ${exec_name}"
  if [ -f "${MOCK_CRASH_SENDING}" ]; then
    local mock_in=$(cat "${MOCK_CRASH_SENDING}")
    if [ "${mock_in}" = "" ]; then
      lecho "Mocking successful send"
      return 0
    else
      lecho "Mocking unsuccessful send"
      return 1
    fi
  fi

  if ! sleep ${sleep_time}; then
    lecho "Sleep failed"
    return 1
  fi

  local report_id="${TMP_DIR}/report_id"
  local curl_stderr="${TMP_DIR}/curl_stderr"

  set +e
  curl "${url}" \
    -F "prod=${CHROMEOS_PRODUCT}" \
    -F "ver=${chromeos_version}" \
    -F "upload_file_${kind}=@${report_path}" \
    -F "exec_name=${exec_name}" \
    -F "guid=<${CONSENT_ID}" -o "${report_id}" 2>"${curl_stderr}"
  curl_result=$?
  set -e

  if [ ${curl_result} -eq 0 ]; then
    lecho "Crash report receipt ID $(cat ${report_id})"
  else
    lecho "Crash sending failed with: $(cat ${curl_stderr})"
  fi

  rm -f "${report_id}" "${output_file}"

  return ${curl_result}
}

# Send all crashes from the given directory.  The directory is currently
# expected to just contain a bunch of minidumps.
send_crashes() {
  local dir="$1"
  lecho "Considering crashes in ${dir}"

  # Cycle through minidumps, most recent first.  That way if we're about
  # to exceed the daily rate, we send the most recent minidumps.
  if [ ! -d "${dir}" ]; then
    return
  fi
  for file in $(ls -1t "${dir}"); do
    local report_path="${dir}/${file}"
    lecho "Considering file ${report_path}"
    local kind=$(get_kind "${report_path}")

    if [ "${kind}" = "core" ]; then
      lecho "Ignoring core file."
      continue
    elif [ "${kind}" != "minidump" ] && [ "${kind}" != "kcrash" ]; then
      lecho "Unknown report kind: ${kind}.  Removing report."
      rm -f "${report_path}"
      continue
    fi
    if ! check_rate; then
      lecho "Sending ${report_path} would exceed rate.  Leaving for later."
      return 0
    fi
    local chromeos_version=$(get_version)
    if is_feedback_disabled; then
      lecho "Uploading is disabled.  Removing crash."
      rm "${report_path}"
    elif is_on_3g; then
      lecho "Not sending crash report while on 3G, saving for later."
    elif send_crash "${report_path}"; then
      # Send was successful, now remove
      lecho "Successfully sent crash ${report_path} and removing"
      rm "${report_path}"
    else
      lecho "Problem sending ${report_path}, not removing"
    fi
  done
}

main() {
  if [ -e "${PAUSE_CRASH_SENDING}" ]; then
    lecho "Exiting early due to ${PAUSE_CRASH_SENDING}"
    exit 1
  fi

  check_not_already_running

  if [ ! -x "${FIND}" ]; then
    lecho "Fatal: Crash sending disabled: ${FIND} not found."
    exit 1
  fi

  TMP_DIR="$(mktemp -d /tmp/crash_sender.XXXX)"
  trap cleanup_tmp_dir EXIT INT

  # Send system-wide crashes
  send_crashes "/var/spool/crash"

  # Send user-specific crashes
  send_crashes "/home/chronos/user/crash"
}

main
