#!/bin/sh -e # # 2012-2016 Steven Armstrong (steven-cdist at armstrong.cc) # 2016 Carlos Ortigoza (carlos.ortigoza at ungleich.ch) # 2016 Nico Schottelius (nico.schottelius at ungleich.ch) # 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) # # This file is part of cdist. # # cdist 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. # # cdist 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 cdist. If not, see . # # # Configure system-wide locale by modifying i18n file. # version_ge() { awk -F '[^0-9.]' -v target="${1:?}" ' function max(x, y) { return x > y ? x : y } BEGIN { getline nx = split($1, x, ".") ny = split(target, y, ".") for (i = 1; i <= max(nx, ny); ++i) { diff = int(x[i]) - int(y[i]) if (diff == 0) continue exit (diff < 0) } }' } key=$__object_id onchange_cmd= # none, by default quote_value=false catval() { # shellcheck disable=SC2059 printf "$($quote_value && echo '"%s"' || echo '%s')" "$(cat "$1")" } state_should=$(cat "${__object}/parameter/state") os=$(cat "$__global/explorer/os") case $os in debian) if version_ge 4 <"${__global}/explorer/os_version" then # Debian 4 (etch) and later locale_conf="/etc/default/locale" else locale_conf="/etc/environment" fi ;; devuan) locale_conf="/etc/default/locale" ;; ubuntu) if version_ge 6.10 <"${__global}/explorer/os_version" then # Ubuntu 6.10 (edgy) and later locale_conf="/etc/default/locale" else locale_conf="/etc/environment" fi ;; archlinux) locale_conf="/etc/locale.conf" ;; centos|redhat|scientific) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") if echo "${version_id}" | version_ge 7 then locale_conf="/etc/locale.conf" else locale_conf="/etc/sysconfig/i18n" fi ;; fedora) # shellcheck source=/dev/null version_id=$(. "${__global}/explorer/os_release" && echo "${VERSION_ID:-0}") if echo "${version_id}" | version_ge 18 then locale_conf="/etc/locale.conf" quote_value=false else locale_conf="/etc/sysconfig/i18n" fi ;; gentoo) case $(cat "${__global}/explorer/init") in (*openrc*) locale_conf="/etc/env.d/02locale" onchange_cmd="env-update --no-ldconfig" quote_value=true ;; (systemd) locale_conf="/etc/locale.conf" ;; esac ;; freebsd|netbsd) # NetBSD doesn't have a separate configuration file to set locales. # In FreeBSD locales could be configured via /etc/login.conf but parsing # that would be annoying, so the shell login file will have to do. # "Non-POSIX" shells like csh will not be updated here. locale_conf="/etc/profile" quote_value=true value="$(catval "${__object}/parameter/value"); export ${key}" ;; solaris) locale_conf="/etc/default/init" locale_conf_group="sys" if version_ge 5.11 <"${__global}/explorer/os_version" then # mode on Oracle Solaris 11 is actually 0444, # but the write bit makes sense, IMO locale_conf_mode=0644 # Oracle Solaris 11.2 and later uses SMF to store environment info. # This is a hack, but I didn't feel like modifying the whole type # just for some Oracle nonsense. # 11.3 apparently added nlsadm(1m), but it is missing from 11.2. # Illumos continues to use /etc/default/init # NOTE: Remember not to use "cool" POSIX features like -q or -e with # Solaris grep. release_regex='Oracle Solaris 11.[2-9][0-9]*' case $state_should in (present) svccfg_cmd="svccfg -s svc:/system/environment:init setprop environment/${key} = astring: '$(cat "${__object}/parameter/value")'" ;; (absent) svccfg_cmd="svccfg -s svc:/system/environment:init delprop environment/${key}" ;; esac refresh_cmd='svcadm refresh svc:/system/environment' onchange_cmd="grep '${release_regex}' /etc/release >&- || exit 0; ${svccfg_cmd:-:} && ${refresh_cmd}" else locale_conf_mode=0555 fi ;; slackware) # NOTE: lang.csh (csh config) is ignored here. locale_conf="/etc/profile.d/lang.sh" locale_conf_mode=0755 key="export ${__object_id}" ;; suse) if test -s "${__global}/explorer/os_release" then # shellcheck source=/dev/null os_version=$(. "${__global}/explorer/os_release" && echo "${VERSION}") else os_version=$(sed -n 's/^VERSION\ *=\ *//p' "${__global}/explorer/os_version") fi os_major=$(expr "${os_version}" : '\([0-9]\{1,\}\)') # https://documentation.suse.com/sles/15-SP2/html/SLES-all/cha-suse.html#sec-suse-l10n if expr "${os_major}" '>=' 15 \& "${os_major}" != 42 then # It seems that starting with SuSE 15 the systemd /etc/locale.conf # is the preferred way to set locales, although # /etc/sysconfig/language is still available. # Older documentation doesn't mention /etc/locale.conf, even though # is it created when localectl is used. locale_conf="/etc/locale.conf" else locale_conf="/etc/sysconfig/language" quote_value=true key="RC_${__object_id}" fi ;; voidlinux) locale_conf="/etc/locale.conf" ;; *) echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 echo "Please contribute an implementation for it if you can." >&2 exit 1 ;; esac __file "${locale_conf}" --state exists \ --owner "${locale_conf_owner:-0}" \ --group "${locale_conf_group:-0}" \ --mode "${locale_conf_mode:-0644}" require="__file/${locale_conf}" \ __key_value "${locale_conf}:${key#export }" \ --file "${locale_conf}" \ --key "${key}" \ --delimiter '=' --exact_delimiter \ --state "${state_should}" \ --value "${value:-$(catval "${__object}/parameter/value")}" \ --onchange "${onchange_cmd}"