#!/bin/sh
#
# Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This script is part of the google-chrome package.
#
# It creates the repository configuration file for package updates, since
# we cannot do this during the google-chrome installation since the repository
# is locked.
#
# This functionality can be controlled by creating the $DEFAULTS_FILE and
# setting "repo_add_once" to "true" or "false" as desired. An empty
# $DEFAULTS_FILE is the same as setting the value to "false".

# This script has been adapted for the Keybase .rpm package, by changing the
# package name/URLs, and by changing the PGP key. The above copyright notice is
# from the original Chrome package.

# System-wide package configuration.
DEFAULTS_FILE="/etc/default/@@NAME@@"

# sources.list setting for Keybase updates.
REPOCONFIG="@@REPO_URL@@"
SSLREPOCONFIG="@@REPO_SSL_URL@@"

# Install the repository signing key (see also:
# https://keybase.io/docs/server_security/our_code_signing_key)
install_rpm_key() {
  # Check to see if key already exists.
  # NOTE: The full package name will have another hash after the fingerprint
  # here, but this should be enough to uniquely identify it.
  rpm -q gpg-pubkey-656d16c7 > /dev/null 2>&1
  if [ "$?" -eq "0" ]; then
    # Key already exists
    return 0
  fi

  # RPM on Mandriva 2009 is dumb and does not understand "rpm --import -"
  TMPKEY=$(mktemp /tmp/keybase.sig.XXXXXX)
  if [ -n "$TMPKEY" ]; then
    cat > "$TMPKEY" <<KEYDATA
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG/MacGPG2 v2.0.22 (Darwin)
Comment: GPGTools - https://gpgtools.org

[encoded data, 4485 characters]
oJO3q10K/XeP2GohBf5q0imfUw==
=2Er/
-----END PGP PUBLIC KEY BLOCK-----
KEYDATA
    rpm --import "$TMPKEY"
    rc=$?
    rm -f "$TMPKEY"
    if [ "$rc" -eq "0" ]; then
      return 0
    fi
  fi
  return 1
}

determine_rpm_package_manager() {
  local RELEASE
  LSB_RELEASE="$(which lsb_release 2> /dev/null)"
  if [ -x "$LSB_RELEASE" ]; then
    RELEASE=$(lsb_release -i 2> /dev/null | sed 's/:\t/:/' | cut -d ':' -f 2-)
    case $RELEASE in
    "Fedora")
      PACKAGEMANAGER=yum
      ;;
    "Mageia"|"MandrivaLinux")
      PACKAGEMANAGER=urpmi
      ;;
    "SUSE LINUX")
      PACKAGEMANAGER=yast
      ;;
    esac
  fi

  if [ "$PACKAGEMANAGER" ]; then
    return
  fi

  # Fallback methods that are probably unnecessary on modern systems.
  if [ -f "/etc/lsb-release" ]; then
    # file missing on Fedora, does not contain DISTRIB_ID on OpenSUSE.
    eval $(sed -e '/DISTRIB_ID/!d' /etc/lsb-release)
    case $DISTRIB_ID in
    MandrivaLinux)
      PACKAGEMANAGER=urpmi
      ;;
    esac
  fi

  if [ "$PACKAGEMANAGER" ]; then
    return
  fi

  if [ -f "/etc/fedora-release" ] || [ -f "/etc/redhat-release" ]; then
    PACKAGEMANAGER=yum
  elif [ -f "/etc/SuSE-release" ]; then
    PACKAGEMANAGER=yast
  elif [ -f "/etc/mandriva-release" ]; then
    PACKAGEMANAGER=urpmi
  fi
}

DEFAULT_ARCH="@@RPM_ARCH@@"
YUM_REPO_FILE="/etc/yum.repos.d/@@NAME@@.repo"
ZYPPER_REPO_FILE="/etc/zypp/repos.d/@@NAME@@.repo"
URPMI_REPO_FILE="/etc/urpmi/urpmi.cfg"

install_yum() {
  install_rpm_key

  if [ ! "$REPOCONFIG" ]; then
    return 0
  fi

  if [ -d "/etc/yum.repos.d" ]; then
cat > "$YUM_REPO_FILE" << REPOCONTENT
[@@NAME@@]
name=@@NAME@@
baseurl=$REPOCONFIG/$DEFAULT_ARCH
enabled=1
gpgcheck=1
gpgkey=https://keybase.io/docs/server_security/code_signing_key.asc
metadata_expire=60
REPOCONTENT
  fi
}

# This is called by the cron job, rather than in the RPM postinstall.
# We cannot do this during the install when urpmi is running due to
# database locking. We also need to enable the repository, and we can
# only do that while we are online.
# see: https://qa.mandriva.com/show_bug.cgi?id=31893
configure_urpmi() {
  if [ ! "$REPOCONFIG" ]; then
    return 0
  fi

  urpmq --list-media | grep -q -s "^@@NAME@@$"
  if [ "$?" -eq "0" ]; then
    # Repository already configured
    return 0
  fi
  urpmi.addmedia --update \
    "@@NAME@@" "$REPOCONFIG/$DEFAULT_ARCH"
}

install_urpmi() {
  # urpmi not smart enough to pull media_info/pubkey from the repository?
  install_rpm_key

  # Defer urpmi.addmedia to configure_urpmi() in the cron job.
  # See comment there.
  #
  # urpmi.addmedia --update \
  #   "@@NAME@@" "$REPOCONFIG/$DEFAULT_ARCH"
}

install_yast() {
  if [ ! "$REPOCONFIG" ]; then
    return 0
  fi

  # We defer adding the key to later. See comment in the cron job.

  # Ideally, we would run: zypper addrepo -t YUM -f \
  # "$REPOCONFIG/$DEFAULT_ARCH" "@@NAME@@"
  # but that does not work when zypper is running.
  if [ -d "/etc/zypp/repos.d" ]; then
cat > "$ZYPPER_REPO_FILE" << REPOCONTENT
[@@NAME@@]
name=@@NAME@@
enabled=1
autorefresh=1
baseurl=$REPOCONFIG/$DEFAULT_ARCH
type=rpm-md
keeppackages=0
REPOCONTENT
  fi
}

# Check if the automatic repository configuration is done, so we know when to
# stop trying.
verify_install() {
  # It's probably enough to see that the repo configs have been created. If they
  # aren't configured properly, update_bad_repo should catch that when it's run.
  case $1 in
  "yum")
    [ -f "$YUM_REPO_FILE" ]
    ;;
  "yast")
    [ -f "$ZYPPER_REPO_FILE" ]
    ;;
  "urpmi")
    urpmq --list-url | grep -q -s "\b@@NAME@@\b"
    ;;
  esac
}

# Update the Keybase repository if it's not set correctly.
update_bad_repo() {
  if [ ! "$REPOCONFIG" ]; then
    return 0
  fi

  determine_rpm_package_manager

  case $PACKAGEMANAGER in
  "yum")
    update_repo_file "$YUM_REPO_FILE"
    ;;
  "yast")
    update_repo_file "$ZYPPER_REPO_FILE"
    ;;
  "urpmi")
    update_urpmi_cfg
    ;;
  esac
}

update_repo_file() {
  REPO_FILE="$1"

  # Don't do anything if the file isn't there, since that probably means the
  # user disabled it.
  if [ ! -r "$REPO_FILE" ]; then
    return 0
  fi

  # Check if the correct repository configuration is in there.
  REPOMATCH=$(grep "^baseurl=$REPOCONFIG/$DEFAULT_ARCH" "$REPO_FILE" \
    2>/dev/null)
  # If it's there, nothing to do
  if [ "$REPOMATCH" ]; then
    return 0
  fi

  # Check if it's there but disabled by commenting out (as opposed to using the
  # 'enabled' setting).
  MATCH_DISABLED=$(grep "^[[:space:]]*#.*baseurl=$REPOCONFIG/$DEFAULT_ARCH" \
    "$REPO_FILE" 2>/dev/null)
  if [ "$MATCH_DISABLED" ]; then
    # It's OK for it to be disabled, as long as nothing bogus is enabled in its
    # place.
    ACTIVECONFIGS=$(grep "^baseurl=.*" "$REPO_FILE" 2>/dev/null)
    if [ ! "$ACTIVECONFIGS" ]; then
      return 0
    fi
  fi

  # If we get here, the correct repository wasn't found, or something else is
  # active, so fix it. This assumes there is a 'baseurl' setting, but if not,
  # then that's just another way of disabling, so we won't try to add it.
  sed -i -e "s,^baseurl=.*,baseurl=$REPOCONFIG/$DEFAULT_ARCH," "$REPO_FILE"
}

update_urpmi_cfg() {
  REPOCFG=$(urpmq --list-url | grep "\b@@NAME@@\b")
  if [ ! "$REPOCFG" ]; then
    # Don't do anything if the repo isn't there, since that probably means the
    # user deleted it.
    return 0
  fi

  # See if it's the right repo URL
  REPOMATCH=$(echo "$REPOCFG" | grep "\b$REPOCONFIG/$DEFAULT_ARCH\b")
  # If so, nothing to do
  if [ "$REPOMATCH" ]; then
    return 0
  fi

  # Looks like it's the wrong URL, so recreate it.
  urpmi.removemedia "@@NAME@@" && \
    urpmi.addmedia --update "@@NAME@@" "$REPOCONFIG/$DEFAULT_ARCH"
}

## MAIN ##
DEFAULTS_FILE="/etc/default/@@NAME@@"
if [ -r "$DEFAULTS_FILE" ]; then
  . "$DEFAULTS_FILE"
fi

if [ "$repo_add_once" = "true" ]; then
  determine_rpm_package_manager

  # The initial install happens in the post-install scripts, but there have been
  # reports of configuration problems, so just verify that everything looks
  # good, and if not, try to install again.
  verify_install $PACKAGEMANAGER
  if [ $? -ne 0 ]; then
    install_${PACKAGEMANAGER}
  fi

  # Now do any extra configuration that couldn't be done by post-install.
  case $PACKAGEMANAGER in
  "urpmi")
    # We need to configure urpmi after the install has finished.
    # See configure_urpmi() for details.
    configure_urpmi
    ;;
  "yast")
    # It looks as though yast/zypper has a lock on the RPM DB during
    # postinstall, so we cannot add the signing key with install_rpm_key().
    # Instead, we attempt to do this here. If the user attempt to update before
    # the cron job imports the key, Yast will grab the key from our server and
    # prompt the user to accept the key.
    install_rpm_key
    ;;
  esac

  if [ $? -eq 0 ]; then
    # Before we quit auto-configuration, check that everything looks sane, since
    # part of this happened during package install and we don't have the return
    # value of that process.
    verify_install $PACKAGEMANAGER
    if [ $? -eq 0 ]; then
      sed -i -e 's/[[:space:]]*repo_add_once=.*/repo_add_once="false"/' \
        "$DEFAULTS_FILE"
    fi
  fi
else
  update_bad_repo
fi
