#!/bin/sh
# Title:    apt-whatsup
# Purpose:  Check status of upgradeable packages
# Project:  NCAR/RAL
# Author:   Stephen Dowdy (sdowdy@ucar.edu)
# RCS:      $Header$
# Note:     See RCS/CVS Log info at End of File
# References:  http://security-tracker.debian.org/tracker
# Caveats:
# Todo:
#
# Copyright UCAR (c) 2006-2015
# University Corporation for Atmospheric Research (UCAR),
# National Center for Atmospheric Research (NCAR),
# Research Applications Laboratory (RAL),
# P.O. Box 3000, Boulder, Colorado, 80307-3000, USA.

is_debug() { [ ${DEBUG:-0} -ge 1 ] ;}
debug() { is_debug && echo "DEBUG: " "$@" 1>&2 ;}

full_prog=$(readlink -f $0)
this_prog=$(basename ${full_prog})

usage() {
    cat <<EOF
${this_prog}:
    ${this_prog} [ -d ] [ -n ] [ -k | {search-pattern} ]

This program reports all the outstanding Debian Package Updates
for this system.

    -d  debug
    -k  display kernel only updates pending
    -n  don't do 'aptitude update' phase
    -s  display security updates only
    {search-pattern}     any apt-regex search pattern
       e.g. "cups", "^apache2$"

EOF
}

security=0; kernel_only=0; no_aptup=0
eval $(apt-config shell apt_default_release APT::Default-Release)
eval $(apt-config shell apt_sourcelist  Dir::Etc::sourcelist/f)
eval $(apt-config shell apt_sourceparts Dir::Etc::sourceparts/d)

if [ "$(id -u)" != 0 ]; then
    echo "Warning: not 'root' so no aptitude update will be performed" 1>&2
    no_aptup=1
fi

while getopts dhkns option; do
    case "${option}" in
        d)  DEBUG=1;;
        k)  kernel_only=1
            search_pattern="~nlinux-(image|header)"
            debug "kernel only called"
            ;;
        n)  no_aptup=1;;
        s)  security=1
            if [ -r ${apt_sourceparts}/security-updates.list ]; then
                apt_opts=-o\ Dir::Etc::sourcelist="${apt_sourceparts}/security-updates.list"\ -o\ Dir::Etc::sourceparts=/dev/null
            else
                # best-effort attempt to find RELEASE/updates source
                trap '[ -f "${tmpfile}" ] && /bin/rm -f "${tmpfile}"' 0
                tmpfile="$(mktemp ${HOME}/apt.sources.list.security.$(date -I)_XXXXXXXX)" || { echo 'ERROR: Could not create temporary file, exiting ... ' 1>&2 ; exit 1 ;}
                readonly tmpfile
                chmod 600 "${tmpfile}"
                awk '$1=="deb"&&$3=="'$(lsb_release -cs)'/updates"{print $0}' \
                    ${apt_sourcelist} ${apt_sourceparts}/*.list \
                    > "${tmpfile}"  2>/dev/null
                apt_opts=-o\ Dir::Etc::sourcelist="${tmpfile}"\ -o\ Dir::Etc::sourceparts=/dev/null
            fi 
            ;;
        h|*)  usage; exit 0;;
    esac
done
shift `expr $OPTIND - 1`
[ -n "$1" ] && search_pattern="$1"

# Update the package description db
if [ "${no_aptup:-0}" -eq 0 ]; then
    debug "performing 'aptitude update'..."
    aptitude -q=2 update
else
    echo "Warning, no aptitude update performed, results may be inaccurate..." 1>&2
fi

debug "finished 'aptitude update'..."
debug "search_pattern=${search_pattern}"

is_debug && set -xv
aptitude ${apt_opts} search --disable-columns -F "%1p# %4v# %1V#" "~U ${search_pattern}" | tr ' ' '\t' | expand -t36,66
is_debug && set +xv

exit

: << END_NOTES

--------------------------------------------------------------------
# aptitude --width=80 versions  '~U'   # '~U' means "upgradeable"
    Package apt:
    i   0.9.7.9                                                                 100
    p   0.9.7.9+deb7u1                                stable                    500

    Package apt-utils:
    i   0.9.7.9                                                                 100
    p   0.9.7.9+deb7u1                                stable                    500
    ...

# aptitude --width=80 versions --group-by=none '~U'
    i   apt 0.9.7.9                                                             100
    p   apt 0.9.7.9+deb7u1                            stable                    500
    i   apt-utils 0.9.7.9                                                       100
    p   apt-utils 0.9.7.9+deb7u1                      stable                    500
    i   base-files 7.1wheezy2                                                   100
    p   base-files 7.1wheezy4                         stable                    500
    ...

--------------------------------------------------------------------
aptitude search -F %p '~U !~n"linux-(image|header)"'
Find all Upgradable packages whose names don't match linux-image or linux-header

--------------------------------------------------------------------
aptitude -y install -F %p '~U !~n"linux-(image|header)"'
Upgrade all packages except the kernel+headers, attempt to do unattended
(with -yes)

pdsh> aptitude update -q=2; DEBIAN_FRONTEND=noninteractive aptitude -q=2 safe-upgrade --assume-yes -o Dpkg::Options::="--force-confold" </dev/null

--------------------------------------------------------------------
aptitude update >/dev/null && aptitude search -F "%1p# %4v# -> %1V#" "~U"

get a listing of all upgradable packages showing name, current version,
and version awaiting upgrade

aptitude search -F "%1p# %4v# -> %1V#" '?upgradable ?not(?name("linux-(image|header)"))'
and exclude kernel packages

--------------------------------------------------------------------
Show packages that are non-free or contrib.  These have a DIFFERING security policy!

aptitude  search '?and(?or(~snon-free,~scontrib),~i)' -F '%8?C %2?s %10?p %10?v '

--------------------------------------------------------------------
aptitude install debian-archive-keyring

--------------------------------------------------------------------

(/tmp/sources.list is only the security archive)
# aptitude search -o Dir::Etc::sourcelist="/tmp/sources.list" -o Dir::Etc::sourceparts="foo"  ~U | wc -l
31
# aptitude search ~U | wc -l
66

$ grep '^Label:.*Security' $(apt-config shell zorky Dir::State::lists/d | sed -e "s/^.*='//;s/'$//")/*Release
/var/lib/apt/lists/<REPO>dists_wheezy_updates_Release:Label: Debian-Security

# grep --color=always -i security *_Release | less -R
<REPO>_Release:Label: Debian-Security
<REPO>_Release:Description: Debian 7.0 Security Updates

# apt-cache policy libssl1.0.0
libssl1.0.0:
  Installed: 1.0.1e-2
  Candidate: 1.0.1e-2+deb7u4
  Version table:
     1.0.1e-2+deb7u4 0
        500 http://<REPO>/ wheezy/main amd64 Packages
     1.0.1e-2+deb7u3 0
        500 http://<REPO>/debian-security/ wheezy/updates/main amd64 Packages
 *** 1.0.1e-2 0
        100 /var/lib/dpkg/status

END_NOTES
