Files
Das-OS/srcpkgs/das-helpers/files/dsys
T
dasandClaude Opus 5.5 acb7532a4f Stage 7: command-line helpers dsv, duser, dfw, dsys (0.5.0)
- das-helpers replaces the dsv package and adds shared functions in
  /usr/lib/das/helpers.sh (bilingual messages, sudo re-exec, prompts).
- dsv new creates a runit service (command, user, directory, environment,
  svlogd log) and checks it stays up; dsv rm deletes one not from a package.
- duser: list, add (installer groups, --admin, key, password), del, passwd,
  lock/unlock (key logins too), key add|list|rm, groups +/-.
- dfw: allow/deny/status/reload for the tcp_ports and udp_ports sets of the
  inet das table, kept in /etc/nftables.d/dfw.nft and checked with nft -c.
- dsys: info, hostname, timezone, locale, keymap.
- xtools-minimal on both images.
- nftables.conf no longer suggests restarting the nftables service: its
  finish script flushes the whole ruleset, fail2ban's and Docker's included.
- das-server-install 0.2.0 mentions the helpers when it finishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 06:58:25 +03:00

248 lines
8.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# dsys - system settings on Das OS: host name, time zone, language and
# console keyboard, in place of hostnamectl, timedatectl and localectl.
set -euo pipefail
# shellcheck source=helpers.sh
. "${DAS_HELPERS:-/usr/lib/das/helpers.sh}"
zoneinfo=/usr/share/zoneinfo
libc_locales=/etc/default/libc-locales
keymaps=/usr/share/kbd/keymaps
usage() {
if [[ -n $uk ]]; then
cat <<'EOF'
Використання: dsys [КОМАНДА] [ЗНАЧЕННЯ]
info огляд системи (типова команда)
hostname [ІМ'Я] показати або змінити ім'я хоста
timezone [ЗОНА] показати або змінити часовий пояс (Europe/Kyiv,
достатньо й частини назви: Kyiv)
timezone list [ФІЛЬТР] усі часові пояси
locale [МОВА] показати або змінити мову системи (uk_UA, en_US)
locale list [ФІЛЬТР] доступні мови; * — уже зібрані
keymap [РОЗКЛАДКА] показати або змінити розкладку консолі (us, ua-utf)
keymap list [ФІЛЬТР] доступні розкладки консолі
Мову й розкладку графічного сеансу кожен користувач задає в налаштуваннях
Xfce і в das-welcome; dsys змінює типові для системи й консолі.
EOF
else
cat <<'EOF'
Usage: dsys [COMMAND] [VALUE]
info system overview (the default)
hostname [NAME] show or change the host name
timezone [ZONE] show or change the time zone (Europe/Kyiv,
part of the name will do: Kyiv)
timezone list [FILTER] all time zones
locale [LANGUAGE] show or change the system language (uk_UA, en_US)
locale list [FILTER] available languages; * marks the built ones
keymap [MAP] show or change the console keyboard map (us, ua-utf)
keymap list [FILTER] available console keyboard maps
In the graphical session every user picks the language and keyboard in the
Xfce settings and in das-welcome; dsys changes the system and console defaults.
EOF
fi
}
current_hostname() {
cat /etc/hostname 2>/dev/null || hostname
}
current_timezone() {
local tz
tz=$(readlink /etc/localtime 2>/dev/null || true)
echo "${tz#*zoneinfo/}"
}
current_locale() {
sed -n 's/^LANG=//p' /etc/locale.conf 2>/dev/null | tr -d '"'
}
rc_value() {
sed -n "s/^$1=//p" /etc/rc.conf 2>/dev/null | tr -d '"' | tail -n 1
}
# A graphical session keeps its X authority under the old host name
session_warning() {
if pgrep -x lightdm >/dev/null || [[ -n ${DISPLAY:-} ]]; then
say "Перезавантажте комп'ютер: графічний сеанс не відкриватиме нових вікон зі старим іменем." \
"Reboot: the graphical session will not open new windows under the old name."
fi
}
# 3 д 4 год 5 хв / 3 d 4 h 5 min
uptime_text() {
local s d h m
read -r s _ </proc/uptime
s=${s%.*}
d=$((s / 86400))
h=$((s % 86400 / 3600))
m=$((s % 3600 / 60))
if ((d > 0)); then
say "$d д $h год $m хв" "$d d $h h $m min"
elif ((h > 0)); then
say "$h год $m хв" "$h h $m min"
else
say "$m хв" "$m min"
fi
}
cmd_info() {
local ntp line
pad "$(say "Ім'я хоста:" "Host name:")" 16; current_hostname
pad "$(say "Система:" "System:")" 16; echo "$(uname -sr), $(uname -m)"
pad "$(say "Працює:" "Up:")" 16; uptime_text
pad "$(say "Час:" "Time:")" 16; date '+%Y-%m-%d %H:%M:%S %Z'
pad "$(say "Часовий пояс:" "Time zone:")" 16; current_timezone
if ntp=$(chronyc -n tracking 2>/dev/null); then
if grep -q '^Leap status *: Normal' <<<"$ntp"; then
ntp=$(say "синхронізовано (chrony)" "synchronized (chrony)")
else
ntp=$(say "не синхронізовано (chrony)" "not synchronized (chrony)")
fi
else
ntp=$(say "не працює (dsv enable chronyd)" "not running (dsv enable chronyd)")
fi
pad "$(say "Синхронізація:" "Time sync:")" 16; echo "$ntp"
pad "$(say "Мова:" "Language:")" 16; current_locale
pad "$(say "Консоль:" "Console:")" 16
echo "$(say розкладка keymap) $(rc_value KEYMAP || true), $(say шрифт font) $(rc_value FONT || true)"
say "Мережа:" "Network:"
ip -brief address 2>/dev/null | while read -r line; do
[[ $line == lo\ * ]] || echo " $line"
done
}
cmd_hostname() {
local new=${1:-} old
if [[ -z $new ]]; then
current_hostname
return
fi
[[ $new =~ ^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$ ]] ||
die "'$new': малі латинські літери, цифри й дефіс (не на початку й не в кінці)" \
"'$new': lowercase Latin letters, digits and hyphens (not first or last)"
need_root hostname "$new"
old=$(current_hostname)
echo "$new" >/etc/hostname
# The installers add "127.0.1.1 <name>"; keep the line in step
if grep -qw -- "$old" /etc/hosts; then
sed -i "/^[^#]/s/\([[:space:]]\)${old//./\\.}\([[:space:]]\|$\)/\1$new\2/g" /etc/hosts
fi
grep -qw -- "$new" /etc/hosts || printf '127.0.1.1\t%s\n' "$new" >>/etc/hosts
hostname "$new"
say "Ім'я хоста: $new" "Host name: $new"
session_warning
}
# All time zones, from tzdata's table plus UTC
timezones() {
{ awk '!/^#/ { print $3 }' "$zoneinfo/zone1970.tab"; echo UTC; } | sort -u
}
cmd_timezone() {
local zone=${1:-} matches line
if [[ -z $zone ]]; then
current_timezone
return
fi
if [[ $zone == list ]]; then
timezones | grep -i -- "${2:-}" || true
return
fi
if ! timezones | grep -qx -- "$zone"; then
# Kyiv -> Europe/Kyiv, when only one zone matches
matches=$(timezones | grep -i -- "$zone" || true)
if [[ $(grep -c . <<<"$matches") -eq 1 ]]; then
zone=$matches
elif [[ -n $matches ]]; then
say "Кілька часових поясів підходять, уточніть:" "Several time zones match, be more specific:" >&2
head -n 20 <<<"$matches" | while read -r line; do echo " $line"; done >&2
(($(grep -c . <<<"$matches") <= 20)) || echo " ..." >&2
exit 1
else
die "невідомий часовий пояс '$zone' (dsys timezone list)" "unknown time zone '$zone' (dsys timezone list)"
fi
fi
need_root timezone "$zone"
ln -sfn "$zoneinfo/$zone" /etc/localtime
say "Часовий пояс: $zone, зараз $(date '+%H:%M %Z')" "Time zone: $zone, now $(date '+%H:%M %Z')"
}
# Every UTF-8 locale glibc can build, with * for the enabled ones
locales() {
sed -n 's/^\(#\?\)\([^ ]*\.UTF-8\) UTF-8[[:space:]]*$/\2 \1/p' "$libc_locales" |
awk '{ print ($2 == "#" ? " " : "* ") $1 }'
}
cmd_locale() {
local lang=${1:-} re
if [[ -z $lang ]]; then
current_locale
return
fi
if [[ $lang == list ]]; then
locales | grep -i -- "${2:-}" || true
return
fi
[[ $lang == *.* ]] || lang+=.UTF-8
re=${lang//./\\.}
locales | grep -q "^. $re\$" ||
die "невідома мова '$lang' (dsys locale list)" "unknown language '$lang' (dsys locale list)"
need_root locale "$lang"
if grep -q "^#$re " "$libc_locales"; then
sed -i "s/^#\($re \)/\1/" "$libc_locales"
say "Збираю $lang..." "Building $lang..."
xbps-reconfigure -f glibc-locales >/dev/null
fi
# Keep the other settings, Void's default file also has LC_COLLATE=C
if grep -q '^LANG=' /etc/locale.conf 2>/dev/null; then
sed -i "s/^LANG=.*/LANG=$lang/" /etc/locale.conf
else
echo "LANG=$lang" >>/etc/locale.conf
fi
say "Мова системи: $lang (діє з наступного входу)" "System language: $lang (from the next login)"
}
cmd_keymap() {
local map=${1:-}
if [[ -z $map ]]; then
rc_value KEYMAP
return
fi
if [[ $map == list ]]; then
find "$keymaps" -name '*.map.gz' -printf '%f\n' | sed 's/\.map\.gz$//' | sort -u | grep -i -- "${2:-}" || true
return
fi
[[ -n $(find "$keymaps" -name "$map.map.gz" -print -quit) ]] ||
die "невідома розкладка '$map' (dsys keymap list)" "unknown keyboard map '$map' (dsys keymap list)"
need_root keymap "$map"
set_rc KEYMAP "$map"
# The default console font has no Cyrillic letters
if [[ $map == @(ua|ru|by|bg|mk|sr)* && -z $(rc_value FONT) ]]; then
set_rc FONT cyr-sun16
fi
loadkeys "$map" >/dev/null 2>&1 || true
say "Розкладка консолі: $map" "Console keyboard map: $map"
}
cmd=${1:-info}
[[ $# -gt 0 ]] && shift
case $cmd in
info | status) cmd_info ;;
hostname | host) cmd_hostname "$@" ;;
timezone | tz) cmd_timezone "$@" ;;
locale | lang) cmd_locale "$@" ;;
keymap | keyboard) cmd_keymap "$@" ;;
-h | --help | help) usage ;;
*)
usage >&2
exit 1
;;
esac