#!/bin/bash #This program is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation, either version 3 of the License, or #(at your option) any later version. #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. #You should have received a copy of the GNU General Public License #along with this program. If not, see . baseurl='https://www.debian.org' # "seclines" are the lines from https://www.debian.org/security (or # security.debian.org), which contains the "Recent Advisories"# the seclines # are in the form: [date] [DSA-number] [package name] "security update" # Check if wget of curl exists and is executable - then get the HTML document, # print it to stdout and save it in Variable "seclines". # Of course, wget and curl have to be silent/quiet. if [[ -x /usr/bin/wget ]]; then download_cmd () { /usr/bin/wget -qO- "$@"; } seclines="$(download_cmd $baseurl/security/)" [[ -z "$seclines" ]] && exit elif [[ -x /usr/bin/curl ]]; then download_cmd () { /usr/bin/curl -s "$@"; } seclines="$(download_cmd $baseurl/security/)" [[ -z "$seclines" ]] && exit else printf '%s\n' "Unable to find /usr/bin/wget or /usr/bin/curl. One of them is needed to download the document from $baseurl/security/" exit fi # a list of all packages currently installed with their version installeddebs="$(dpkg-query -W -f='${binary:Package} ${Version}\n')" # a list of all packages currently installed with their source package dpkgsrclist="$(dpkg-query -W -f='${source:Package} ${binary:Package}\n')" get_srcpackage () { cut -d' ' -f5 <<< "$line" } # generate the DSA-URLs by grabbing the DSA-XXXX from the security information # lines and ... urlline_tmp () { sed -n 's/.*\(DSA-[^ ]*\).*/\1/;s/DSA/dsa/p' <<< "$line" } # ... appending it to https://www.debian.org/security/ urllines_cmd () { urlline_raw="$baseurl/security/$(date '+%Y')/$(urlline_tmp)" urlline="$(printf '%b\n' "\033[01;34m $urlline_raw\033[00m")" } # check if binarie packages (= debnames) from the sourcepackage are installed check_source () { unset error if ! grep -q "^$srcpackage\ " <<< "$dpkgsrclist"; then error=y fi } # get a list of the installed debnames of the sourcepackage parse_source () { sed -n "/^$srcpackage\ / {s/[^ ]*\ //p}" } # get new version of the source package parse_urlline () { grep -o '[^ ]*deb9u[0-9]*' } # get the version for each debname extract_version () { sed -n "/^$debname\ / {s/[^ ]*\ //p}" <<< "$installeddebs" } # get the versions of the installed binary packages (debnames) of a source package checkupdate_cmd () { unset installedversions # the name of the source package, for example "firefox-esr" # the names of the deblist that are built from this source package, for # example "firefox-esr-dev" or "firefox-esr" check_source if [[ $error != y ]]; then deblist="$(parse_source <<< "$dpkgsrclist")" # the new version of the packages from this source package newversion_tmp=$(download_cmd "$urlline_raw" | parse_urlline) [[ -z $newversion_tmp ]] && stable=n newversion=${newversion_tmp/*:/} while read debname; do version_tmp=$(extract_version) installedversions+=(${version_tmp/*:/}) done <<< "$deblist" fi } search_cmd () { printf '%s\n' "${installedversions[@]}" | grep "$1" "$2" } sed_color () { sed_color_var=$(printf '%b\n' "\033[01;3$1m$srcpackage \033[00msecurity update \033[00;3$1m$2\033[00m") sed "s/$srcpackage security update/$sed_color_var/" <<< "$line" } colorise_cmd () { if [[ $stable == n ]]; then sed_color 2 "No update for stable distribution." elif [[ -z "${installedversions[@]}" ]]; then if [[ $error == y ]]; then sed_color 3 "No debs of this package installed." else sed "s/$/$(printf '%b\n' " \033[01;31mAn error occured.\033[00m")/" <<< "$line" fi elif search_cmd -q "bpo"; then if search_cmd -qv "bpo"; then installedversions=($(printf '%s\n' "${installedversions[@]}" | sed "s/.*bpo.*//;/^$/d")) if search_cmd -qx "$newversion"; then if search_cmd -qxv "$newversion"; then sed_color 1 "There are backports and partial upgraded packages." else sed_color 2 "There are backports and upgraded packages." fi else sed_color 1 "There are backports and not upgraded packages." fi else sed_color 2 "There are only backports of this package packages." fi elif search_cmd -qx "$newversion"; then if search_cmd -qxv "$newversion"; then sed_color 1 "(partial upgraded)" else sed "s/$srcpackage/$(printf '%b\n' "\033[01;32m$srcpackage\033[00m")/" <<< "$line" fi else sed "s/$srcpackage/$(printf '%b\n' "\033[01;31m$srcpackage\033[00m")/" <<< "$line" fi } old_update () { sed_color 1 "Update deprecated." } parse_seclines () { sed -n '/security\ update
$/ {s/<[^>]*>//gp}' <<< "$seclines" } output="$(parse_seclines | while read line; do srcpackage="$(get_srcpackage)" export srcpackage if ! grep -qx "$srcpackage" <<< "$(printf '%s\n' "${database[@]}")"; then urllines_cmd && checkupdate_cmd colorise_cmd && printf '%s\n\n' "$urlline" else urllines_cmd && old_update printf '%s\n\n' "$urlline" fi database+=($srcpackage) unset stable done)" # Check for pager less, than for pager more. If both are unavailable, print to stdout. if [[ -x /usr/bin/less ]]; then less -R <<< "$output" elif [[ -x /bin/more ]]; then more <<< "$output" else printf '%s\n' "$output" fi