#! /bin/sh set -e set -u PERL_PROGS="/usr/local/bin/tails-security-check \ /usr/local/lib/tails-htp-notify-user \ /usr/local/lib/tails-virt-notify-user" PYTHON_PROGS="/etc/whisperback/config.py \ /usr/local/bin/electrum \ /usr/local/bin/liferea \ /usr/local/bin/tails-about \ /usr/local/bin/tails-additional-software-config \ /usr/local/bin/tails-screen-locker \ /usr/local/bin/tails-upgrade-frontend-wrapper \ /usr/local/sbin/tails-additional-software \ /usr/local/lib/python3/dist-packages/unlock_veracrypt_volumes/volume.py \ /usr/local/lib/python3/dist-packages/unlock_veracrypt_volumes/volume_list.py \ /usr/local/lib/python3/dist-packages/unlock_veracrypt_volumes/volume_manager.py /usr/local/lib/tails-additional-software-notify \ /usr/local/sbin/tails-additional-software" SHELL_PROGS="/etc/NetworkManager/dispatcher.d/60-tor-ready.sh \ /usr/local/bin/keepassx \ /usr/local/lib/tails-spoof-mac \ /usr/local/bin/tor-browser \ /usr/local/sbin/unsafe-browser" JAVASCRIPT_PROGS=" \ /usr/share/gnome-shell/extensions/status-menu-helper@tails.boum.org/extension.js \ /usr/share/gnome-shell/extensions/torstatus@tails.boum.org/extension.js \ " GLADE_UI="\ /usr/share/tails/additional-software/configuration-window.ui \ " LOCALE_BASEDIR=config/chroot_local-includes/usr/share/locale ### External libraries . config/chroot_local-includes/usr/local/lib/tails-shell-library/common.sh . config/chroot_local-includes/usr/local/lib/tails-shell-library/po.sh ### Functions normalize_pot () { sed --regexp-extended \ -i 's@^"Content-Type: text/plain; charset=CHARSET\\n"@"Content-Type: text/plain; charset=UTF-8\\n"@' \ "${@}" } prog_potfile () { prog=$1 progpath="config/chroot_local-includes$prog" case $prog in /usr/share/gnome-shell/extensions/status-menu-helper@tails.boum.org/extension.js) domain=status-menu-helper-extension.js ;; /usr/share/gnome-shell/extensions/torstatus@tails.boum.org/extension.js) domain=torstatus-extension.js ;; /usr/local/lib/*/unlock_veracrypt_volumes/*) domain="unlock-veracrypt-volumes-$(basename "$prog")" ;; *) domain=$(basename $prog) ;; esac echo "tmp/pot/${domain}.pot" } create_pot () { prog=$1 proglang=$2 progpath="config/chroot_local-includes${prog}" if [ -e "${progpath}" ]; then pot="$(prog_potfile "${prog}")" mkdir -p "$(dirname ${pot})" xgettext --language="${proglang}" --from-code=UTF-8 \ --add-comments="Translators:" -o "${pot}" "${progpath}" normalize_pot "${pot}" else echo "error: We are supposed to create a POT file for '${prog}'" \ "but '${progpath}' does not exist" exit 1 fi } po_file () { locale=$1 echo "po/${locale}.po" } mo_file () { locale=$1 echo "${LOCALE_BASEDIR}/${locale}/LC_MESSAGES/tails.mo" } refresh_mo () { for locale in "$@" ; do po=$(po_file $locale) mo=$(mo_file $locale) mkdir -p $(dirname "$mo") msgfmt -o "${mo}" "${po}" done } no_left_out_files () { (cd po && intltool-update --maintain) [ ! -e po/missing ] || return 1 return 0 } intltool_update_pot () { ( cd po cp -a tails.pot tails.pot.orig intltool-update --pot --gettext-package=tails normalize_pot tails.pot tails.pot.orig if [ "${FORCE:-}" = yes ]; then echo "Force-updating 'tails.pot'." rm tails.pot.orig elif diff_without_pot_creation_date_and_comments -q tails.pot.orig tails.pot; then echo "Only header or comment changes in tails.pot: keeping the old one" mv tails.pot.orig tails.pot else echo "Real changes in tails.pot: switching to the updated one" rm tails.pot.orig fi ) } intltool_merge_desktop () { extract_from_file_between_markers po/POTFILES.in \ '^# Files updated by intltool-update --desktop-style' '^$' \ | while read infile ; do intltool-merge --quiet --desktop-style --utf8 \ po "$infile" "${infile%.in}" done } intltool_merge_xml () { extract_from_file_between_markers po/POTFILES.in \ '^# Files updated by intltool-update --xml-style' '^$' \ | while read infile ; do intltool-merge --quiet --xml-style --utf8 \ po "$infile" "${infile%.in}" done } ### Main FORCE=no KEEP_TMP_POT=no while [ -n "${@:-}" ]; do case "${1:-}" in '--force') FORCE=yes ;; '--keep-tmp-pot') KEEP_TMP_POT=yes ;; *) echo "Unknown option: ${1}" exit 1 ;; esac shift done # Schedule clean up trap "rm -fr po/*.new po/*.orig ; [ "$KEEP_TMP_POT" = yes ] || rm -fr tmp/pot" EXIT # Update POT files mkdir -p tmp/pot for prog in $PERL_PROGS ; do create_pot $prog Perl ; done for prog in $PYTHON_PROGS ; do create_pot $prog Python ; done for prog in $SHELL_PROGS ; do create_pot $prog Shell ; done for prog in $JAVASCRIPT_PROGS ; do create_pot $prog JavaScript ; done for prog in $GLADE_UI ; do create_pot $prog Glade ; done intltool_update_pot # If left out files are detected, intltool-update --maintain writes # them to po/missing. if ! no_left_out_files; then echo "E: These files should be listed in POTFILES.in or POTFILES.skip:" >&2 cat po/missing exit 3 fi # Update PO files intltool_update_po $(po_languages) # Update files that are actually used at runtime refresh_mo $(po_languages) intltool_merge_desktop intltool_merge_xml chmod +x config/chroot_local-includes/etc/skel/Desktop/*.desktop