#!/bin/bash set -e SUPPORTED=/var/lib/locales/supported.d LOCALES=/usr/share/i18n/locales STATEDIR=/var/lib/belocs [ -n "$POSIXLY_CORRECT" ] && unset POSIXLY_CORRECT || true IS_LANG=no ARCHIVE=yes PURGE=no ALIASES= # Handle command-line options prev= while true do option="$1" if [ -n "$prev" ]; then eval "$prev=\$option" prev= continue fi case $option in -h|--help) cat <> "$SUPPORTED/local" fi else # try to come up with a sensible default GENERATE=`grep -E "^${1}( |[._@][^[:space:]]* )UTF-8" /usr/share/i18n/SUPPORTED` if [ -z "$GENERATE" ]; then echo "Error: '$1' is not a supported language or locale" >&2 exit 1 fi NL=' ' IFS_SAVE="$IFS" IFS="$NL" for L in $GENERATE; do IFS="$IFS_SAVE" # add to supported.d/local if necessary if [ ! -f "$SUPPORTED/local" ] || ! grep -q "^$L" "$SUPPORTED/local"; then echo "$L" >> "$SUPPORTED/local" fi IFS="$NL" done IFS="$IFS_SAVE" fi shift done [ -d "$STATEDIR" ] || mkdir -p "$STATEDIR" || PURGE=yes no_archive= [ "$ARCHIVE" = yes ] || no_archive="--no-archive" locale_alias= [ -n "$ALIASES" ] && [ -r "$ALIASES" ] && locale_alias="-A $ALIASES" umask 022 is_entry_ok() { if [ -n "$locale" ] && [ -n "$charset" ] then true else echo "Error: Bad entry '$locale $charset'" 1>&2 false fi } normalize_locale() { # Insert a leading x in case $1 begins with a dash this_locale=x$1 charset= if echo $this_locale | LC_ALL=C grep '\.' > /dev/null 2>&1; then charset=$(echo $this_locale | sed -e 's/^x//' -e 's/.*\(\.[^@]*\).*/\1/' | LC_ALL=C tr '[A-Z]' '[a-z]' | LC_ALL=C sed -e 's/[^a-z0-9.]//g') fi modifier= if echo $this_locale | LC_ALL=C grep '@' > /dev/null 2>&1; then modifier=$(echo $this_locale | sed -e 's/^x//' -e 's/.*\(@[^.]*\).*/\1/') fi main=$(echo $this_locale | sed -e 's/^x//' -e 's/[.@].*//') echo $main$charset$modifier } gen_dep() { [ -d "$STATEDIR" ] || return 1 # Generate the dependency list. It is needed by update_md5sum() ( LC_ALL=C grep '^\(include\|copy\)' "$LOCALES"/* |\ sed -e "s,^$LOCALES/,," -e 's/\(include\|copy\)[ ]*"/ /' -e 's/".*//' ) | LC_ALL=C sort -u > "$STATEDIR/locales.dep" 2>/dev/null } gen_md5sum() { [ -d "$STATEDIR" ] || return 1 # If old md5sums are not present, regenerate all locales. [ -f "$STATEDIR/hashfile" ] || return 1 mv -f "$STATEDIR/hashfile" "$STATEDIR/hashfile.old" || return 1 md5sum "$LOCALES"/* > "$STATEDIR/hashfile.new" || return 1 locale -a > "$STATEDIR/list" 2>/dev/null || return 1 } # Check whether a locale was already generated and all its dependencies # have not been modified. already_generated() { [ -f "$STATEDIR/locales.dep" ] || return 1 [ -f "$STATEDIR/hashfile.old" ] || return 1 [ -f "$STATEDIR/hashfile.new" ] || return 1 [ -f "$STATEDIR/list" ] || return 1 this_locale=$(normalize_locale $1) this_input=$2 # Check whether the locale is already present. LC_ALL=C grep "^$this_locale\$" "$STATEDIR/list" > /dev/null 2>&1 || return 1 # If yes, check if this file and its dependencies have changed for file in "$this_input" $(LC_ALL=C grep "^$this_input:" "$STATEDIR/locales.dep" | awk '{printf "%s ", $2}') do md5old=$(LC_ALL=C grep "/$file\$" "$STATEDIR/hashfile.old" | sed -e 1q) md5new=$(LC_ALL=C grep "/$file\$" "$STATEDIR/hashfile.new" | sed -e 1q) [ -n "$md5old" ] || return 1 [ -n "$md5new" ] || return 1 [ "$md5new" = "$md5old" ] || return 1 done return 0 } update_md5sum() { [ -f "$STATEDIR/locales.dep" ] || return 0 this_locale=$1 for file in "$this_locale" $(LC_ALL=C grep "^$this_locale:" "$STATEDIR/locales.dep" | awk '{printf "%s ", $2}') do md5sum "$LOCALES/$file" >> "$STATEDIR/hashfile" || return 0 done } gen_dep 2>/dev/null || true [ "$PURGE" = yes ] || gen_md5sum 2>/dev/null || PURGE=yes if [ "$PURGE" = yes ]; then rm -f "$STATEDIR/hashfile.old" "$STATEDIR/hashfile.new" "$STATEDIR/list" 2>/dev/null || true for dir in /usr/lib/locale/*; do [ -e "$dir" ] || continue if [ "${dir#/usr/lib/locale/}" = C.UTF-8 ]; then # owned by libc-bin continue fi rm -rf "$dir" 2>/dev/null || true done fi echo "Generating locales..." /bin/echo -e "$GENERATE" | sort -u | while read locale charset do case $locale in \#*) continue;; "") continue;; esac is_entry_ok || continue # Remove charset if present input=$(echo $locale | sed -e 's/\.[^@]*//') # Insert charset before modifier printf "%s" $input | sed -e "s/^\\([^@]*\\)\\(.*\\)/ \\1.${charset}\\2... /" if already_generated $locale $input; then echo 'up-to-date' else if localedef $no_archive -i $input -c -f $charset $locale_alias $locale; then echo 'done' else echo 'failed' fi fi update_md5sum $input 2>/dev/null done echo "Generation complete."