#!/bin/sh

# refresh-pubring  version 0.11
# A script to update a portion of your GPG keyring
#
# Copyright (c) 2005-2025 Francesco Poli
# 
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

usage()
{
    NAME=$(basename "$0")
    printf 'usage: %s [NUMBER_OF_KEYS]\n' "$NAME" 1>&2
}

update_keys()
{
    # determine which keys have to be updated
    while read -r KEY
    do
        set -- "$@" "$KEY"
    done <<- EOF
	$(gpg --list-keys --with-colons 2> /dev/null | grep '^pub' | \
	awk -F: "$FIRST <= NR && NR < $REMEMBER {print \"0x\"\$5;}")
	EOF

    if test "$#" = 1 -a "$1" = ""
    then
        return 1
    fi

    # update them
    gpg --keyserver-options no-honor-keyserver-url \
        --import-options    repair-pks-subkey-bug  \
        --refresh-keys "$@" 2>&1 || return 2
}

# compute number of keys to be refreshed
NKEYS=${1:-"1"}
if test "$NKEYS" -eq "$NKEYS" 2> /dev/null   # if $NKEYS is an integer...
then
    if test "$NKEYS" -le "0"
    then
        usage
        exit 1
    fi
else        # if $NKEYS is not an integer...
    usage
    exit 2
fi


# determine where we must start from
FILERC=~/.refresh-pubringrc
if test -r "$FILERC"
then
    TEMP=$(head -n 1 "$FILERC")
    if test "$TEMP" -gt "0" 2> /dev/null
    then
        NEXT="$TEMP"
    fi
fi
FIRST=${NEXT:-"1"}

# compute where we'll start from next time
REMEMBER=$((FIRST + NKEYS))
SAVE="no"

# count the total number of keys in the keyring (and tell the user)
TOTALNUM=$(gpg --list-keys --with-colons 2> /dev/null | grep -c '^pub')
printf "found %d keys in keyring...\n\n" "$TOTALNUM"

# update keys
update_keys

case "$?" in
    0) SAVE="yes" ;;
    1) printf "end of keyring reached: will start from beginning next time\n"
       REMEMBER="1"
       SAVE="yes" ;;
    2) SAVE="no" ;;
esac

# save where we'll start from next time
if test "$SAVE" = "yes"
then
    printf '%s\n' "$REMEMBER" > "$FILERC"
fi
