useful-scripts/bin/citrix-update

202 lines
5.4 KiB
Text
Raw Normal View History

2025-10-29 16:55:38 +00:00
#!/bin/bash
# name: citrix-update
# summary: Startup script: Downloads and installs "Citrix Workspace"
# params: none
THISDIR="$(dirname "$(readlink -f "${0}")")"
# shellcheck disable=SC1091
. "${THISDIR}/.inc/common"
2025-10-29 16:55:38 +00:00
########
# INIT #
########
# find all download links on update page
# find corresponding checksums
2025-10-30 13:58:34 +00:00
needs_commands "xidel" "curl" || exit 1
2025-10-29 16:55:38 +00:00
echo -n "Downloading citrix update page ... " >&2
html_data="$(curl -sSfL 'https://www.citrix.com/downloads/workspace-app/linux/workspace-app-for-linux-latest.html')"
echo "OK!" >&2
# # XPath playground
# echo "${html_data}" | xidel - \
# --silent \
# --printed-node-format text \
# --extract "links:=//div[contains(@class, 'ctx-dl-content')]//a[contains(@class, 'ctx-dl-link') and @rel]/@rel" \
# --extract "csums:=//div[contains(@class, 'ctx-dl-content')]//ul[contains(@class, 'ctx-checksum-list')]/li[1]/text()"
# exit 0
# parse using XPath
declare -a links csums
eval "$( \
echo "${html_data}" | xidel - \
--silent \
--output-format bash \
--extract "links:=//div[contains(@class, 'ctx-dl-content')]//a[contains(@class, 'ctx-dl-link') and @rel]/@rel" \
--extract "csums:=//div[contains(@class, 'ctx-dl-content')]//ul[contains(@class, 'ctx-checksum-list')]/li[1]/text()" \
2025-10-29 16:55:38 +00:00
)"
# ensure every link has a checksum
if [[ "${!links[*]}" != "${!csums[*]}" ]]; then
echo "Links and Checksums don't match up!" >&2
exit 1
2025-10-29 16:55:38 +00:00
fi
# postprocess data
declare -A citrix_data
for key in "${!links[@]}"; do
link="${links["${key}"]}"
2025-10-29 16:55:38 +00:00
# if link starts with "//" (no protocol), assume https
if [[ "${link}" == "//"* ]]; then
link="https:${link}"
fi
2025-10-29 16:55:38 +00:00
# extract checksum only (64 hex digits)
csum="$(echo "${csums["${key}"]}" | grep -Eo "\<[[:xdigit:]]{64}\>")"
2025-10-29 16:55:38 +00:00
citrix_data["${csum}"]="${link}"
2025-10-29 16:55:38 +00:00
done
# remove intermediate containers
unset links csums
#########
# FUNCS #
#########
find_links() { # $filename_regex
local link_regex="://downloads\.citrix\.com/[[:digit:]]+/${1}\?__gda__=exp=[[:digit:]]+~acl=[^~]+~hmac=[[:digit:]a-f]{64}$"
2025-10-29 16:55:38 +00:00
for key in "${!citrix_data[@]}"; do
if echo "${citrix_data["${key}"]}" | grep -E "${link_regex}" &>/dev/null; then
echo "${key} ${citrix_data["${key}"]}"
fi
done
2025-10-29 16:55:38 +00:00
}
find_links_deb() { # $name $arch
case "${2}" in
x86_64) local arch="amd64" ;;
arm64) local arch="arm64" ;;
*) local arch="${2}" ;;
esac
2025-10-29 16:55:38 +00:00
find_links "${1}_[[:digit:]\.]+_${arch}\.deb"
2025-10-29 16:55:38 +00:00
}
find_links_rpm() { # $name $flavor $arch
find_links "${1}(:?-${2})?-[[:digit:]\.]+(:?-[[:digit:]]+)?.${3}\.rpm"
2025-10-29 16:55:38 +00:00
}
find_links_targz() { # $arch
case "${1}" in
x86_64) local arch="x64" ;;
arm64) local arch="arm64" ;;
*) local arch="${1}" ;;
esac
2025-10-29 16:55:38 +00:00
find_links "linux${arch}-[[:digit:]\.]+\.tar.gz"
2025-10-29 16:55:38 +00:00
}
# shellcheck disable=SC2155
list_all_links() {
local debs="$(find_links_deb "[[:lower:]]+" "[[:alnum:]]+")"
local debc="$(echo "${debs}" | wc -l)"
echo "deb:"
echo "${debs}"
local rpms="$(find_links_rpm "[[:alpha:]]+" "[[:lower:]]+" "[[:alnum:]_]+")"
local rpmc="$(echo "${rpms}" | wc -l)"
echo "rpm:"
echo "${rpms}"
local tars="$(find_links_targz "[[:alnum:]]+")"
local tarc="$(echo "${tars}" | wc -l)"
echo "tar.gz:"
echo "${tars}"
local anys="$(find_links "[[:alnum:]\._-]+")"
local anyc="$(echo "${anys}" | wc -l)"
echo "any:"
echo "${anys}"
if [ $(( debc + rpmc + tarc )) -ne $(( anyc )) ]; then
echo "Not all links matched!" >&2
exit 1
fi
2025-10-29 16:55:38 +00:00
}
install_deb() { # $name
needs_commands "dpkg-query" "zenity" "notify-send" "gdebi-gtk" || return 1
local arch
arch="$(uname -m)"
echo "Trying to install ${1} DEB for ${arch}" >&2
local link
if ! link="$(find_links_deb "${1}" "${arch}")"; then
echo "No DEB found!" >&2
return 1
elif [ "$(echo "${link}" | wc -l)" -ne 1 ]; then
echo "More than one DEB found!" >&2
return 1
2025-10-29 16:55:38 +00:00
fi
local csum
csum="$(echo "${link}" | cut -d' ' -f1)"
link="$(echo "${link}" | cut -d' ' -f2)"
local version_available
version_available="$(echo "${link}" | sed -r 's/^.*\/[^_]+_([[:digit:]\.]+)_[^\.]+\.deb.*$/\1/')"
local version_installed
if version_installed="$(dpkg-query --show --showformat='${Version}\n' "${1}")" \
&& [ "${version_available}" = "${version_installed}" ]; then
echo "Newest version already installed!" >&2
notify-send \
--app-name "citrix-update" \
--icon "info" \
"Citrix Update" \
"Citrix \"${1}\": Newest version is installed!"
sleep 2
return 0
fi
2025-10-29 16:55:38 +00:00
if ! zenity \
--question \
--title="New Version Available" \
--text="<span size=\"xx-large\">Citrix Upgrade Available!</span>\n\nInstall ${1} version <b>${version_available}</b> now?"; then
echo "Installation of ${1} cancelled!" >&2
return 0
fi
2025-10-30 13:58:34 +00:00
local destfile
destfile="$(mktemp --tmpdir "XXXXX_${1}_${version_available}.deb")"
if download_gui "${link}" "${destfile}" "${csum}"; then
echo "Download for ${1} successful!" >&2
gdebi-gtk "${destfile}"
fi
2025-10-29 16:55:38 +00:00
rm -f "${destfile}"
echo "Cleaned up '${destfile}'" >&2
2025-10-29 16:55:38 +00:00
return 0
}
########
# MAIN #
########
list_all_links > /dev/null
2025-10-29 16:55:38 +00:00
if has_command "apt"; then
install_deb "icaclient" || exit 1
install_deb "ctxusb" || exit 1
2025-10-29 16:55:38 +00:00
fi
exit 0