#!/bin/bash # SPDX-Version: 3.0 # SPDX-CreationInfo: 2025-10-10; WEIDNER, Marc S.; # SPDX-ExternalRef: GIT https://git.coresecret.dev/msw/CISS.debian.live.builder.git # SPDX-FileContributor: WEIDNER, Marc S.; Centurion Intelligence Consulting Agency # SPDX-FileCopyrightText: 2024-2025; WEIDNER, Marc S.; # SPDX-FileType: SOURCE # SPDX-License-Identifier: LicenseRef-CNCL-1.1 OR LicenseRef-CCLA-1.1 # SPDX-LicenseComment: This file is part of the CISS.debian.installer.secure framework. # SPDX-PackageName: CISS.debian.live.builder # SPDX-Security-Contact: security@coresecret.eu set -Ceuo pipefail ####################################### # Minimal leap-second probe for Debian/chrony systems. # - Prints kernel leap flags & TAI offset (delta AT). # - Reads tzdata's leap-seconds list (authoritative TAI-UTC). # - Shows chrony tracking summary (incl. leap status). # - Demonstrates 23:59:60 rendering via TZ=right/UTC. # Globals: # None # Arguments: # None # Returns: # 0: on success ####################################### main() { ### 1) System TZ and tzdata source. printf "System TZ link: [%s]\n\n" "$(readlink -f /etc/localtime || true)" if [[ -f /usr/share/zoneinfo/leap-seconds.list ]]; then declare tz_leap_line tz_tai tz_ntp ts_human tz_leap_line="$(awk '($1 !~ /^#/) {L=$0} END{print L}' /usr/share/zoneinfo/leap-seconds.list)" tz_ntp="$(awk '{print $1}' <<<"${tz_leap_line}")" tz_tai="$(awk '{print $2}' <<<"${tz_leap_line}")" ts_human="$(awk -F'#' '{gsub(/^[[:space:]]+/, "", $2); print $2}' <<<"${tz_leap_line}")" printf "tzdata delta AT (TAI-UTC): %s s [last change at: %s; NTP ts: %s]\n\n" "${tz_tai:-?}" "${ts_human:-?}" "${tz_ntp:-?}" else printf "tzdata leap-seconds.list not found.\n" fi ### 2) Kernel view (requires adjtimex). if command -v adjtimex >/dev/null 2>&1; then printf "Kernel time status (adjtimex -p):\n" adjtimex -p | sed 's/^/ /' declare k_tai k_tai="$(adjtimex -p | awk '/^tai:/ {print $2}')" if [[ -n "${k_tai:-}" ]]; then printf "Kernel-exported delta AT [tai]: %s s\n" "${k_tai}" fi else printf "Package: 'adjtimex' not found. Install 'adjtimex' for kernel leap/TAI details.\n\n" fi ### 3) Chrony summary. if command -v chronyc >/dev/null 2>&1; then printf "\n" printf "chronyc tracking:\n" chronyc -n tracking | sed 's/^/ /' else printf "Package: 'chronyc' not found. Skipping chrony status.\n\n" fi ### 4) right/UTC demonstration of 23:59:60 (uses 2016-12-31 leap). if [[ -f /usr/share/zoneinfo/right/UTC ]]; then printf "\n" printf "right/UTC leap rendering check (expect 23:59:60):\n\n" TZ=right/UTC date -ud '2017-01-01 00:00:00 -1 second' || true else printf "\n" printf "File: 'tzdata right/UTC' zone not installed; skipping 23:59:60 demo.\n\n" fi printf "\n" printf "Hint:\n" printf " - delta AT (TAI-UTC) should match tzdata and kernel (chrony sets kernel TAI if leapsectz/leapseclist is used).\n" printf " - For monotonic intervals, apps must use CLOCK_MONOTONIC, not CLOCK_REALTIME.\n" return 0 } ### Build right/UTC from tzdata leap table if missing. if [[ ! -e /usr/share/zoneinfo/right/UTC ]]; then install -d -m 0755 /usr/share/zoneinfo/right ### Minimal zic source for a fixed UTC zone. declare -r tmp_src="/tmp/UTC.src" printf 'Zone UTC 0 - UTC\n' > "${tmp_src}" ### Prefer the zic-format leapseconds file. declare leap_zic="/usr/share/zoneinfo/leapseconds" if [[ -s "${leap_zic}" ]]; then zic -d /usr/share/zoneinfo/right -L "${leap_zic}" "${tmp_src}" else echo "WARNING: ${leap_zic} not found; building right/UTC without leap info." >&2 zic -d /usr/share/zoneinfo/right -L /dev/null "${tmp_src}" fi rm -f "${tmp_src}" fi if [[ -e /usr/share/zoneinfo/right/UTC ]]; then ### Expect to see 'Sat Dec 31 23:59:60 UTC 2016' rendered in right/UTC TZ=right/UTC date -ud '2017-01-01 00:00:00 -1 second' || true fi main "$@" exit 0 # vim: number et ts=2 sw=2 sts=2 ai tw=128 ft=sh