#!/bin/ash
# Update existing Firefox extension downloaded with firefox_getLatest.sh.
# Uses partial.mar update files to minimise download size.
version=1.1
# 2025-06-28. 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

case "$1" in *-h*) [ -t 1 ] && echo "Firefox Updater v$version for Tiny Core Linux
Usage:
  Update firefox.tcz to latest version in the current release channel:
    firefox_update.sh
  Update firefox.tcz to manually-specified version 128.11.0esr:
    firefox_update.sh -m 128.11.0esr
   (new version must be from the same release channel, eg. esr)
  Read this again:
    firefox_update.sh -h"
  exit
  ;;
esac

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
arch="`uname -m`"
if [ "${arch%64}" != "$arch" ]
then
  if [ -f /lib/ld-linux-x86-64.so.* ]
  then
    ffarch=linux-x86_64
  elif [ -f /lib/ld-linux-aarch64.so.* ]
  then
    ffarch=linux-aarch64
  else
    echo "${RED}Unsupported system architchture${NORMAL}"
    exit 1
  fi
elif [  "${arch#arm}" == "$arch" ]
then
  ffarch=linux-i686
else
  echo "${RED}32-bit ARM not supported.${NORMAL}"
  exit 1
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%64}" != "$ffarch" ] && [ ! -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

# Read manually-entered version number
if [ "$1" == "-m" ]
then
  if [ "$2" ]
  then
    ffnew_v="$2"
  elif [ -t 1 ]
  then
    echo -n -e " ${YELLOW}Please enter version to upgrade Firefox to (eg. 128.11.1esr):${NORMAL}\n  "
    read ffnew_v
  fi
  if [ -z "$ffnew_v" ]
  then
    echo " ${RED}No version number specified.${NORMAL}"
    exit 1
  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 '^[[:blank:]]*Location: ')"
MOZURL="${MOZURL#*Location: }"
if [ -z "$ffnew_v" ]
then 
  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}"
fi

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
site="http://download.cdn.mozilla.net/pub"
tries=0
while [ $tries -lt 2 ]
do
  if /usr/local/bin/wget -c -O "firefox-${ffcurrent_v}-${ffnew_v}-$lang.partial.mar" \
     "$site/firefox/releases/$ffnew_v/update/$ffarch/$lang/firefox-${ffcurrent_v}-${ffnew_v}.partial.mar"
  then
    break
  else
   if /usr/local/bin/wget -c -O "firefox-${ffnew_v}-$lang.complete.mar" \
      "$site/firefox/releases/$ffnew_v/update/$ffarch/$lang/firefox-${ffnew_v}.complete.mar"
    then
      break
    fi
  fi
  # Try again using auto-detected download server
  site="${MOZURL%%/firefox/releases/*}"
  tries=$(( tries + 1 ))
done

if [ $tries -gt 1 ]
then
  echo " ${RED}Couldn't download update file."
  echo " ${YELLOW}Try firefox_getLatest.sh instead.${NORMAL}"
  cd /tmp
  rm -r ffupdater
  exit 1
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 0 /tmp/ffupdates /tmp/ffupdater/usr/local/firefox /tmp/ffupdater/usr/local/firefox first
if [ "`cat /tmp/ffupdates/update.status`" != "succeeded" ]
then
  echo " ${RED}Firefox updater failed${NORMAL}"
  # Pause only if output is to a terminal session
  if [ -t 1 ]
  then
    echo "${RED}Press Enter to view updater log...${NORMAL}"
    read
  else
    echo "${RED}Updater log:${NORMAL}"
  fi
  cat /tmp/ffupdates/update.log
  cd /tmp
  rm -r ffupdater ffpre-update.list
  exit 1
fi
rm -r /tmp/ffupdates

# Update Firefox icon
cp /tmp/ffupdater/usr/local/firefox/browser/chrome/icons/default/default48.png /tmp/ffupdater/usr/local/share/pixmaps/firefox.png

# 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
