#!/bin/bash
-# Copyright (C) 2014 Ian Kelling
+# I, Ian Kelling, follow the GNU license recommendations at
+# https://www.gnu.org/licenses/license-recommendations.en.html. They
+# recommend that small programs, < 300 lines, be licensed under the
+# Apache License 2.0. This file contains or is part of one or more small
+# programs. If a small program grows beyond 300 lines, I plan to switch
+# its license to GPL.
+
+# Copyright 2024 Ian Kelling
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# See the License for the specific language governing permissions and
# limitations under the License.
-distro_name() {
- if [[ -f /etc/fedora-release ]]; then
- echo fedora
+distro-name() {
+ local x
+ if [[ -f /etc/fedora-release ]]; then
+ echo fedora
+ elif [[ -e /etc/os-release ]]; then
+ sed -rn 's/^ID=(.*)/\1/p' /etc/os-release
+ elif type -p lsb_release &>/dev/null; then
+ # well, this is more standard, but it's 2 ms vs 200 ms
+ x=$(lsb_release -si); echo ${x,,}
+ else
+ echo "unknown distro"
+ return 1
+ fi
+}
+
+distro-name-compat() {
+ local x
+ x=$(distro-name)
+ case $x in
+ trisquel)
+ echo ubuntu
+ ;;
+ *)
+ printf "%s\n" "$x"
+ ;;
+ esac
+}
+
+distro-name-ver() {
+ printf "%s\n" "$(distro-name)$(debian-archive)"
+}
+
+distro-num() {
+ # Subshell keeps environment clean.
+ ( . /etc/os-release
+ # in ubuntu the .x matters, trisquel it doesnt
+ if [[ $ID == ubuntu ]]; then
+ echo $VERSION_ID
else
- grep "^ID=.*" /etc/os-release | sed 's/^ID=//'
+ echo ${VERSION_ID%%.*}
+ fi
+ )
+}
+
+debian-archive() {
+ isdeb || return 0
+ local archive expression pri name highpri shortest
+ local policy="${1:-$(apt-cache policy)}" || return $?
+ # a = archive
+ # n = codename
+ # o = origin
+ # c = component (licensing component)
+ # l = label (Debian{,-Security,-Updates})
+ local d
+ d=$(distro-name)
+ # goto b for archive lines we are interested in, a for lines we arent
+ # print priority + archive name. priority is in
+ # the previous line from the archive line.
+ # case insensitive, because $d is lower and we are matching with first char upper
+ read -rd '' expression <<EOF ||:
+/o=$d/I!b a;/l=$d/I!b a;/c=main/!b a b b;
+: a;s/^ *([-0-9]+).*/\1/;h;b;
+: b;s/^.*a=([^,]+).*/ \1/;H;x;s/\n//;p
+EOF
+ while read -r pri name; do
+ # in ubuntu, we get archives like flidas, flidas-updates, all the same pri,
+ # so just pick the shortest one.
+ if [[ ! $highpri ]]; then
+ highpri=$pri;
+ shortest=$name
+ continue
+ fi
+ if [[ $pri != "$highpri" ]]; then
+ break
+ fi
+ if (( ${#shortest} > ${#name} )); then
+ shortest=$name
fi
+ done < <(echo "$policy" | sed -rn "$expression" | sort -rn || [[ $? == 141 ]])
+ echo "$shortest"
}
+
+# formatted for use in pfile() in package-manager-abstractions
+positive-origins() {
+ isdeb || return 0
+ local archive expression pri name highpri shortest policy
+ # In theory we might want a policy subset, we could alter this to pass
+ # it in.
+ policy="(apt-cache policy)"
+ # a = archive
+ # n = codename
+ # o = origin
+ # c = component (licensing component)
+ # l = label (Debian{,-Security,-Updates})
+ read -rd '' expression <<EOF ||:
+/^ *([-0-9]+).*/{s/^ *([-0-9]+).*/\1/;h}
+/^.*o=([^,]+).*/{s/^.*o=([^,]+).*/ \1/;H;x;s/\n//;p}
+EOF
+ origins=
+ while read -r pri name; do
+ if (( pri > 0 )); then
+ if [[ ! $origins ]]; then
+ origins=$name
+ else
+ origins+=,$name
+ fi
+ fi
+ done < <(echo "$policy" | sed -rn "$expression" | sort -rn || [[ $? == 141 ]])
+ echo $origins
+}
+
+isdebian-testing() {
+ [[ $(debian-archive) == testing ]]
+}
+# I only do testing or stable.
+isdebian-stable() {
+ [[ $(debian-archive) == stable ]]
+}
+
+debian-codename() {
+ isdeb || return 0
+ local policy
+ policy="$(apt-cache policy)"
+ archive=$(debian-archive "$policy")
+ printf "%s\n" "$policy" | sed -rn "s/^.*a=$archive,n=([a-z]+).*/\1/p;T;q" || [[ $? == 141 ]]
+}
+debian-codename-compat() {
+ local n
+ n=$(debian-codename)
+ case $n in
+ flidas)
+ echo xenial
+ ;;
+ etiona)
+ echo bionic
+ ;;
+ nabia)
+ echo focal
+ ;;
+ aramo)
+ echo jammy
+ ;;
+ *)
+ echo $n
+ ;;
+ esac
+}
+
isfedora() {
- local d=$(distro_name)
- [[ $d == fedora ]] || return 1
+ [[ $(distro-name) == fedora ]]
}
isdebian() {
- local d=$(distro_name)
- [[ $d == debian ]] || return 1
+ [[ $(distro-name) == debian ]]
}
-isdeb() {
- local d=$(distro_name)
- [[ $d == debian || $d == ubuntu ]] || return 1
+isarch() {
+ [[ $(distro-name) == arch ]]
}
isubuntu() {
- local d=$(distro_name)
- [[ $d == ubuntu ]] || return 1
+ [[ $(distro-name) == ubuntu ]]
+}
+istrisquel() {
+ [[ $(distro-name) == trisquel ]]
}
+# is debian/apt based
+isdeb() { command -v apt-get &>/dev/null; }