commit:     28cd240fb23d880b8641a058831c6762db71c3e2
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 29 22:34:37 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Apr  9 06:51:35 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=28cd240f

emerge-webrsync: support PGP verification via gemato

Introduce PGP verification of the webrsync snapshot tarballs
using app-portage/gemato - which is already a dependency of Portage
for verifying normal rsync.

This is the same method Portage uses (see below).

Technical changes before we dive into the rationale:
- Use gemato for PGP verification just like Portage does for
  sync-type=webrsync, sync-type=rsync (although that uses a metamanifest),
  and sync-type=git (although that uses gemato for gpg-wrap, so works 
differently).

- Use gentoo-functions automagically if available for better output
  functions.

- Be more verbose about verification and various other operations,
  while also respecting --quiet if passed for misc. existing & new
  messages.

- Make --verbose a no-op. There weren't enough output messages
  to justify three states (--quiet, normal, --verbose).

- Bail out more aggressively in the event of errors or "warnings".

- Use modern terminology for repository, etc (avoid overloading the
  "portage" term.)

- Allow disabling PGP verification with --no-pgp-verify.

Technically, the fix is very straightforward, but getting to
the fix was the slightly painful bit. What I've concluded
happened is:
- Portage starts getting reworked to gain proper sync module support;

- Someone gets the idea of implementing emerge-webrsync fully in Python
  as a Portage sync module (which is a not-unreasonable idea);

  [This ultimately hasn't gone anywhere, and in fact, while working on this
  bug, I ended up finding a bunch of typos that meant you couldn't even test it.
  But it's a stub anyway.]

- The idea of deprecating emerge-webrsync is floated around. The idea
  being Portage should call it via its new sync module with sync-type=webrsync.

  This is presumably with the ultimate goal of it transparently one day
  using the aforementioned (yet-non-existent) Python implementation as its
  backend, and not the shell script.

  [To this day, Portage's webrsync implementation shells out to the 
emerge-webrsync
  shell script, but it has the abstraction to switch that out, in theory.]

- At the time, PGP verification in general of the Gentoo
  repository is an active topic, especially now we'd migrated to git which makes
  it way easier, unlike CVS.

- A bug is filed for PGP verification in emerge-webrsync.

  People decide it doesn't matter too much, because Portage is going to
  Real Soon Now (TM) have its own backend (replacing the shell script) and/or
  Portage's sync module support obsoletes emerge-webrsync entirely.

  The idea here, I think, being that nobody should call emerge-webrsync and
  everyone should just call emerge (or emaint) to sync as appropriate.

  [This isn't a terrible idea in a sense, but it needs a better basis:
  we should probably make emerge-webrsync a wrapper which creates a temporary
  repo config to forcefully webrsync a repository if the user asks us to. This
  is what people expect from emerge-webrsync with the default sync-type=rsync
  in repos.conf for ::gentoo.

  I actually started implementing this before I realised that emerge was
  shelling out to emerge-webrsync, so have postponed it.]

- Then nothing happens with the "replacement" ideas and the good
  ol' trusty emerge-webrsync ends up with the same problems sitting
  there because nobody saw the point in working on it if it was to
  be replaced soon. But that didn't happen.

The fix overall for this is pretty small, but the commit is larger
than I'd like because I had to rework a few things to sensibly allow
disabling PGP verification as well as follow the flow.

(I did start splitting up this commit but ultimately it needs -w
for best review even without the output tweaks in this commit and
deconstructing this for atomic commits would end up being more brittle
as I couldn't be as confident in the result.)

Bug: https://bugs.gentoo.org/597800
Signed-off-by: Sam James <sam <AT> gentoo.org>

 NEWS                |   5 +
 bin/emerge-webrsync | 363 ++++++++++++++++++++++++++++++++++------------------
 2 files changed, 240 insertions(+), 128 deletions(-)

diff --git a/NEWS b/NEWS
index 3dfaf2a09..4a41fc0c6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
 portage-3.0.47 (UNRELEASED)
 ---------------
 
+Security:
+* emerge-webrsync (the standalone tool) now verifies PGP signatures, see
+  bug #597800. Note that 'sync-type = webrsync' in repos.conf already
+  handled PGP verification when configured to do so (and it is by default).
+
 Features:
 * install-qa-check.d: 90gcc-warnings: Add additional code quality warnings:
   - -Wrestrict

diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
index 4b982a1c1..43ac18f46 100755
--- a/bin/emerge-webrsync
+++ b/bin/emerge-webrsync
@@ -24,14 +24,49 @@
 # gpg --homedir /etc/portage/gnupg --edit-key ${KEY_ID} trust
 #
 
-# Only echo if in verbose mode
-vvecho() { [[ ${do_verbose} -eq 1 ]] && echo "$@" ; }
-# Only echo if not in verbose mode
-nvecho() { [[ ${do_verbose} -eq 0 ]] && echo "$@" ; }
-# warning echos
-wecho() { echo "${argv0##*/}: warning: $*" 1>&2 ; }
-# error echos
-eecho() { echo "${argv0##*/}: error: $*" 1>&2 ; }
+# Opportunistically use gentoo-functions for nicer output
+functions_script="${EPREFIX:-/}/lib/gentoo/functions.sh"
+source "${functions_script}" || {
+       echo "${argv0}: Could not source ${functions_script}!" 1>&2
+
+       ebegin() {
+               printf '%s*%s %s ... ' "${GOOD}" "${NORMAL}" "$*"
+       }
+
+       eend() {
+               local r=${1:-0}
+               shift
+               if [[ $r -eq 0 ]] ; then
+                       printf '[ %sok%s ]\n' "${GOOD}" "${NORMAL}"
+               else
+                       printf '%s [ %s!!%s ]\n' "$*" "${BAD}" "${NORMAL}"
+               fi
+               return "${r}"
+       }
+
+       einfo() {
+               echo "${argv0##*/}: $*"
+       }
+
+       ewarn() {
+               echo "${argv0##*/}: warning: $*" 1>&2
+       }
+
+       eerror() {
+               echo "${argv0##*/}: error: $*" 1>&2
+       }
+
+}
+
+# Only echo if in normal mode
+vvecho() { [[ ${PORTAGE_QUIET} != 1 ]] && echo "$@" ; }
+# Only echo if in quiet mode
+nvecho() { [[ ${PORTAGE_QUIET} == 1 ]] && echo "$@" ; }
+
+# Unfortunately, gentoo-functions doesn't yet have a die() (bug #878505)
+die() {
+       eerror "$@" && exit 1
+}
 
 argv0=$0
 
@@ -43,8 +78,7 @@ if [[ -x "${scriptpath%/*}/portageq" ]]; then
 elif type -P portageq > /dev/null ; then
        portageq=portageq
 else
-       eecho "could not find 'portageq'; aborting"
-       exit 1
+       die "could not find 'portageq'; aborting"
 fi
 
 eval "$("${portageq}" envvar -v DISTDIR EPREFIX FEATURES \
@@ -60,54 +94,74 @@ source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
 repo_name=gentoo
 repo_location=$(__repo_attr "${repo_name}" location)
 if [[ -z ${repo_location} ]]; then
-       eecho "Repository '${repo_name}' not found"
-       exit 1
+       die "Repository '${repo_name}' not found"
 fi
 repo_sync_type=$(__repo_attr "${repo_name}" sync-type)
 
 # If PORTAGE_NICENESS is overriden via the env then it will
 # still pass through the portageq call and override properly.
 if [[ -n "${PORTAGE_NICENESS}" ]]; then
-       renice ${PORTAGE_NICENESS} $$ > /dev/null
+       renice "${PORTAGE_NICENESS}" $$ > /dev/null
 fi
 
-do_verbose=0
 do_debug=0
 keep=false
 
-has webrsync-gpg ${FEATURES} && webrsync_gpg=1 || webrsync_gpg=0
+handle_pgp_setup() {
+       has webrsync-gpg ${FEATURES} && webrsync_gpg=1 || webrsync_gpg=0
 
-if [[ ${webrsync_gpg} -eq 1 ]]; then
-       wecho "FEATURES=webrsync-gpg is deprecated, see the make.conf(5) man 
page."
-fi
+       if [[ ${webrsync_gpg} -eq 1 ]]; then
+               ewarn "FEATURES=webrsync-gpg is deprecated, see the 
make.conf(5) man page."
+       fi
 
-repo_has_webrsync_verify=$(
-       has $(__repo_attr "${repo_name}" sync-webrsync-verify-signature | 
LC_ALL=C tr '[:upper:]' '[:lower:]') true yes
-)
-
-if [[ -n ${PORTAGE_TEMP_GPG_DIR} ]] || [[ ${repo_has_webrsync_verify} -eq 1 
]]; then
-       # If FEATURES=webrsync-gpg is enabled then allow direct emerge-webrsync
-       # calls for backward compatibility (this triggers a deprecation warning
-       # above). Since direct emerge-webrsync calls do not use gemato for 
secure
-       # key refresh, this behavior will not be supported in a future release.
-       if [[ ! ( -d ${PORTAGE_GPG_DIR} && ${webrsync_gpg} -eq 1 ) &&
-               -z ${PORTAGE_TEMP_GPG_DIR} ]]; then
-               eecho "Do not call ${argv0##*/} directly, instead call emerge 
--sync or emaint sync."
-               exit 1
+       repo_has_webrsync_verify=$(
+               has $(__repo_attr "${repo_name}" sync-webrsync-verify-signature 
| LC_ALL=C tr '[:upper:]' '[:lower:]') true yes
+       )
+
+       # WEBRSYNC_VERIFY_SIGNATURE=0: disable PGP verification
+       # WEBRSYNC_VERIFY_SIGNATURE=1: use gemato for verification, fallback to 
regular gpg
+       # WEBRSYNC_VERIFY_SIGNATURE=2: use legacy FEATURES="webrsync-gpg"
+       WEBRSYNC_VERIFY_SIGNATURE=1
+
+       if [[ -n ${PORTAGE_TEMP_GPG_DIR} ]] || [[ ${repo_has_webrsync_verify} 
-eq 1 ]]; then
+               # If FEATURES=webrsync-gpg is enabled then allow direct 
emerge-webrsync
+               # calls for backward compatibility (this triggers a deprecation 
warning
+               # above). Since direct emerge-webrsync calls do not use gemato 
for secure
+               # key refresh, this behavior will not be supported in a future 
release.
+               if [[ ! ( -d ${PORTAGE_GPG_DIR} && ${webrsync_gpg} -eq 1 ) && 
-z ${PORTAGE_TEMP_GPG_DIR} ]]; then
+                       die "Do not call ${argv0##*/} directly, instead call 
emerge --sync or emaint sync."
+               fi
+
+               WEBRSYNC_VERIFY_SIGNATURE=2
+       elif has webrsync-gpg ${FEATURES}; then
+               WEBRSYNC_VERIFY_SIGNATURE=2
+       elif [[ -n ${no_pgp_verify} ]]; then
+               WEBRSYNC_VERIFY_SIGNATURE=0
        fi
 
-       WEBSYNC_VERIFY_SIGNATURE=1
-elif has webrsync-gpg ${FEATURES}; then
-       WEBSYNC_VERIFY_SIGNATURE=1
-else
-       WEBSYNC_VERIFY_SIGNATURE=0
-fi
+       case "${WEBRSYNC_VERIFY_SIGNATURE}" in
+               0)
+                       [[ ${PORTAGE_QUIET} -eq 1 ]] || ewarn "PGP verification 
method: disabled"
+                       ;;
+               1)
+                       [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "PGP verification 
method: gemato"
+                       ;;
+               2)
+                       ewarn "PGP verification method: legacy 
FEATURES=webrsync-gpg"
+                       ;;
+               *)
+                       die "Unknown WEBRSYNC_VERIFY_SIGNATURE state: 
\${WEBRSYNC_VERIFY_SIGNATURE}=${WEBRSYNC_VERIFY_SIGNATURE}"
+                       ;;
+       esac
 
-[[ -n ${PORTAGE_TEMP_GPG_DIR} ]] && PORTAGE_GPG_DIR=${PORTAGE_TEMP_GPG_DIR}
-if [[ ${WEBSYNC_VERIFY_SIGNATURE} != 0 && -z "${PORTAGE_GPG_DIR}" ]]; then
-       eecho "Please set PORTAGE_GPG_DIR in make.conf!"
-       exit 1
-fi
+       if [[ -n ${PORTAGE_TEMP_GPG_DIR} ]]; then
+               PORTAGE_GPG_DIR=${PORTAGE_TEMP_GPG_DIR}
+       fi
+
+       if [[ ${WEBRSYNC_VERIFY_SIGNATURE} == 2 && -z "${PORTAGE_GPG_DIR}" ]]; 
then
+               die "Please set PORTAGE_GPG_DIR in make.conf!"
+       fi
+}
 
 do_tar() {
        local file=$1
@@ -134,9 +188,9 @@ get_date_part() {
        local part="$2"
 
        if [[ ${USERLAND} == BSD ]] ; then
-               date -r ${utc_time_in_secs} -u +"${part}"
+               date -r "${utc_time_in_secs}" -u +"${part}"
        else
-               date -d @${utc_time_in_secs} -u +"${part}"
+               date -d "@${utc_time_in_secs}" -u +"${part}"
        fi
 }
 
@@ -152,7 +206,7 @@ get_utc_second_from_string() {
        fi
 }
 
-get_portage_timestamp() {
+get_repository_timestamp() {
        local portage_current_timestamp=0
 
        if [[ -f "${repo_location}/metadata/timestamp.x" ]]; then
@@ -175,7 +229,7 @@ fetch_file() {
                rm -f "${DISTDIR}/${FILE}"
        fi
 
-       __vecho "Fetching file ${FILE} ..."
+       [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Fetching file ${FILE} ..."
        # Already set DISTDIR=
        eval "${FETCHCOMMAND} ${opts}"
 
@@ -192,7 +246,7 @@ check_file_digest() {
        local file="$2"
        local r=1
 
-       __vecho "Checking digest ..."
+       [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Checking digest ..."
 
        if type -P md5sum > /dev/null; then
                local md5sum_output=$(md5sum "${file}")
@@ -201,43 +255,85 @@ check_file_digest() {
        elif type -P md5 > /dev/null; then
                [[ "$(md5 -q "${file}")" == "$(cut -d ' ' -f 1 "${digest}")" ]] 
&& r=0
        else
-               eecho "cannot check digest: no suitable md5/md5sum binaries 
found"
+               die "cannot check digest: no suitable md5/md5sum binaries found"
        fi
 
        return "${r}"
 }
 
-check_file_signature() {
+check_file_signature_gemato() {
        local signature="$1"
        local file="$2"
        local r=1
-       local gnupg_status line
 
-       if [[ ${WEBSYNC_VERIFY_SIGNATURE} != 0 ]]; then
-               __vecho "Checking signature ..."
+       if type -P gemato > /dev/null; then
+               local gemato_args=(
+                       openpgp-verify-detached
+                       -K /usr/share/openpgp-keys/gentoo-release.asc
+               )
 
-               if type -P gpg > /dev/null; then
-                       if gnupg_status=$(gpg --homedir "${PORTAGE_GPG_DIR}" 
--batch \
-                               --status-fd 1 --verify "${signature}" 
"${file}"); then
-                               while read -r line; do
-                                       if [[ ${line} == "[GNUPG:] GOODSIG"* 
]]; then
-                                               r=0
-                                               break
-                                       fi
-                               done <<< "${gnupg_status}"
-                       fi
+               [[ ${PORTAGE_QUIET} == 1 ]] && gemato_args+=( --quiet )
+               [[ ${do_debug} == 1 ]] && gemato_args+=( --debug )
 
-                       if [[ ${r} -ne 0 ]]; then
-                               # Exit early since it's typically inappropriate 
to
-                               # try other mirrors in this case (it may 
indicate
-                               # a keyring problem).
-                               eecho "signature verification failed"
-                               exit 1
-                       fi
-               else
-                       eecho "cannot check signature: gpg binary not found"
-                       exit 1
+               gemato "${gemato_args[@]}" "${signature}" "${file}"
+               r=$?
+
+               if [[ ${r} -ne 0 ]]; then
+                       # Exit early since it's typically inappropriate to
+                       # try other mirrors in this case (it may indicate
+                       # a keyring problem).
+                       die "signature verification failed"
+               fi
+       fi
+
+       return "${r}"
+}
+
+check_file_signature_gpg_unwrapped() {
+       local signature="$1"
+       local file="$2"
+
+       if type -P gpg > /dev/null; then
+               if gnupg_status=$(gpg --homedir "${PORTAGE_GPG_DIR}" --batch \
+                       --status-fd 1 --verify "${signature}" "${file}"); then
+                       while read -r line; do
+                               if [[ ${line} == "[GNUPG:] GOODSIG"* ]]; then
+                                       r=0
+                                       break
+                               fi
+                       done <<< "${gnupg_status}"
                fi
+
+               if [[ ${r} -ne 0 ]]; then
+                       # Exit early since it's typically inappropriate to
+                       # try other mirrors in this case (it may indicate
+                       # a keyring problem).
+                       die "signature verification failed"
+               fi
+       else
+               die "cannot check signature: gpg binary not found"
+       fi
+}
+
+check_file_signature() {
+       local signature="$1"
+       local file="$2"
+       local r=1
+       local gnupg_status line
+
+       if [[ ${WEBRSYNC_VERIFY_SIGNATURE} != 0 ]]; then
+               [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Checking signature ..."
+
+               case ${WEBRSYNC_VERIFY_SIGNATURE} in
+                       1)
+                               check_file_signature_gemato "${signature}" 
"${file}"
+                               r=$?
+                               ;;
+                       2)
+                               check_file_signature_gpg_unwrapped 
"${signature}" "${file}"
+                               r=$?
+                               ;;
+               esac
        else
                r=0
        fi
@@ -254,7 +350,7 @@ get_snapshot_timestamp() {
 sync_local() {
        local file="$1"
 
-       __vecho "Syncing local tree ..."
+       [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Syncing local repository ..."
 
        local ownership="portage:portage"
        if has usersync ${FEATURES} ; then
@@ -275,36 +371,39 @@ sync_local() {
                if ! tarsync $(vvecho -v) -s 1 ${chown_opts} \
                        -e /distfiles -e /packages -e /local "${file}" 
"${repo_location}"; then
 
-                       eecho "tarsync failed; tarball is corrupt? (${file})"
+                       eerror "tarsync failed; tarball is corrupt? (${file})"
                        return 1
                fi
        else
                if ! do_tar "${file}" -x --strip-components=1 -f -; then
-                       eecho "tar failed to extract the image. tarball is 
corrupt? (${file})"
+                       eerror "tar failed to extract the image. tarball is 
corrupt? (${file})"
                        return 1
                fi
 
                # Free disk space
                ${keep} || rm -f "${file}"
 
-               local rsync_opts="${PORTAGE_RSYNC_OPTS} 
${PORTAGE_RSYNC_EXTRA_OPTS}"
+               local rsync_opts="${PORTAGE_RSYNC_OPTS} 
${PORTAGE_RSYNC_EXTRA_OPTS} $(nvecho -q)"
                if chown ${ownership} . > /dev/null 2>&1; then
                        chown -R ${ownership} .
                        rsync_opts+=" --owner --group"
                fi
 
                chmod 755 .
-               rsync ${rsync_opts} . "${repo_location%%/}"
+               rsync ${rsync_opts} . "${repo_location%%/}" || {
+                       eerror "rsync failed: $?"
+                       die "Aborting because of rsync failure"
+               }
 
-               __vecho "Cleaning up ..."
+               [[ ${PORTAGE_QUIET} == 1 ]] || einfo "Cleaning up ..."
        fi
 
        if has metadata-transfer ${FEATURES} ; then
-               __vecho "Updating cache ..."
+               einfo "Updating cache ..."
                emerge --metadata
        fi
 
-       local post_sync=${PORTAGE_CONFIGROOT}etc/portage/bin/post_sync
+       local post_sync=${PORTAGE_CONFIGROOT%/}/etc/portage/bin/post_sync
        [[ -x "${post_sync}" ]] && "${post_sync}"
 
        # --quiet suppresses output if there are no relevant news items
@@ -327,20 +426,20 @@ do_snapshot() {
 
        type -P xzcat > /dev/null && compressions="${compressions} 
${repo_name}:xz portage:xz"
        type -P bzcat > /dev/null && compressions="${compressions} 
${repo_name}:bz2 portage:bz2"
-       type -P  zcat > /dev/null && compressions="${compressions} 
${repo_name}:gz portage:gz"
-
+       type -P zcat > /dev/null && compressions="${compressions} 
${repo_name}:gz portage:gz"
        if [[ -z ${compressions} ]] ; then
-               eecho "unable to locate any decompressors (xzcat or bzcat or 
zcat)"
-               exit 1
+               die "unable to locate any decompressors (xzcat or bzcat or 
zcat)"
        fi
 
        for mirror in ${GENTOO_MIRRORS} ; do
                mirror=${mirror%/}
-               __vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
+               [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Trying to retrieve 
${date} snapshot from ${mirror} ..."
 
                for compression in ${compressions} ; do
                        local name=${compression%%:*}
+
                        compression=${compression#*:}
+
                        local file="${name}-${date}.tar.${compression}"
                        local digest="${file}.md5sum"
                        local signature="${file}.gpgsig"
@@ -353,10 +452,11 @@ do_snapshot() {
 
                        if [[ ${have_files} -eq 0 ]] ; then
                                fetch_file "${mirror}/snapshots/${digest}" 
"${digest}" && \
-                               fetch_file "${mirror}/snapshots/${signature}" 
"${signature}" && \
-                               fetch_file "${mirror}/snapshots/${file}" 
"${file}" && \
-                               check_file_digest "${DISTDIR}/${digest}" 
"${DISTDIR}/${file}" && \
-                               check_file_signature "${DISTDIR}/${signature}" 
"${DISTDIR}/${file}" && \
+                                       fetch_file 
"${mirror}/snapshots/${signature}" "${signature}" && \
+                                       fetch_file 
"${mirror}/snapshots/${file}" "${file}" && \
+                                       check_file_digest 
"${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \
+                                       check_file_signature 
"${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \
+
                                have_files=1
                        fi
 
@@ -366,25 +466,25 @@ do_snapshot() {
                        # from a different mirror
                        #
                        if [[ ${have_files} -eq 1 ]]; then
-                               __vecho "Getting snapshot timestamp ..."
-                               local 
snapshot_timestamp=$(get_snapshot_timestamp "${DISTDIR}/${file}")
+                               [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Getting 
snapshot timestamp ..."
+
+                               local snapshot_timestamp
+                               snapshot_timestamp=$(get_snapshot_timestamp 
"${DISTDIR}/${file}")
 
                                if [[ ${ignore_timestamp} == 0 ]]; then
-                                       if [[ ${snapshot_timestamp} -lt 
$(get_portage_timestamp) ]]; then
-                                               wecho "portage is newer than 
snapshot"
+                                       if [[ ${snapshot_timestamp} -lt 
$(get_repository_timestamp) ]]; then
+                                               ewarn "Repository (age) is 
newer than fetched snapshot"
                                                have_files=0
                                        fi
                                else
-                                       local 
utc_seconds=$(get_utc_second_from_string "${date}")
+                                       local utc_seconds
+                                       
utc_seconds=$(get_utc_second_from_string "${date}")
 
-                                       #
-                                       # Check that this snapshot
-                                       # is what it claims to be ...
-                                       #
+                                       # Check that this snapshot is what the 
age it claims to be
                                        if [[ ${snapshot_timestamp} -lt 
${utc_seconds} || \
                                                ${snapshot_timestamp} -gt 
$((${utc_seconds}+ 2*86400)) ]]; then
 
-                                               wecho "snapshot timestamp is 
not in acceptable period"
+                                               ewarn "Snapshot timestamp is 
not within acceptable period!"
                                                have_files=0
                                        fi
                                fi
@@ -393,9 +493,7 @@ do_snapshot() {
                        if [[ ${have_files} -eq 1 ]]; then
                                break
                        else
-                               #
                                # Remove files and use a different mirror
-                               #
                                rm -f "${DISTDIR}/${file}" 
"${DISTDIR}/${digest}" "${DISTDIR}/${signature}"
                        fi
                done
@@ -406,7 +504,7 @@ do_snapshot() {
        if [[ ${have_files} -eq 1 ]]; then
                sync_local "${DISTDIR}/${file}" && r=0
        else
-               __vecho "${date} snapshot was not found"
+               ewarn "${date} snapshot was not found"
        fi
 
        ${keep} || rm -f "${DISTDIR}/${file}" "${DISTDIR}/${digest}" 
"${DISTDIR}/${signature}"
@@ -417,7 +515,7 @@ do_latest_snapshot() {
        local attempts=0
        local r=1
 
-       __vecho "Fetching most recent snapshot ..."
+       [[ ${PORTAGE_QUIET} -eq 1 ]] || einfo "Fetching most recent snapshot 
..."
 
        # The snapshot for a given day is generated at 00:45 UTC on the 
following
        # day, so the current day's snapshot (going by UTC time) hasn't been
@@ -428,12 +526,18 @@ do_latest_snapshot() {
        # are considered to be approximately equal.
        local min_time_diff=$(( 2 * 60 * 60 ))
 
-       local existing_timestamp=$(get_portage_timestamp)
+       local existing_timestamp
        local timestamp_difference
        local timestamp_problem
        local approx_snapshot_time
-       local start_time=$(get_utc_date_in_seconds)
-       local start_hour=$(get_date_part ${start_time} "%H")
+       local start_time
+       local start_hour
+       local snapshot_date
+       local snapshot_date_seconds
+
+       existing_timestamp=$(get_repository_timestamp)
+       start_time=$(get_utc_date_in_seconds)
+       start_hour=$(get_date_part "${start_time}" "%H")
 
        # Daily snapshots are created at 00:45 and are not
        # available until after 01:00. Don't waste time trying
@@ -441,17 +545,19 @@ do_latest_snapshot() {
        if [[ ${start_hour} -lt 1 ]] ; then
                (( start_time -= 86400 ))
        fi
-       local snapshot_date=$(get_date_part ${start_time} "%Y%m%d")
-       local snapshot_date_seconds=$(get_utc_second_from_string 
${snapshot_date})
 
-       while (( ${attempts} <  40 )) ; do
+       snapshot_date=$(get_date_part "${start_time}" "%Y%m%d")
+       snapshot_date_seconds=$(get_utc_second_from_string "${snapshot_date}")
+
+       while (( ${attempts} < 40 )) ; do
                (( attempts++ ))
                (( snapshot_date_seconds -= 86400 ))
                # snapshots are created at 00:45
                (( approx_snapshot_time = snapshot_date_seconds + 86400 + 2700 
))
                (( timestamp_difference = existing_timestamp - 
approx_snapshot_time ))
-               [ ${timestamp_difference} -lt 0 ] && (( timestamp_difference = 
-1 * timestamp_difference ))
-               snapshot_date=$(get_date_part ${snapshot_date_seconds} "%Y%m%d")
+
+               [[ ${timestamp_difference} -lt 0 ]] && (( timestamp_difference 
= -1 * timestamp_difference ))
+               snapshot_date=$(get_date_part "${snapshot_date_seconds}" 
"%Y%m%d")
 
                timestamp_problem=""
                if [[ ${timestamp_difference} -eq 0 ]]; then
@@ -497,9 +603,10 @@ usage() {
 
        Options:
          --revert=yyyymmdd   Revert to snapshot
+         --no-pgp-verify     Disable PGP verification of snapshot
          -k, --keep          Keep snapshots in DISTDIR (don't delete)
          -q, --quiet         Only output errors
-         -v, --verbose       Enable verbose output
+         -v, --verbose       Enable verbose output (no-op)
          -x, --debug         Enable debug output
          -h, --help          This help screen (duh!)
        EOF
@@ -521,24 +628,25 @@ main() {
                        -h|--help)    usage ;;
                        -k|--keep)    keep=true ;;
                        -q|--quiet)   PORTAGE_QUIET=1 ;;
-                       -v|--verbose) do_verbose=1 ;;
+                       -v|--verbose) unset PORTAGE_QUIET ;;
                        -x|--debug)   do_debug=1 ;;
                        --revert=*)   revert_date=${v} ;;
+                       --no-pgp-verify) no_pgp_verify=1 ;;
                        *)            usage "Invalid option '${arg}'" ;;
                esac
        done
 
+       handle_pgp_setup
+
        [[ -d ${repo_location} ]] || mkdir -p "${repo_location}"
        if [[ ! -w ${repo_location} ]] ; then
-               eecho "Repository '${repo_name}' is not writable: 
${repo_location}"
-               exit 1
+               die "Repository '${repo_name}' is not writable: 
${repo_location}"
        fi
 
        [[ -d ${PORTAGE_TMPDIR}/portage ]] || mkdir -p 
"${PORTAGE_TMPDIR}/portage"
        TMPDIR=$(mktemp -d "${PORTAGE_TMPDIR}/portage/webrsync-XXXXXX")
        if [[ ! -w ${TMPDIR} ]] ; then
-               eecho "TMPDIR is not writable: ${TMPDIR}"
-               exit 1
+               die "TMPDIR is not writable: ${TMPDIR}"
        fi
        trap 'cd / ; rm -rf "${TMPDIR}"' EXIT
        cd "${TMPDIR}" || exit 1
@@ -547,21 +655,20 @@ main() {
        [[ ! -d "${DISTDIR}" ]] && mkdir -p "${DISTDIR}"
 
        if ${keep} && [[ ! -w ${DISTDIR} ]] ; then
-               eecho "DISTDIR is not writable: ${DISTDIR}"
-               exit 1
+               die "DISTDIR is not writable: ${DISTDIR}"
        fi
 
        # This is a sanity check to help prevent people like funtoo users
        # from accidentally wiping out their git tree.
-       if [[ -n ${repo_sync_type} &&  ${repo_sync_type} != rsync && 
${repo_sync_type} != webrsync ]] ; then
-               echo "The current sync-type attribute of repository 'gentoo' is 
not set to 'rsync' or 'webrsync':" >&2
-               echo >&2
-               echo "  sync-type=${repo_sync_type}" >&2
-               echo >&2
-               echo "If you intend to use emerge-webrsync then please" >&2
-               echo "adjust sync-type and sync-uri attributes to refer to 
rsync." >&2
-               echo "emerge-webrsync exiting due to abnormal sync-type 
setting." >&2
-               exit 1
+       if [[ -n ${repo_sync_type} && ${repo_sync_type} != rsync && 
${repo_sync_type} != webrsync ]] ; then
+               eerror "The current sync-type attribute of repository 'gentoo' 
is not set to 'rsync' or 'webrsync':"
+               eerror
+               eerror "  sync-type=${repo_sync_type}"
+               eerror
+               eerror "If you intend to use emerge-webrsync then please"
+               eerror "adjust sync-type and sync-uri attributes to refer to 
rsync."
+               eerror "emerge-webrsync exiting due to abnormal sync-type 
setting."
+               die
        fi
 
        [[ ${do_debug} -eq 1 ]] && set -x

Reply via email to