Tiny Core Linux
General TC => Programming & Scripting - Unofficial => Topic started by: CNK on April 30, 2025, 04:00:41 AM
-
This script uses Firefox's update system to update any firefox.tcz extension created using firefox_getLatest.sh to the latest version in its release family. The main advantage is that the download sizes are much smaller (about 10MB unless updating a version many months old) than running firefox_getLatest.sh to download the complete new binary, similar to how tce-update uses Zsync to download just the changes to updated extension files. It also verifies the signature of the downloaded update file without you needing to set up GnuPG to work with "firefox_getLatest.sh -g".
If the firefox.tcz extension is already loaded (but Firefox isn't running) the script automatically adapts the symlinks to any changes and mounts the updated extension so that the new Firefox version is available immediately (the old extension is permanently replaced at next reboot). So you don't have to reboot to use the new version as with firefox_getLatest.sh.
Note that firefox.tcz.dep is not updated if the dependencies for Firefox change in a new version. This must then be edited manually.
Tested on TC15 x86 and x86_64. It should work in any recent version of Tiny Core.
#!/bin/ash
# Update existing Firefox extension downloaded with firefox_getLatest.sh.
# Uses partial.mar update files to minimise download size.
# V. 1.0, 2025-04-30. By CNK.
# Firefox update info:
# https://wiki.mozilla.org/Software_Update:Manually_Installing_a_MAR_file#Steps_for_Linux
# https://firefox-source-docs.mozilla.org/toolkit/mozapps/update/docs/InAppUpdateProcess.html
. /etc/init.d/tc-functions
useBusybox
if [ "$USER" = root ]
then
echo " ${YELLOW}This script can't be run by the 'root' user.${NORMAL}"
exit 1
fi
if [ ! -w /etc/sysconfig/tcedir/optional ]
then
echo " ${RED}Extension directory is missing or not writable.${NORMAL}"
exit 1
fi
if [ ! -w /etc/sysconfig/tcedir/optional/firefox.tcz ]
then
echo " ${YELLOW}Firefox extension missing or unwritable. Try firefox_getLatest.sh instead.${NORMAL}"
exit 1
fi
if [ -e /etc/sysconfig/tcedir/optional/upgrade/firefox.tcz ]
then
echo " ${YELLOW}An updated Firefox extension is already set to be installed at next reboot.${NORMAL}"
exit 1
fi
if killall -q -0 firefox
then
echo " ${YELLOW}Please close Firefox before running this script.${NORMAL}"
exit 1
fi
# Check there's enough disk space for upgrade mode or old extension backup
backup=1
tcz_partition="`readlink /etc/sysconfig/tcedir`"
tcz_partition="${tcz_partition#/mnt/}"
tcz_partition=${tcz_partition%%/*}
free=`expr "\`df -m /dev/$tcz_partition\`" : '.*/dev/[a-zA-Z0-9]* *[0-9]* *[0-9]* *\([0-9]*\)'`
required=`du -m /etc/sysconfig/tcedir/optional/firefox.tcz | cut -f 1`
# Allow for max. 10MB size increase
required=`expr $required + 10`
if [ "$free" ]
then
if [ $free -lt $required ]
then
if [ -e /usr/local/tce.installed/firefox ]
then
echo -e " ${RED}Not enough free disk space (${required}MB required).\n"\
"${YELLOW}Please run without the firefox.tcz extension loaded.${NORMAL}"
exit 1
fi
# Can't backup old extenion before upgrading
backup=0
fi
else
echo " ${YELLOW}Caution, unable to determine free disk space remaining.${NORMAL}"
fi
# Download/install script's dependencies
echo " ${BLUE}Loading dependencies${NORMAL}..."
deps="wget squashfs-tools gtk3"
for Z in $deps
do
Z="${Z#*$'\n'}"
if [ ! -e /etc/sysconfig/tcedir/optional/$Z ]
then
if ! tce-load -w $Z >/dev/null
then
echo " ${RED}Dependency $Z download failed${NORMAL}"
exit 1
fi
fi
done
if ! tce-load -i $deps >/dev/null
then
echo " ${RED}Dependency install failed${NORMAL}"
exit 1
fi
# Discover system architecture
if [ "`uname -m`" == x86_64 -a -f /lib/ld-linux-x86-64.so.* ]
then
ffarch=linux-x86_64
else
ffarch=linux-i686
fi
# Check system language
for lang in ${LANG%.*}
do
case $lang in
C) lang=en-US ;; #English
en_GB*) lang=en-GB ;;
en_ZA*) lang=en-ZA ;;
en*) lang=en-US ;;
es_ES*) lang=es-ES ;; #Spanish
es_MX*) lang=es-MX ;;
es_CL*) lang=es-CL ;;
es_AR*) lang=es-AR ;;
es*) lang=es-ES ;;
fr*) lang=fr ;; #French
de*) lang=de ;; #German
af*) lang=af ;; #Afrikaans
sq*) lang=sq ;; #Albanian
ar*) lang=ar ;; #Arabic
an*) lang=an ;; #Aragonese
hy_AM*) lang=hy-AM ;; #Armenian
ast*) lang=ast ;; #Asturian
as*) lang=as ;; #Assamese
az*) lang=az ;; #Azerbaijani
eu*) lang=eu ;; #Basque
be*) lang=be ;; #Belarusian
bn_BD*) lang=bn-BD ;; #Bengali (Bangladesh)
bn_IN*) lang=bn-IN ;; #Bengali (India)
bs*) lang=bs ;; #Bosnian
br*) lang=br ;; #Breton
bg*) lang=bg ;; #Bulgarian
ca*) lang=ca ;; #Catalan
zh_CN*) lang=zh-CN ;; #Chinese (Simplified)
zh*) lang=zh-TW ;; #Chinese (Traditional)
hr*) lang=hr ;; #Croatian
cs*) lang=cs ;; #Czech
da*) lang=da ;; #Danish
nl*) lang=nl ;; #Dutch
et*) lang=et ;; #Estonian
fi*) lang=fi ;; #Finnish
fy*) lang=fy-NL ;; #Frisian
ff*) lang=ff ;; #Fulah
gd*) lang=gd ;; #Gaelic (Scotland)
gl*) lang=gl ;; #Galician
el*) lang=el ;; #Greek
gu*) lang=gu-IN ;; #Gujarati (India)
he*) lang=he ;; #Hebrew
hi_IN*) lang=hi-IN ;; #Hindi (India)
hu*) lang=hu ;; #Hungarian
is*) lang=is ;; #Icelandic
id*) lang=id ;; #Indonesian
ga_IE*) lang=ga-IE ;; #Irish
it*) lang=it ;; #Italian
ja*) lang=ja ;; #Japanese
kn*) lang=kn ;; #Kannada
kk*) lang=kk ;; #Kazakh
km*) lang=km ;; #Khmer
ko*) lang=ko ;; #Korean
lv*) lang=lv ;; #Latvian
lt*) lang=lt ;; #Lithuanian
mk*) lang=mk ;; #Macedonian
ms*) lang=ms ;; #Malay
ml*) lang=ml ;; #Malayalam
mr*) lang=mr ;; #Marathi
nb_NO*) lang=nb-NO ;; #Norwegian (Bokmal)
nn_NO*) lang=nn-NO ;; #Norwegian (Nynorsk)
or*) lang=or ;; #Oriya
fa*) lang=fa ;; #Persian
pl*) lang=pl ;; #Polish
pt_BR*) lang=pt-BR ;; #Portuguese (Brazilian)
pt_PT*) lang=pt-PT ;; #Portuguese (Portugal)
ro*) lang=ro ;; #Romanian
ru*) lang=ru ;; #Russian
sr*) lang=sr ;; #Serbian
si*) lang=si ;; #Sinhala
sk*) lang=sk ;; #Slovak
sl*) lang=sl ;; #Slovenian
sv_SE*) lang=sv-SE ;; #Swedish
ta*) lang=ta ;; #Tamil
te*) lang=te ;; #Telugu
th*) lang=th ;; #Thai
tr*) lang=tr ;; #Turkish
uk*) lang=uk ;; #Ukrainian
hsb*) lang=hsb ;; #Upper Sorbian
uz*) lang=uz ;; #Uzbek
vi*) lang=vi ;; #Vietnamese
cy*) lang=cy ;; #Welsh
xh*) lang=xh ;; #Xhosa
*) lang=en-US ; echo " ${YELLOW}Language not recognised (check locale bootcode), using defualt${NORMAL}" ;;
esac
done
# Check the version of Firefox in the current extension
if [ -e /usr/local/tce.installed/firefox ]
then
ffcurrent_v="`firefox -v`"
else
# Unpack current extension to determine current version
rm -r /tmp/ffupdater 2>/dev/null
echo " ${BLUE}Unpacking old Firefox extension${NORMAL}..."
unsquashfs -q -d /tmp/ffupdater /etc/sysconfig/tcedir/optional/firefox.tcz || exit 1
if [ "$ffarch" == "linux-x86_64" ] && [ ! -e /lib64 ]
then
sudo ln -s /lib /lib64
fi
echo " ${BLUE}Loading Firefox dependencies${NORMAL}..."
if ! tce-load -i `cat /etc/sysconfig/tcedir/optional/firefox.tcz.dep` >/dev/null
then
echo " ${RED}Dependency install failed${NORMAL}"
rm -r /tmp/ffupdater
exit 1
fi
ffcurrent_v="`/tmp/ffupdater/usr/local/firefox/firefox -v`"
fi
ffcurrent_v="${ffcurrent_v##* }"
# Find release channel in use
altver="`echo -n \"$ffcurrent_v\" | tr -d \".[0-9]\"`"
product=firefox-latest
if [ "$altver" == "esr" ]
then
product=firefox-esr-latest
else
if [ "$altver" == "b" ]
then
product=firefox-beta-latest
altver="b[0-9]*"
fi
fi
# Find the latest version
addressX='http://download.mozilla.org/?os=linux&product='
MOZURL="$(/usr/local/bin/wget -q --max-redirect 0 -S --spider "$addressX$product" 2>&1 | grep 'Location:')"
ffnew_v=$(expr "$MOZURL" : ".*releases/\([0-9]*\.[0-9.]*$altver\)/") #"
if [ -z "$ffnew_v" ]
then
echo " ${RED}Failed to determine latest version (check network connection).${NORMAL}"
rm -r /tmp/ffupdater 2>/dev/null
exit 1
fi
echo " ${GREEN}Latest version ${WHITE}is ${CYAN}$ffnew_v${NORMAL}"
if [ "$ffcurrent_v" == "$ffnew_v" ]
then
echo " ${YELLOW}$product ${CYAN}$ffnew_v${YELLOW} is already the currently installed version.${NORMAL}"
echo " ${GREEN}No update required.${NORMAL}"
rm -r /tmp/ffupdater 2>/dev/null
exit
fi
echo " ${BLUE}Updating $product from ${CYAN}$ffcurrent_v ${BLUE}to ${CYAN}$ffnew_v${NORMAL}..."
# Need to unpack the extension now if this was skipped before
if [ -e /usr/local/tce.installed/firefox ]
then
rm -r /tmp/ffupdater 2>/dev/null
echo " ${BLUE}Unpacking old Firefox extension${NORMAL}..."
unsquashfs -q -d /tmp/ffupdater /etc/sysconfig/tcedir/optional/firefox.tcz || exit 1
fi
# Update extension files
mkdir -p /tmp/ffupdates
cd /tmp/ffupdates
# Check that last update download wasn't for another Firefox build
if [ -L update.mar ]
then
mar="`readlink update.mar`"
if [ "$mar" != "firefox-${ffcurrent_v}-${ffnew_v}-$lang.partial.mar" ] && [ "$mar" != "firefox-${ffnew_v}-$lang.complete.mar" ]
then
rm firefox-*.mar
fi
fi
# Download update
if ! /usr/local/bin/wget -c -O "firefox-${ffcurrent_v}-${ffnew_v}-$lang.partial.mar" \
"http://download.cdn.mozilla.net/pub/firefox/releases/$ffnew_v/update/$ffarch/$lang/firefox-${ffcurrent_v}-${ffnew_v}.partial.mar"
then
if ! /usr/local/bin/wget -c -O "firefox-${ffnew_v}-$lang.complete.mar" \
"http://download.cdn.mozilla.net/pub/firefox/releases/$ffnew_v/update/$ffarch/$lang/firefox-${ffnew_v}.complete.mar"
then
echo " ${RED}Couldn't download update file."
echo " ${YELLOW}Try firefox_getLatest.sh instead.${NORMAL}"
cd /tmp
rm -r ffupdater
exit 1
fi
fi
# Symlink to downloaded file
[ -e update.mar ] || ln -s firefox-*"${ffnew_v}-$lang".*.mar update.mar
# Save pre-update file list:
find /tmp/ffupdater > /tmp/ffpre-update.list
cd /tmp/ffupdater/usr/local/firefox
echo " ${BLUE}Applying update${NORMAL}..."
LD_LIBRARY_PATH=/tmp/ffupdater/usr/local/firefox ./updater /tmp/ffupdates /tmp/ffupdater/usr/local/firefox /tmp/ffupdater/usr/local/firefox
if [ "`cat /tmp/ffupdates/update.status`" != "succeeded" ]
then
echo " ${RED}Firefox updater failed${NORMAL}"
echo "${RED}Updater log:${NORMAL}"
cat /tmp/ffupdates/update.log
cd /tmp
rm -r ffupdater ffpre-update.list
exit 1
fi
rm -r /tmp/ffupdates
# Check if extension is installed
if [ -e /usr/local/tce.installed/firefox ]
then
installdir=/etc/sysconfig/tcedir/optional/upgrade
mkdir -p $installdir || exit 1
reloadExt=1
else
installdir=/etc/sysconfig/tcedir/optional
reloadExt=0
fi
# Rebuild extension
echo " ${BLUE}Rebuilding Firefox extension${NORMAL}..."
cd $installdir
if [ -f "firefox.tcz" ]
then
# Backup old extension in case mksquashfs fails, if there's enough disk space
[ $backup -gt 0 ] && mv firefox.tcz firefox.tcz.old || rm -f firefox.tcz
fi
if ! mksquashfs /tmp/ffupdater/ firefox.tcz -all-root -quiet
then
" ${RED}Rebuilding extension failed${NORMAL}"
rm -rf firefox.tcz /tmp/ffupdater /tmp/ffpre-update.list
[ $backup -gt 0 ] && mv firefox.tcz.old firefox.tcz
exit 1
fi
md5sum firefox.tcz > firefox.tcz.md5.txt
[ $reloadExt -gt 0 ] && cp ../firefox.tcz.dep ./
echo " ${GREEN}Firefox extension updated.${NORMAL}"
# Remount extension
if [ $reloadExt -gt 0 ]
then
# Save post-update file list:
find /tmp/ffupdater > /tmp/ffpost-update.list
# Rebuild symlinks to any changed/added filenames
if ! busybox diff -U 0 /tmp/ffpre-update.list /tmp/ffpost-update.list > /tmp/ffdiff.list
then
grep '/tmp/ffupdater' /tmp/ffdiff.list | while read FILE
do
MODE="${FILE%%/*}"
FILE="${FILE#?/tmp/ffupdater}"
if [ "$MODE" == "+" ]
then
if [ -d "/tmp/ffupdater$FILE" ]
then
# Make new directory
sudo mkdir "$FILE"
else
# Make new symlink
sudo ln -s "/tmp/tcloop/firefox$FILE" "$FILE"
fi
else
# Remove old directory/symlink
sudo rm -rf "$FILE"
fi
done
fi
echo " ${BLUE}Mounting updated extension...${NORMAL}"
sudo umount /tmp/tcloop/firefox
if sudo mount $installdir/firefox.tcz /tmp/tcloop/firefox
then
echo " ${GREEN}Firefox $ffnew_v is now ready to use.${NORMAL}"
fi
fi
rm -rf firefox.tcz.old /tmp/ffupdater /tmp/ffpre-update.list /tmp/ffpost-update.list /tmp/ffdiff.list