File check-for-expired-apt-key-and-rename-it of Package kimi-utils-ubuntu

#!/bin/bash
LANG=C

# Parse options
NO_COLORS=0
DEBUG=0        # default: hide detailed per-file checks; set to 1 with --debug
for arg in "$@"; do
    case "$arg" in
        --no-colors) NO_COLORS=1 ;;
        --debug) DEBUG=1 ;;
        *) ;;
    esac
done

# Helper to conditionally print detailed info (shown only when --debug is passed)
dprint() {
    if [[ $DEBUG -eq 1 ]]; then
        echo "$@"
    fi
}
dprinte() {
    if [[ $DEBUG -eq 1 ]]; then
        echo "$@" >&2
    fi
}

# ANSI color codes (disabled if --no-colors passed)
if [[ $NO_COLORS -eq 0 ]] && [[ -t 1 ]] && tput setaf 1 &> /dev/null; then
    RED=$(tput setaf 1)     # Red for "expired"
    GREEN=$(tput setaf 2)   # Green for paths
    NC=$(tput sgr0)         # Reset to default color
else
    RED=""
    GREEN=""
    NC=""
fi

readonly KEYRING_DIRS=(
    "/etc/apt/trusted.gpg.d"
    "/etc/apt/keyrings"
    "/usr/share/keyrings"
)

# Check for expired APT keys
expired_keys=()
for KEYRING_DIR in "${KEYRING_DIRS[@]}"; do
    for keyfile in "$KEYRING_DIR"/*.gpg; do
        if [ -f "$keyfile" ]; then
            # retrieve key data
            key_data=$(gpg --with-colons --show-keys "$keyfile" 2>/dev/null)
            if [[ $? -ne 0 || -z "$key_data" ]]; then
                dprinte "Failed to retrieve key data from $keyfile."
                continue
            fi

            # --- Detailed per-file output (shown only with --debug) ---
            # Get unique numeric, non-empty pub expiration epochs
            mapfile -t expiration_dates < <(
                echo "$key_data" \
                    | awk -F: '$1 == "pub" && $7 ~ /^[0-9]+$/ {print $7}' \
                    | sort -n -u
            )

            # Compute earliest non-zero timestamp (min_ts==0 => never)
            min_ts=0
            for ed in "${expiration_dates[@]}"; do
                if [[ -n "$ed" && "$ed" -ne 0 ]]; then
                    if [[ $min_ts -eq 0 || $ed -lt $min_ts ]]; then
                        min_ts=$ed
                    fi
                fi
            done

            # Print header once (conditionally shown)
            dprint "Checking key file: $keyfile"

            # No expiration found
            if [[ ${#expiration_dates[@]} -eq 0 ]] || [[ $min_ts -eq 0 ]]; then
                dprint -e "${NC}${GREEN}No expiration${NC}"
                continue
            fi

            # Single authoritative line using min_ts only (date as YYYY-MM-DD)
            now=$(date +%s)
            expiry_short=$(date -d "@$min_ts" '+%Y-%m-%d')
            expiry_full=$(date -d "@$min_ts" '+%Y-%m-%d %H:%M:%S')

            if (( now > min_ts )); then
                days_ago=$(( (now - min_ts) / 86400 ))
                dprint -e "${NC}${RED}Expired:${NC} $expiry_short, ${RED}$days_ago day(s) ago${NC}"
                expired_keys+=("$keyfile ${NC}(${RED}Expired${NC} on $expiry_full, ${RED}$days_ago day(s) ago${NC})")
            else
                days_left=$(( (min_ts - now) / 86400 ))
                dprint -e "Valid until: $expiry_short, ${NC}${GREEN}$days_left day(s) left${NC}"
            fi

            # Also list each individual expiration (conditionally shown)
            for expiration_date in "${expiration_dates[@]}"; do
                if [[ -z "$expiration_date" || "$expiration_date" -eq 0 ]]; then
                    dprint "${NC}(${GREEN}No expiration${NC})"
                    continue
                fi
                now=$(date +%s)
                expiry_human=$(date -d "@$expiration_date" '+%Y-%m-%d %H:%M:%S')
                if (( now > expiration_date )); then
                    days_ago=$(( (now - expiration_date) / 86400 ))
                    # add to expired list (always collected)
                    expired_keys+=("$keyfile ${NC}(${RED}Expired${NC} on $expiry_human, ${RED}$days_ago day(s) ago${NC})")
                else
                    days_left=$(( (expiration_date - now) / 86400 ))
                    dprint "${NC}(${GREEN}Valid until${NC}: $expiry_human, $days_left day(s) left)"
                fi
            done
            # --- End detailed block ---
        fi
    done
done

# Check if any expired keys were found
if [[ ${#expired_keys[@]} -eq 0 ]]; then
    echo "No expired APT keys found."
    exit 0
fi

# Final summary (always shown) and rename handling
echo -e "Expired APT keys found:"

# Check if running as root
is_root=0
print_root_message=0
if [[ "$(id -u)" -ne 0 ]]; then
    print_root_message=1
else
    is_root=1
fi

# De-duplicate expired_keys entries by filename (keep first occurrence)
declare -A _seen
_unique_expired=()
for entry in "${expired_keys[@]}"; do
    fname=${entry%%[[:space:]]*}
    if [[ -z "${_seen[$fname]}" ]]; then
        _seen[$fname]=1
        _unique_expired+=("$entry")
    fi
done
expired_keys=("${_unique_expired[@]}")

# Process output (always shown)
for line in "${expired_keys[@]}"; do
    echo -e "${GREEN}${line}${NC}"
    if (( is_root )); then
        original_path=$(echo "$line" | awk '{print $1}')
        new_path="${original_path}~"
        while [[ -e "$new_path" ]]; do
            timestamp=$(date +"%Y-%m-%d_%H-%M-%S")
            new_path="${original_path}.${timestamp}~"
        done
        mv "$original_path" "$new_path"
        echo "Successfully renamed: $original_path to $new_path"
    fi
done

if (( print_root_message )); then
    echo
    echo "You need to be root to rename the expired keys"
    echo "so that they do not interfere with updates."
fi
openSUSE Build Service is sponsored by