Vendors Arkenfox updater/prefsCleaner scripts

Also see related : arkenfox/user.js#910

> closes #1, #10, #29, #35 and #41
This commit is contained in:
Samuel FORESTIER 2024-08-31 16:03:00 +02:00 committed by Samuel FORESTIER
parent b814b88b93
commit 6183dda54a
4 changed files with 1052 additions and 0 deletions

134
prefsCleaner.bat Normal file
View File

@ -0,0 +1,134 @@
@ECHO OFF & SETLOCAL DisableDelayedExpansion
TITLE prefs.js cleaner
REM ## prefs.js cleaner for Windows
REM ## /!\ This script is a vendored/adapted version of Arkenfox own prefsCleaner.bat /!\
REM ## author: @claustromaniac
REM ## version: 2.7
CD /D "%~dp0"
IF /I "%~1"=="-unattended" (SET _ua=1)
:begin
ECHO:
ECHO:
ECHO ########################################
ECHO #### prefs.js cleaner for Windows ####
ECHO #### by claustromaniac ####
ECHO #### v2.7 ####
ECHO ########################################
ECHO:
CALL :message "This script should be run from your Thunderbird profile directory."
ECHO It will remove any entries from prefs.js that also exist in user.js.
CALL :message "This will allow inactive preferences to be reset to their default values."
ECHO This Thunderbird profile shouldn't be in use during the process.
CALL :message ""
TIMEOUT 1 /nobreak >nul
IF NOT DEFINED _ua (
CHOICE /C SHE /N /M "Start [S] Help [H] Exit [E]"
CLS
IF ERRORLEVEL 3 (EXIT /B)
IF ERRORLEVEL 2 (GOTO :showhelp)
)
IF NOT EXIST "user.js" (CALL :abort "user.js not found in the current directory." 30)
IF NOT EXIST "prefs.js" (CALL :abort "prefs.js not found in the current directory." 30)
CALL :strlenCheck
CALL :FFcheck
CALL :message "Backing up prefs.js..."
FOR /F "delims=" %%# IN ('powershell get-date -format "{yyyyMMdd_HHmmss}"') DO @SET ldt=%%#
COPY /B /V /Y prefs.js "prefs-backup-%ldt%.js"
CALL :message "Cleaning prefs.js..."
CALL :cleanup
CALL :message "All done!"
TIMEOUT 5 >nul
ENDLOCAL
EXIT /B
REM ########## Abort Function ###########
:abort
CALL :message %1
TIMEOUT %~2 >nul
EXIT
REM ########## Message Function #########
:message
ECHO:
ECHO: %~1
ECHO:
GOTO :EOF
REM ### string length Check Function ####
:strlenCheck
SET /a cnt=0
setlocal ENABLEDELAYEDEXPANSION
FOR /F "tokens=1,* delims=:" %%G IN ('FINDSTR /N "^" prefs.js') DO (
ECHO:%%H >nul
SET /a cnt += 1
IF /I "%%G" NEQ "!cnt!" (
ECHO:
CALL :message "ERROR: line !cnt! in prefs.js is too long."
(CALL :abort "Aborting ..." 30)
)
)
endlocal
GOTO :EOF
REM ####### Thunderbird Check Function ######
:FFcheck
TASKLIST /FI "IMAGENAME eq thunderbird.exe" 2>NUL | FIND /I /N "thunderbird.exe">NUL
IF NOT ERRORLEVEL 1 (
CLS
CALL :message "Thunderbird is still running."
ECHO If you're not currently using this profile you can continue, otherwise
CALL :message "close Thunderbird first!"
ECHO:
PAUSE
CLS
CALL :message "Resuming..."
TIMEOUT 5 /nobreak >nul
)
GOTO :EOF
REM ######### Cleanup Function ##########
:cleanup
FOR /F tokens^=2^ delims^=^'^" %%G IN ('FINDSTR /R /C:"^[^\"']*user_pref[ ]*\([ ]*[\"'][^\"']*[\"'][ ]*," user.js') DO (
IF NOT ""=="%%G" (SET "[%%G]=1")
)
(
FOR /F "tokens=1,* delims=:" %%G IN ('FINDSTR /N "^" prefs.js') DO (
IF ""=="%%H" (
ECHO:
) ELSE (
FOR /F tokens^=1^,2^ delims^=^"^' %%I IN ("%%H") DO (
IF NOT DEFINED [%%J] (ECHO:%%H)
)
)
)
)>tempcleanedprefs
MOVE /Y tempcleanedprefs prefs.js
GOTO :EOF
REM ############### Help ##################
:showhelp
MODE 80,34
CLS
CALL :message "This script creates a backup of your prefs.js file before doing anything."
ECHO It should be safe, but you can follow these steps if something goes wrong:
ECHO:
CALL :message " 1. Make sure Thunderbird is closed."
ECHO 2. Delete prefs.js in your profile folder.
CALL :message " 3. Delete Invalidprefs.js if you have one in the same folder."
ECHO 4. Rename or copy your latest backup to prefs.js.
CALL :message " 5. Run Thunderbird and see if you notice anything wrong with it."
ECHO 6. If you do notice something wrong, especially with your extensions,
CALL :message " and/or with the UI, go to about:support, and restart Thunderbird with"
ECHO add-ons disabled. Then, restart it again normally, and see if the
CALL :message " problems were solved."
ECHO:
CALL :message "If you are able to identify the cause of your issues, please bring it up"
ECHO on thunderbird user.js GitHub repository.
ECHO:
ECHO:
PAUSE
CLS
GOTO :begin
REM #####################################

186
prefsCleaner.sh Executable file
View File

@ -0,0 +1,186 @@
#!/usr/bin/env bash
## prefs.js cleaner for Linux/Mac
## /!\ This script is a vendored/adapted version of Arkenfox own prefsCleaner.sh /!\
## author: @claustromaniac
## version: 2.1
## special thanks to @overdodactyl and @earthlng for a few snippets that I stol..*cough* borrowed from the updater.sh
## DON'T GO HIGHER THAN VERSION x.9 !! ( because of ASCII comparison in update_prefsCleaner() )
readonly CURRDIR=$(pwd)
## get the full path of this script (readlink for Linux, greadlink for Mac with coreutils installed)
SCRIPT_FILE=$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null)
## fallback for Macs without coreutils
[ -z "$SCRIPT_FILE" ] && SCRIPT_FILE=${BASH_SOURCE[0]}
AUTOUPDATE=true
QUICKSTART=false
## download method priority: curl -> wget
DOWNLOAD_METHOD=''
if command -v curl >/dev/null; then
DOWNLOAD_METHOD='curl --max-redirs 3 -so'
elif command -v wget >/dev/null; then
DOWNLOAD_METHOD='wget --max-redirect 3 --quiet -O'
else
AUTOUPDATE=false
echo -e "No curl or wget detected.\nAutomatic self-update disabled!"
fi
fQuit() {
## change directory back to the original working directory
cd "${CURRDIR}"
[ "$1" -eq 0 ] && echo -e "\n$2" || echo -e "\n$2" >&2
exit $1
}
fUsage() {
echo -e "\nUsage: $0 [-ds]"
echo -e "
Optional Arguments:
-s Start immediately
-d Don't auto-update prefsCleaner.sh"
}
download_file() { # expects URL as argument ($1)
declare -r tf=$(mktemp)
$DOWNLOAD_METHOD "${tf}" "$1" &>/dev/null && echo "$tf" || echo '' # return the temp-filename or empty string on error
}
fFF_check() {
# there are many ways to see if thunderbird is running or not, some more reliable than others
# this isn't elegant and might not be future-proof but should at least be compatible with any environment
while [ -e lock ]; do
echo -e "\nThis Thunderbird profile seems to be in use. Close Thunderbird and try again.\n" >&2
read -r -p "Press any key to continue."
done
}
## returns the version number of a prefsCleaner.sh file
get_prefsCleaner_version() {
echo "$(sed -n '5 s/.*[[:blank:]]\([[:digit:]]*\.[[:digit:]]*\)/\1/p' "$1")"
}
## updates the prefsCleaner.sh file based on the latest public version
update_prefsCleaner() {
declare -r tmpfile="$(download_file 'https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/prefsCleaner.sh')"
[ -z "$tmpfile" ] && echo -e "Error! Could not download prefsCleaner.sh" && return 1 # check if download failed
[[ $(get_prefsCleaner_version "$SCRIPT_FILE") == $(get_prefsCleaner_version "$tmpfile") ]] && return 0
mv "$tmpfile" "$SCRIPT_FILE"
chmod u+x "$SCRIPT_FILE"
"$SCRIPT_FILE" "$@" -d
exit 0
}
fClean() {
# the magic happens here
prefs="@@"
prefexp="user_pref[ ]*\([ ]*[\"']([^\"']+)[\"'][ ]*,"
while read -r line; do
if [[ "$line" =~ $prefexp && $prefs != *"@@${BASH_REMATCH[1]}@@"* ]]; then
prefs="${prefs}${BASH_REMATCH[1]}@@"
fi
done <<< "$(grep -E "$prefexp" user.js)"
while IFS='' read -r line || [[ -n "$line" ]]; do
if [[ "$line" =~ ^$prefexp ]]; then
if [[ $prefs != *"@@${BASH_REMATCH[1]}@@"* ]]; then
echo "$line"
fi
else
echo "$line"
fi
done < "$1" > prefs.js
}
fStart() {
if [ ! -e user.js ]; then
fQuit 1 "user.js not found in the current directory."
elif [ ! -e prefs.js ]; then
fQuit 1 "prefs.js not found in the current directory."
fi
fFF_check
mkdir -p prefsjs_backups
bakfile="prefsjs_backups/prefs.js.backup.$(date +"%Y-%m-%d_%H%M")"
mv prefs.js "${bakfile}" || fQuit 1 "Operation aborted.\nReason: Could not create backup file $bakfile"
echo -e "\nprefs.js backed up: $bakfile"
echo "Cleaning prefs.js..."
fClean "$bakfile"
fQuit 0 "All done!"
}
while getopts "sd" opt; do
case $opt in
s)
QUICKSTART=true
;;
d)
AUTOUPDATE=false
;;
esac
done
## change directory to the Thunderbird profile directory
cd "$(dirname "${SCRIPT_FILE}")"
# Check if running as root and if any files have the owner as root/wheel.
if [ "${EUID:-"$(id -u)"}" -eq 0 ]; then
fQuit 1 "You shouldn't run this with elevated privileges (such as with doas/sudo)."
elif [ -n "$(find ./ -user 0)" ]; then
printf 'It looks like this script was previously run with elevated privileges,
you will need to change ownership of the following files to your user:\n'
find . -user 0
fQuit 1
fi
[ "$AUTOUPDATE" = true ] && update_prefsCleaner "$@"
echo -e "\n\n"
echo " ╔══════════════════════════╗"
echo " ║ prefs.js cleaner ║"
echo " ║ by claustromaniac ║"
echo " ║ v2.1 ║"
echo " ╚══════════════════════════╝"
echo -e "\nThis script should be run from your Thunderbird profile directory.\n"
echo "It will remove any entries from prefs.js that also exist in user.js."
echo "This will allow inactive preferences to be reset to their default values."
echo -e "\nThis Thunderbird profile shouldn't be in use during the process.\n"
[ "$QUICKSTART" = true ] && fStart
echo -e "\nIn order to proceed, select a command below by entering its corresponding number.\n"
select option in Start Help Exit; do
case $option in
Start)
fStart
;;
Help)
fUsage
echo -e "\nThis script creates a backup of your prefs.js file before doing anything."
echo -e "It should be safe, but you can follow these steps if something goes wrong:\n"
echo "1. Make sure Thunderbird is closed."
echo "2. Delete prefs.js in your profile folder."
echo "3. Delete Invalidprefs.js if you have one in the same folder."
echo "4. Rename or copy your latest backup to prefs.js."
echo "5. Run Thunderbird and see if you notice anything wrong with it."
echo "6. If you do notice something wrong, especially with your extensions, and/or with the UI, go to about:support, and restart Thunderbird with add-ons disabled. Then, restart it again normally, and see if the problems were solved."
echo -e "If you are able to identify the cause of your issues, please bring it up on the thunderbird user.js GitHub repository.\n"
;;
Exit)
fQuit 0
;;
esac
done
fQuit 0

324
updater.bat Normal file
View File

@ -0,0 +1,324 @@
@ECHO OFF & SETLOCAL EnableDelayedExpansion
TITLE thunderbird user.js updater
REM ## thunderbird user.js updater for Windows
REM ## /!\ This script is a vendored/adapted version of Arkenfox own updater.bat /!\
REM ## author: @claustromaniac
REM ## version: 4.19
REM ## instructions: https://github.com/arkenfox/user.js/wiki/5.1-Updater-[Options]#-windows
SET v=4.19
VERIFY ON
CD /D "%~dp0"
SET _myname=%~n0
SET _myparams=%*
:parse
IF "%~1"=="" (GOTO endparse)
IF /I "%~1"=="-unattended" (SET _ua=1)
IF /I "%~1"=="-log" (SET _log=1)
IF /I "%~1"=="-logp" (SET _log=1 & SET _logp=1)
IF /I "%~1"=="-multioverrides" (SET _multi=1)
IF /I "%~1"=="-merge" (SET _merge=1)
IF /I "%~1"=="-updatebatch" (SET _updateb=1)
IF /I "%~1"=="-singlebackup" (SET _singlebackup=1)
IF /I "%~1"=="-esr" (SET _esr=1)
SHIFT
GOTO parse
:endparse
FOR /F %%i IN ('PowerShell -Command "[Enum]::GetNames([Net.SecurityProtocolType]) -contains 'Tls12'"') DO (
IF "%%i" == "False" (
CALL :message "Your PowerShell version doesn't support TLS1.2 ^!"
ECHO: Instructions to update PowerShell are on the arkenfox wiki
PAUSE
EXIT
)
)
IF DEFINED _updateb (
REM The normal flow here goes from phase 1 to phase 2 and then phase 3.
IF NOT "!_myname:~0,9!"=="[updated]" (
IF EXIST "[updated]!_myname!.bat" (
REM ## Phase 3 ##: The new script, with the original name, will:
REM * Delete the [updated]*.bat and *.bat.old scripts
REM * Begin the normal routine
FC "[updated]!_myname!.bat" "!_myname!.bat.old" >nul
IF NOT "!errorlevel!"=="0" (
CALL :message "Script updated to version !v!"
TIMEOUT 3 >nul
)
REN "[updated]!_myname!.bat" "[updated]!_myname!.bat.old"
DEL /F "!_myname!.bat.old" "[updated]!_myname!.bat.old"
GOTO begin
)
REM ## Phase 1 ##
REM * Download new batch and name it [updated]*.bat
REM * Start that script in a new CMD window
REM * Exit
CALL :message "Updating script..."
REM Uncomment the next line and comment out the PowerShell call for testing.
REM COPY /B /Y "!_myname!.bat" "[updated]!_myname!.bat" >nul
CALL :psdownload https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/updater.bat "[updated]!_myname!.bat"
IF EXIST "[updated]!_myname!.bat" (
START /min CMD /C "[updated]!_myname!.bat" !_myparams!
) ELSE (
CALL :message "Failed. Make sure PowerShell is allowed internet access."
TIMEOUT 120 >nul
)
) ELSE (
IF "!_myname!"=="[updated]" (
CALL :message "The [updated] label is reserved. Rename this script and try again."
TIMEOUT 300 >nul
) ELSE (
REM ## Phase 2 ##: The [updated]*.bat script will:
REM * Rename the old script and make a copy of itself with the original name.
REM * Run that copy in a new CMD instance
REM * Exit
IF EXIST "!_myname:~9!.bat" ( REN "!_myname:~9!.bat" "!_myname:~9!.bat.old" )
COPY /B /Y "!_myname!.bat" "!_myname:~9!.bat"
START CMD /C "!_myname:~9!.bat" !_myparams!
)
)
EXIT /B
)
:begin
CLS
ECHO:
ECHO:
ECHO: ########################################
ECHO: #### user.js Updater for Windows ####
ECHO: #### by claustromaniac ####
ECHO: #### v!v! ####
ECHO: ########################################
ECHO:
SET /A "_line=0"
IF NOT EXIST user.js (
CALL :message "user.js not detected in the current directory."
) ELSE (
FOR /F "skip=1 tokens=1,* delims=:" %%G IN (user.js) DO (
SET /A "_line+=1"
IF !_line! GEQ 4 (GOTO exitloop)
IF !_line! EQU 1 (SET _name=%%H)
IF !_line! EQU 2 (SET _date=%%H)
IF !_line! EQU 3 (SET _version=%%G)
)
:exitloop
IF NOT "!_name!"=="" (
SET "_tempvar="
IF /I NOT "!_name!"=="!_name:ghacks=!" SET _tempvar=1
IF /I NOT "!_name!"=="!_name:arkenfox=!" SET _tempvar=1
IF !_tempvar! EQU 1 (
CALL :message "!_name! !_version:~2!,!_date!"
) ELSE (CALL :message "Current user.js version not recognised.")
) ELSE (CALL :message "Current user.js version not recognised.")
)
ECHO:
IF NOT DEFINED _ua (
CALL :message "This batch should be run from your Thunderbird profile directory."
ECHO: It will download the latest version of thunderbird user.js from github and then
CALL :message "append any of your own changes from user-overrides.js to it."
CALL :message "Visit the wiki for more detailed information."
ECHO:
TIMEOUT 1 /nobreak >nul
CHOICE /C SHE /N /M "Start [S] Help [H] Exit [E]"
CLS
IF ERRORLEVEL 3 (EXIT /B)
IF ERRORLEVEL 2 (GOTO :showhelp)
)
IF DEFINED _log (
CALL :log >>user.js-update-log.txt 2>&1
IF DEFINED _logp (START user.js-update-log.txt)
EXIT /B
:log
SET _log=2
ECHO:##################################################################
ECHO: %date%, %time%
)
IF EXIST user.js.new (DEL /F "user.js.new")
CALL :message "Retrieving latest user.js file from github repository..."
CALL :psdownload https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/user.js "user.js.new"
IF EXIST user.js.new (
IF DEFINED _esr (
CALL :message "Activating ESR section..."
CALL :activate user.js.new ".x still uses all the following prefs"
)
IF DEFINED _multi (
FORFILES /P user.js-overrides /M *.js >nul 2>&1
IF NOT ERRORLEVEL 1 (
IF DEFINED _merge (
CALL :message "Merging..."
COPY /B /Y user.js-overrides\*.js user-overrides-merged.js
CALL :merge user-overrides-merged.js
COPY /B /Y user.js.new+user-overrides-merged.js user.js.new
CALL :merge user.js.new
) ELSE (
CALL :message "Appending..."
COPY /B /Y user.js.new+"user.js-overrides\*.js" user.js.new
)
) ELSE (CALL :message "No override files found.")
) ELSE (
IF EXIST "user-overrides.js" (
COPY /B /Y user.js.new+"user-overrides.js" "user.js.new"
IF DEFINED _merge (
CALL :message "Merging user-overrides.js..."
CALL :merge user.js.new
) ELSE (
CALL :message "user-overrides.js appended."
)
) ELSE (CALL :message "user-overrides.js not found.")
)
IF EXIST user.js (
FC user.js.new user.js >nul && SET "_changed=false" || SET "_changed=true"
)
IF "!_changed!"=="true" (
CALL :message "Backing up..."
IF DEFINED _singlebackup (
MOVE /Y user.js user.js.bak >nul
) ELSE (
FOR /F "delims=" %%# IN ('powershell get-date -format "{yyyyMMdd_HHmmss}"') DO @SET ldt=%%#
MOVE /Y user.js "user-backup-!ldt!.js" >nul
)
REN user.js.new user.js
CALL :message "Update complete."
) ELSE (
IF "!_changed!"=="false" (
DEL /F user.js.new >nul
CALL :message "Update completed without changes."
) ELSE (
REN user.js.new user.js
CALL :message "Update complete."
SET "_changed=true"
)
)
) ELSE (
CALL :message "Update failed. Make sure PowerShell is allowed internet access."
ECHO: No changes were made.
)
IF NOT DEFINED _log (
IF NOT DEFINED _ua (
IF EXIST prefsCleaner.bat (
IF "!_changed!"=="true" (
CALL :message "Would you like to run the prefsCleaner now?"
CHOICE /C YN /N /M "(Y/N) "
IF "1"=="!errorlevel!" ( START "" cmd.exe /C "prefsCleaner.bat" )
) ELSE (PAUSE)
) ELSE (PAUSE)
)
)
EXIT /B
::::::::::::::: Message :::::::::::::::
:message
SETLOCAL DisableDelayedExpansion
IF NOT "2"=="%_log%" (ECHO:)
ECHO: %~1
IF NOT "2"=="%_log%" (ECHO:)
ENDLOCAL
GOTO :EOF
::::::::::::::: Download :::::::::::::::
:psdownload
(
PowerShell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; (New-Object Net.WebClient).DownloadFile('%~1', '%~2')"
) >nul 2>&1
GOTO :EOF
::::::::::::::: Activate Section :::::::::::::::
:activate
:: arg1 = file
:: arg2 = line substring
SETLOCAL DisableDelayedExpansion
(
FOR /F "tokens=1,* delims=:" %%G IN ('FINDSTR /N "^" "%~1"') DO (
SET "_temp=%%H"
SETLOCAL EnableDelayedExpansion
IF "!_temp:%~2=!"=="!_temp!" (
ENDLOCAL & ECHO:%%H
) ELSE (
ECHO://!_temp:~2!
ENDLOCAL
)
)
)>updatertempfile
MOVE /Y updatertempfile "%~1" >nul
ENDLOCAL
GOTO :EOF
::::::::::::::: Merge :::::::::::::::
:merge
SETLOCAL DisableDelayedExpansion
FOR /F tokens^=2^,^*^ delims^=^'^" %%G IN ('FINDSTR /R /C:"^user_pref[ ]*\([ ]*[\"'].*[\"'][ ]*,.*\)[ ]*;" "%~1"') DO (SET "[%%G]=%%H")
FOR /F tokens^=2^,^*^ delims^=^' %%G IN ('FINDSTR /R /C:"^//// --- comment-out --- '[^'][^']*'.*" "%~1"') DO (SET "__unset__%%G=1")
(
FOR /F "tokens=1,* delims=:" %%I IN ('FINDSTR /N "^" "%~1"') DO (
SET "_temp=%%J"
SETLOCAL EnableDelayedExpansion
IF NOT "!_temp:~0,9!"=="user_pref" (
ENDLOCAL & ECHO:%%J
) ELSE (
IF "!_temp:;=!"=="!_temp!" (
ENDLOCAL & ECHO:%%J
) ELSE (
ENDLOCAL
FOR /F tokens^=2^ delims^=^'^" %%K IN ("%%J") DO (
IF NOT "_user.js.parrot"=="%%K" (
IF DEFINED __unset__%%K (
ECHO://%%J
) ELSE (
IF DEFINED [%%K] (
SETLOCAL EnableDelayedExpansion
FOR /F "delims=" %%L IN ("![%%K]!") DO (
ENDLOCAL & ECHO:user_pref("%%K"%%L
SET "[%%K]="
)
)
)
) ELSE (ECHO:%%J)
)
)
)
)
)>updatertempfile
MOVE /Y updatertempfile "%~1" >nul
ENDLOCAL
GOTO :EOF
::::::::::::::: Help :::::::::::::::
:showhelp
MODE 80,54
CLS
CALL :message "Available arguments (case-insensitive):"
CALL :message " -esr"
ECHO: Activate ESR related preferences
CALL :message " -log"
ECHO: Write the console output to a logfile (user.js-update-log.txt)
CALL :message " -logP"
ECHO: Like -log, but also open the logfile after updating.
CALL :message " -merge"
ECHO: Merge overrides instead of appending them. Single-line comments and
ECHO: _user.js.parrot lines are appended normally. Overrides for inactive
ECHO: user.js prefs will be appended. When -Merge and -MultiOverrides are used
ECHO: together, a user-overrides-merged.js file is also generated in the root
ECHO: directory for quick reference. It contains only the merged data from
ECHO: override files and can be safely discarded after updating, or used as the
ECHO: new user-overrides.js. When there are conflicting records for the same
ECHO: pref, the value of the last one declared will be used. Visit the wiki
ECHO: for usage examples and more detailed information.
CALL :message " -multiOverrides"
ECHO: Use any and all .js files in a user.js-overrides sub-folder as overrides
ECHO: instead of the default user-overrides.js file. Files are appended in
ECHO: alphabetical order.
CALL :message " -unattended"
ECHO: Run without user input.
CALL :message " -singleBackup"
ECHO: Use a single backup file and overwrite it on new updates, instead of
ECHO: cumulative backups. This was the default behaviour before v4.3.
CALL :message " -updateBatch"
ECHO: Update the script itself on execution, before the normal routine.
CALL :message ""
PAUSE
MODE 80,25
GOTO :begin

408
updater.sh Executable file
View File

@ -0,0 +1,408 @@
#!/usr/bin/env bash
## thunderbird user.js updater for macOS and Linux
## /!\ This script is a vendored/adapted version of Arkenfox own updater.sh /!\
## version: 4.0
## Author: Pat Johnson (@overdodactyl)
## Additional contributors: @earthlng, @ema-pe, @claustromaniac, @infinitewarp
## DON'T GO HIGHER THAN VERSION x.9 !! ( because of ASCII comparison in update_updater() )
# Check if running as root
if [ "${EUID:-"$(id -u)"}" -eq 0 ]; then
printf "You shouldn't run this with elevated privileges (such as with doas/sudo).\n"
exit 1
fi
readonly CURRDIR=$(pwd)
SCRIPT_FILE=$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null)
[ -z "$SCRIPT_FILE" ] && SCRIPT_FILE=${BASH_SOURCE[0]}
readonly SCRIPT_DIR=$(dirname "${SCRIPT_FILE}")
#########################
# Base variables #
#########################
# Colors used for printing
RED='\033[0;31m'
BLUE='\033[0;34m'
BBLUE='\033[1;34m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Argument defaults
UPDATE='check'
CONFIRM='yes'
OVERRIDE='user-overrides.js'
BACKUP='multiple'
COMPARE=false
SKIPOVERRIDE=false
VIEW=false
PROFILE_PATH=false
ESR=false
# Download method priority: curl -> wget
DOWNLOAD_METHOD=''
if command -v curl >/dev/null; then
DOWNLOAD_METHOD='curl --max-redirs 3 -so'
elif command -v wget >/dev/null; then
DOWNLOAD_METHOD='wget --max-redirect 3 --quiet -O'
else
echo -e "${RED}This script requires curl or wget.\nProcess aborted${NC}"
exit 1
fi
show_banner() {
echo -e "${BBLUE}
############################################################################
#### ####
#### thunderbird user.js ####
#### Hardening the Privacy and Security Settings of Thunderbird ####
#### Maintained by @Thorin-Oakenpants and @earthlng ####
#### Updater for macOS and Linux by @overdodactyl ####
#### ####
############################################################################"
echo -e "${NC}\n"
echo -e "Documentation for this script is available here: ${CYAN}https://github.com/arkenfox/user.js/wiki/5.1-Updater-[Options]#-maclinux${NC}\n"
}
#########################
# Arguments #
#########################
usage() {
echo
echo -e "${BLUE}Usage: $0 [-bcdehlnrsuv] [-p PROFILE] [-o OVERRIDE]${NC}" 1>&2 # Echo usage string to standard error
echo -e "
Optional Arguments:
-h Show this help message and exit.
-p PROFILE Path to your Thunderbird profile (if different than the dir of this script)
IMPORTANT: If the path contains spaces, wrap the entire argument in quotes.
-l Choose your Thunderbird profile from a list
-u Update updater.sh and execute silently. Do not seek confirmation.
-d Do not look for updates to updater.sh.
-s Silently update user.js. Do not seek confirmation.
-b Only keep one backup of each file.
-c Create a diff file comparing old and new user.js within userjs_diffs.
-o OVERRIDE Filename or path to overrides file (if different than user-overrides.js).
If used with -p, paths should be relative to PROFILE or absolute paths
If given a directory, all files inside will be appended recursively.
You can pass multiple files or directories by passing a comma separated list.
Note: If a directory is given, only files inside ending in the extension .js are appended
IMPORTANT: Do not add spaces between files/paths. Ex: -o file1.js,file2.js,dir1
IMPORTANT: If any file/path contains spaces, wrap the entire argument in quotes.
Ex: -o \"override folder\"
-n Do not append any overrides, even if user-overrides.js exists.
-v Open the resulting user.js file.
-r Only download user.js to a temporary file and open it.
-e Activate ESR related preferences."
echo
exit 1
}
#########################
# File Handling #
#########################
download_file() { # expects URL as argument ($1)
declare -r tf=$(mktemp)
$DOWNLOAD_METHOD "${tf}" "$1" &>/dev/null && echo "$tf" || echo '' # return the temp-filename or empty string on error
}
open_file() { # expects one argument: file_path
if [ "$(uname)" == 'Darwin' ]; then
open "$1"
elif [ "$(uname -s | cut -c -5)" == "Linux" ]; then
xdg-open "$1"
else
echo -e "${RED}Error: Sorry, opening files is not supported for your OS.${NC}"
fi
}
readIniFile() { # expects one argument: absolute path of profiles.ini
declare -r inifile="$1"
# tempIni will contain: [ProfileX], Name=, IsRelative= and Path= (and Default= if present) of the only (if) or the selected (else) profile
if [ "$(grep -c '^\[Profile' "${inifile}")" -eq "1" ]; then ### only 1 profile found
tempIni="$(grep '^\[Profile' -A 4 "${inifile}")"
else
echo -e "Profiles found:\n"
## cmd-substitution to strip trailing newlines and in quotes to keep internal ones:
echo "$(grep --color=never -E 'Default=[^1]|\[Profile[0-9]*\]|Name=|Path=|^$' "${inifile}")"
echo ''
read -p 'Select the profile number ( 0 for Profile0, 1 for Profile1, etc ) : ' -r
echo -e "\n"
if [[ $REPLY =~ ^(0|[1-9][0-9]*)$ ]]; then
tempIni="$(grep "^\[Profile${REPLY}" -A 4 "${inifile}")" || {
echo -e "${RED}Profile${REPLY} does not exist!${NC}" && exit 1
}
else
echo -e "${RED}Invalid selection!${NC}" && exit 1
fi
fi
# extracting 0 or 1 from the "IsRelative=" line
declare -r pathisrel=$(sed -n 's/^IsRelative=\([01]\)$/\1/p' <<< "${tempIni}")
# extracting only the path itself, excluding "Path="
PROFILE_PATH=$(sed -n 's/^Path=\(.*\)$/\1/p' <<< "${tempIni}")
# update global variable if path is relative
[[ ${pathisrel} == "1" ]] && PROFILE_PATH="$(dirname "${inifile}")/${PROFILE_PATH}"
}
getProfilePath() {
declare -r f1=~/Library/Application\ Support/Thunderbird/profiles.ini
declare -r f2=~/.thunderbird/profiles.ini
if [ "$PROFILE_PATH" = false ]; then
PROFILE_PATH="$SCRIPT_DIR"
elif [ "$PROFILE_PATH" = 'list' ]; then
if [[ -f "$f1" ]]; then
readIniFile "$f1" # updates PROFILE_PATH or exits on error
elif [[ -f "$f2" ]]; then
readIniFile "$f2"
else
echo -e "${RED}Error: Sorry, -l is not supported for your OS${NC}"
exit 1
fi
#else
# PROFILE_PATH already set by user with -p
fi
}
#########################
# Update updater.sh #
#########################
# Returns the version number of a updater.sh file
get_updater_version() {
echo "$(sed -n '5 s/.*[[:blank:]]\([[:digit:]]*\.[[:digit:]]*\)/\1/p' "$1")"
}
# Update updater.sh
# Default: Check for update, if available, ask user if they want to execute it
# Args:
# -d: New version will not be looked for and update will not occur
# -u: Check for update, if available, execute without asking
update_updater() {
[ "$UPDATE" = 'no' ] && return 0 # User signified not to check for updates
declare -r tmpfile="$(download_file 'https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/updater.sh')"
[ -z "${tmpfile}" ] && echo -e "${RED}Error! Could not download updater.sh${NC}" && return 1 # check if download failed
if [[ $(get_updater_version "$SCRIPT_FILE") < $(get_updater_version "${tmpfile}") ]]; then
if [ "$UPDATE" = 'check' ]; then
echo -e "There is a newer version of updater.sh available. ${RED}Update and execute Y/N?${NC}"
read -p "" -n 1 -r
echo -e "\n\n"
[[ $REPLY =~ ^[Yy]$ ]] || return 0 # Update available, but user chooses not to update
fi
else
return 0 # No update available
fi
mv "${tmpfile}" "$SCRIPT_FILE"
chmod u+x "$SCRIPT_FILE"
"$SCRIPT_FILE" "$@" -d
exit 0
}
#########################
# Update user.js #
#########################
# Returns version number of a user.js file
get_userjs_version() {
[ -e "$1" ] && echo "$(sed -n '4p' "$1")" || echo "Not detected."
}
add_override() {
input=$1
if [ -f "$input" ]; then
echo "" >> user.js
cat "$input" >> user.js
echo -e "Status: ${GREEN}Override file appended:${NC} ${input}"
elif [ -d "$input" ]; then
SAVEIFS=$IFS
IFS=$'\n\b' # Set IFS
FILES="${input}"/*.js
for f in $FILES
do
add_override "$f"
done
IFS=$SAVEIFS # restore $IFS
else
echo -e "${ORANGE}Warning: Could not find override file:${NC} ${input}"
fi
}
remove_comments() { # expects 2 arguments: from-file and to-file
sed -e '/^\/\*.*\*\/[[:space:]]*$/d' -e '/^\/\*/,/\*\//d' -e 's|^[[:space:]]*//.*$||' -e '/^[[:space:]]*$/d' -e 's|);[[:space:]]*//.*|);|' "$1" > "$2"
}
# Applies latest version of user.js and any custom overrides
update_userjs() {
declare -r newfile="$(download_file 'https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/user.js')"
[ -z "${newfile}" ] && echo -e "${RED}Error! Could not download user.js${NC}" && return 1 # check if download failed
echo -e "Please observe the following information:
Thunderbird profile: ${ORANGE}$(pwd)${NC}
Available online: ${ORANGE}$(get_userjs_version "$newfile")${NC}
Currently using: ${ORANGE}$(get_userjs_version user.js)${NC}\n\n"
if [ "$CONFIRM" = 'yes' ]; then
echo -e "This script will update to the latest user.js file and append any custom configurations from user-overrides.js. ${RED}Continue Y/N? ${NC}"
read -p "" -n 1 -r
echo -e "\n"
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}Process aborted${NC}"
rm "$newfile"
return 1
fi
fi
# Copy a version of user.js to diffs folder for later comparison
if [ "$COMPARE" = true ]; then
mkdir -p userjs_diffs
cp user.js userjs_diffs/past_user.js &>/dev/null
fi
# backup user.js
mkdir -p userjs_backups
local bakname="userjs_backups/user.js.backup.$(date +"%Y-%m-%d_%H%M")"
[ "$BACKUP" = 'single' ] && bakname='userjs_backups/user.js.backup'
cp user.js "$bakname" &>/dev/null
mv "${newfile}" user.js
echo -e "Status: ${GREEN}user.js has been backed up and replaced with the latest version!${NC}"
if [ "$ESR" = true ]; then
sed -e 's/\/\* \(ESR[0-9]\{2,\}\.x still uses all.*\)/\/\/ \1/' user.js > user.js.tmp && mv user.js.tmp user.js
echo -e "Status: ${GREEN}ESR related preferences have been activated!${NC}"
fi
# apply overrides
if [ "$SKIPOVERRIDE" = false ]; then
while IFS=',' read -ra FILES; do
for FILE in "${FILES[@]}"; do
add_override "$FILE"
done
done <<< "$OVERRIDE"
fi
# create diff
if [ "$COMPARE" = true ]; then
pastuserjs='userjs_diffs/past_user.js'
past_nocomments='userjs_diffs/past_userjs.txt'
current_nocomments='userjs_diffs/current_userjs.txt'
remove_comments "$pastuserjs" "$past_nocomments"
remove_comments user.js "$current_nocomments"
diffname="userjs_diffs/diff_$(date +"%Y-%m-%d_%H%M").txt"
diff=$(diff -w -B -U 0 "$past_nocomments" "$current_nocomments")
if [ -n "$diff" ]; then
echo "$diff" > "$diffname"
echo -e "Status: ${GREEN}A diff file was created:${NC} ${PWD}/${diffname}"
else
echo -e "Warning: ${ORANGE}Your new user.js file appears to be identical. No diff file was created.${NC}"
[ "$BACKUP" = 'multiple' ] && rm "$bakname" &>/dev/null
fi
rm "$past_nocomments" "$current_nocomments" "$pastuserjs" &>/dev/null
fi
[ "$VIEW" = true ] && open_file "${PWD}/user.js"
}
#########################
# Execute #
#########################
if [ $# != 0 ]; then
# Display usage if first argument is -help or --help
if [ "$1" = '--help' ] || [ "$1" = '-help' ]; then
usage
else
while getopts ":hp:ludsno:bcvre" opt; do
case $opt in
h)
usage
;;
p)
PROFILE_PATH=${OPTARG}
;;
l)
PROFILE_PATH='list'
;;
u)
UPDATE='yes'
;;
d)
UPDATE='no'
;;
s)
CONFIRM='no'
;;
n)
SKIPOVERRIDE=true
;;
o)
OVERRIDE=${OPTARG}
;;
b)
BACKUP='single'
;;
c)
COMPARE=true
;;
v)
VIEW=true
;;
e)
ESR=true
;;
r)
tfile="$(download_file 'https://raw.githubusercontent.com/HorlogeSkynet/thunderbird-user.js/master/user.js')"
[ -z "${tfile}" ] && echo -e "${RED}Error! Could not download user.js${NC}" && exit 1 # check if download failed
mv "$tfile" "${tfile}.js"
echo -e "${ORANGE}Warning: user.js was saved to temporary file ${tfile}.js${NC}"
open_file "${tfile}.js"
exit 0
;;
\?)
echo -e "${RED}\n Error! Invalid option: -$OPTARG${NC}" >&2
usage
;;
:)
echo -e "${RED}Error! Option -$OPTARG requires an argument.${NC}" >&2
exit 2
;;
esac
done
fi
fi
show_banner
update_updater "$@"
getProfilePath # updates PROFILE_PATH or exits on error
cd "$PROFILE_PATH" || exit 1
# Check if any files have the owner as root/wheel.
if [ -n "$(find ./ -user 0)" ]; then
printf 'It looks like this script was previously run with elevated privileges,
you will need to change ownership of the following files to your user:\n'
find . -user 0
cd "$CURRDIR"
exit 1
fi
update_userjs
cd "$CURRDIR"