Repository URL to install this package:
|
Version:
14.5.1691-1 ▾
|
#!/bin/bash
TV_SCRIPT_DIR="$(dirname "$(readlink -e "$0")")"
source "$TV_SCRIPT_DIR/tvw_main"
TV_MAJOR=14
TV_PACKAGE_INSTALL='yes'
TV_LOG_DIR="$TV_BASE_DIR/logfiles" # overriding default for TAR_NI
TV_CHECKLIB_DIR='/tmp/teamviewerTARLibCheck'
TV_DBUS_FILE_GUI='com.teamviewer.TeamViewer.service'
TV_DBUS_FILE_DESKTOP='com.teamviewer.TeamViewer.Desktop.service'
TV_POLKIT_FILE='com.teamviewer.TeamViewer.policy'
function TVSetup()
{
CheckInteractive $#
local -r mainAction="$1"
local -r mainForce="$2" # force
local -r mainParam="$3" # update / finish / redir (internal use)
case "$mainAction" in
( 'checklibs' ) CheckLibs ;;
( 'install' ) InstallTar ;;
( 'uninstall' ) InstallTar 'un' ;;
( * ) PrintInfo ;;
esac
}
function CheckInteractive()
{
[ "$1" = 0 ] || return # prevent recursion in case of error
cmdExists tty || return # fail gracefully
tty -s
[ $? = 0 ] && return # we have a tty - check successful
# try to call self with terminal emulator
local -r cmd="$0 --nocheck"
local -r geomc='120x40+300+100'
if cmdExists konsole; then
konsole --hold -e "$cmd"
elif cmdExists gnome-terminal; then
gnome-terminal --geometry=$geomc -e "/bin/bash -c '$cmd; exec bash -i'"
else
xterm -geometry $geomc -hold -e "$cmd"
fi
exit
}
function CheckNoInstallation()
{
[ "$TV_PKGTYPE" = 'TAR_NI' ]
}
function PrintInfo()
{
echo
ABecho 'How to use TeamViewer (tar.xz)'
echo
if CheckNoInstallation; then
ABecho 'teamviewer' 'run teamviewer directly'
echo " You can just extract the tar.xz package and run 'teamviewer' without installation."
echo ' It will behave similar to a TeamViewer Portable or QuickSupport on Windows.'
echo ' This should work if all necessary libraries (packages) are installed on your system.'
echo
fi
ABecho 'tv-setup checklibs' 'identify missing libraries'
echo ' Run this command to identify missing libraries'
echo ' You can then look for the matching packages and install them manually.'
echo
ABecho 'tv-setup install' 'interactive installation'
ABecho 'tv-setup install force' 'no questions'
echo ' A permanent installation with all the features of the RPM/DEB packages'
echo ' (start menu entries, auto start, background daemon for permanent access)'
echo
ABecho 'tv-setup uninstall [force]' 'undo previous (TAR) installation'
echo ' Removes the package. Log files and configuration are not removed'
echo
echo
}
function CheckSystemPackageMatch()
{
checkSupportedArchitecture
local -r testBin="$TV_BIN_DIR/TeamViewer"
local -r sysArch="$(getSystemArchitecture)"
local -r pkgArch="$(getFileArchitecture "$testBin")"
[ "$sysArch" = "$pkgArch" ] && return
Yecho "Your system architecture appears to be '$sysArch', but this package is '$pkgArch'."
if [ "$sysArch" == 'x86_64' ] && [ "$pkgArch" == 'x86_32' ]; then
echo 'You may continue, but it is recommended to install the 64bit package'
else
Rdie 'Please get the appropriate package for your system.'
fi
}
function CheckLibs()
{
local -r silent="$1"
if [ -n "$silent" ]; then
ABecho 'Checking dependencies'
else
echo
ABecho ' -=- TeamViewer tar.xz check -=- '
echo
echo ' In order to use the tar.xz version of TeamViewer, '
echo ' you have to make sure that the necessary libraries are installed.'
echo
fi
cmdExists ldd || Rdie 'ldd not found. ldd needs to be installed'
CheckSystemPackageMatch
local tvdaemn="$TV_BIN_DIR/teamviewerd" # dl, pthread, rt, dbus, X11, Xau, xcb, Xdmcp
local tvdeskt="$TV_BIN_DIR/TeamViewer_Desktop" # dl, pthread, rt, dbus, ICE, SM, uuid, X11, Xau, xcb, Xdmcp, Xext, Xrender, Xdamage, libXfixes, Xrandr, Xtst
local tvgui="$TV_BIN_DIR/TeamViewer" # dl, pthread, rt, dbus, Qt*
local logdir="$TV_LOG_DIR" # save logs in TAR directory in interactive mode
if [ -n "$silent" ] || (! isWritableDir "$logdir"); then # save in /tmp in silent (install/root) mode (and always for Host)
mkdir -p "$TV_CHECKLIB_DIR"
logdir="$TV_CHECKLIB_DIR"
fi
local lddlog="$logdir/DependencyCheck.log"
echo > "$lddlog" || Rdie "could not write to $lddlog"
[ -z "$silent" ] && echo " Writing raw output to $lddlog"
CheckLibDependency 'TV_DMN' "$tvdaemn" "$lddlog"
CheckLibDependency 'TV_DESK' "$tvdeskt" "$lddlog"
CheckLibDependency 'TV_GUI' "$tvgui" "$lddlog"
local fail=
AnalyzeLddResult "$lddlog" || fail=x;
CheckQtQuick || fail=x
[ -n "$fail" ] && LibInstallHint
if [ -n "$silent" ]; then
if [ -n "$fail" ]; then
Recho "Serious Problem - installation should be aborted"
AskPermission 'Missing libraries' 'TeamViewer will not be operational without these libraries. Please install them and try again.'
fi
# copy logfiles - make sure they will be included in a ziplog
mkdir -p "$TV_TARIN_LOGDIR"
cp $TV_CHECKLIB_DIR/* "$TV_TARIN_LOGDIR"
fi
echo
}
function isWritableDir()
{
[ -d "$1" ] && [ -w "$1" ] && [ -x "$1" ]
}
function CheckLibDependency()
{
local -r caption="$1"
local -r binary="$2"
local -r logfile="$3"
local -r ld_path="$4" # may be empty
[ -f "$binary" ] || Rdie "unexpected error: file '$binary' not found."
echo "$caption" >> "$logfile"
# force english output for ldd
# set library path (delegate)
LC_ALL='C' \
LD_LIBRARY_PATH="$ld_path" \
ldd "$binary" >> "$logfile" || CheckLddResult "$logfile"
}
function CheckLddResult()
{
local -r lddlogfile="$1"
Recho "An error occurred."
# Check for 'not a dynamic executable'
cat "$lddlogfile" | grep -q dynamic || return
echo "
Your system probably does not support this package type.
Please make sure you picked the proper package for your system
e.g. x86 64bit for Intel/AMD 64 bit,
x86 32bit for Intel/AMD 32 bit,
or armv7 for ARM devices (Raspberry Pi)
"
exit 1
}
function AnalyzeLddResult()
{
local -r lddlogfile="$1"
echo
ABecho "Analyzing dependencies ..."
cat "$lddlogfile" | sort -u | grep 'not found'
local result=$?
if [ $result != 0 ]; then
Gecho "\n\tAll library dependencies (*.so) seem to be satisfied!"
return 0
else
Recho "\n\tThe libraries listed above seem to be missing."
echo -e "\tPlease find and install the corresponding packages.\n\tThen, run this command again."
return 1
fi
}
function CheckQtQuick()
{
if CheckQtQuickControls; then
Gecho "\n\tQtQuickControls seems to be installed"
else
Recho "\n\tQtQuickControls seems to be missing"
return 1
fi
}
function CheckQtQuickControls()
{
ls /usr/lib*/*/qt5/qml/QtQuick/Controls/qmldir &>/dev/null && return # DEB
ls /usr/lib*/qt5/qml/QtQuick/Controls/qmldir &>/dev/null # RPM
}
function LibInstallHint()
{
local -r debCmd=$(debCommand)
local -r rpmCmd=$(rpmCommand)
local -r debGeneral='libdbus-1-3'
local -r debQtBase='libqt5gui5 libqt5widgets5 libqt5qml5 libqt5quick5 libqt5webkit5 libqt5x11extras5'
local -r debQtModule='qml-module-qtquick2 qml-module-qtquick-controls qml-module-qtquick-dialogs qml-module-qtquick-window2 qml-module-qtquick-layouts '
local -r debQtPlugin='qtdeclarative5-qtquick2-plugin qtdeclarative5-controls-plugin qtdeclarative5-dialogs-plugin qtdeclarative5-window-plugin qtdeclarative5-quicklayouts-plugin'
local -r debVarA="$debGeneral $debQtBase $debQtModule"
local -r debVarB="$debGeneral $debQtBase $debQtPlugin"
local -r rpmGeneral='libdbus-1.so.3'
local -r rpmQtBase='libQt5Gui.so.5 libQt5Widgets.so.5 libQt5Qml.so.5 libQt5Quick.so.5 libQt5WebKitWidgets.so.5 libQt5X11Extras.so.5'
local -r rpmQtPlugin='libqtquick2plugin.so libwindowplugin.so libqquicklayoutsplugin.so libqtquickcontrolsplugin.so libdialogplugin.so'
local -r rpm32="$rpmGeneral $rpmQtBase $rpmQtPlugin"
local -r rpm64="$(wordAppend "$rpm32" "()(64bit)'" "'")"
if hasDebSupport; then
PrintLibInstallHint "$debCmd" "$debVarA" && return
PrintLibInstallAlt "$debCmd" "$debVarB" && return
fi
if hasRpmSupport; then
if hasX86_64Support; then
PrintLibInstallHint "$rpmCmd" "$rpm64" && return
elif hasX86_32Support; then
PrintLibInstallHint "$rpmCmd" "$rpm32" && return
elif hasArmhfSupport; then
PrintLibInstallHint "$rpmCmd" "$rpm32" && return
else
echo 'Unexpected architecture'
fi
fi
}
function PrintLibInstallHint()
{
echo -e "\n\tThe following command may be helpful:\n\t \E[1m$1 $2\E[0m\n"
}
function PrintLibInstallAlt()
{
echo -e "\n\tAlternative command (different names):\n\t \E[1m$1 $2\E[0m\n"
}
function hasDebSupport()
{
cmdExists apt-get && return
cmdExists dpkg
}
function hasRpmSupport()
{
cmdExists zypper && return
cmdExists dnf && return
cmdExists yum && return
cmdExists rpm
}
function debCommand()
{
cmdExists apt-get && echo "apt-get install"
}
function rpmCommand()
{
cmdExists zypper && echo "zypper install" && return
cmdExists dnf && echo "dnf install" && return
cmdExists yum && echo "yum install"
}
function wordAppend()
{
local -r list="$1"
local -r appendix="$2"
local -r prefix="$3"
local result=
local word=
for word in $list; do
result="$result$prefix$word$appendix "
done
echo "$result"
}
function InstallTar()
{
local -r un="$1"
InstallTarHead
isSuperUser || Rdie "You need to be root to ${un}install the package"
# only call once during installation. (Don't call on finish or un uninstall/update)
[ -z "$mainParam" ] && [ -z "$un" ] && CheckLibs silent
local -r installDir="$TV_INSTALL_BASE_DIR"
local -r tvwConfig="$installDir/tv_bin/script/tvw_config"
local -r instSetup="$installDir/tv_bin/script/teamviewer_setup"
if [ -n "$un" ]; then # uninstall
PatchSetup
UseInstalledUninstaller
UnInstallTar
else # install
if [ "$mainParam" == 'finish' ]; then
Configure
else
PrepareInstallation
InstallFiles
FinishInstallation
fi
fi
}
function InstallTarHead()
{
if [ -z "$mainForce" ]; then
case "$mainParam" in
( 'update' | 'redir' ) [ -n "$un" ] && return ;; # don't show uninstall header twice (during update/redirected uninstall)
( 'finish' ) [ -z "$un" ] && return ;; # don't show install header during configure
esac
echo
ABecho " -=- TeamViewer tar.xz interactive ${un}installation -=- "
echo
else
[ "$mainForce" = "force" ] || Rdie "Invalid argument: '$mainForce'."
fi
}
function UseInstalledUninstaller()
{
isInstalledTV && return # already installed installer: return and continue
[ -x "$instSetup" ] || Rdie "Can't uninstall package: missing file '$instSetup'."
"$instSetup" uninstall "$mainForce" redir || Rdie 'Failed to uninstall package'
exit
}
function UnInstallTar()
{
local -r uninstMsg='Uninstalling old package...'
local uninstall
UninstallListAdd "$installDir/tv_bin" # must exist if tvwConfig exists
UninstallListAdd "$installDir/doc"
UninstallListAdd "$installDir/logfiles"
UninstallListAdd "$installDir/config"
UninstallListAdd "/usr/bin/teamviewer"
UninstallListAdd "/usr/share/dbus-1/services/$TV_DBUS_FILE_GUI"
UninstallListAdd "/usr/share/dbus-1/services/$TV_DBUS_FILE_DESKTOP"
UninstallListAdd "/usr/share/polkit-1/actions/$TV_POLKIT_FILE"
# UninstallListAdd "/var/log/teamviewer$TV_MAJOR" # don't remove, according to help message
# UninstallListAdd '/etc/teamviewer'
CheckCurrentInstallationType
[ -n "$mainForce" ] && ABecho "$uninstMsg" # print message, even if not asking for permission
AskPermission "$uninstMsg" "These files and directories will be deleted:
$(ls -gd --time-style=+ $uninstall)
"
MakeMenuEntries 'uninstall'
removeDaemon
echo "Removing files...$uninstall"
rm -rf $uninstall || Rdie 'Could not delete files'
if [ "$mainParam" == "update" ]; then
echo
else
Gecho ' Done!'
echo -e ' TeamViewer TAR has been sucessfully removed.'
echo
fi
}
function UninstallListAdd()
{
#expectVariables uninstall
local -r path="$1"
[ -e "$path" ] || return
[ -d "$path" ] && [[ "$path" != '/opt/'* ]] && return
[ -n "$uninstall" ] && uninstall+=' '
uninstall+="$path"
}
function PrepareInstallation()
{
[ -d "$installDir" ] || return
if [ -f "$tvwConfig" ]; then # already installed
CheckCurrentInstallationType
PatchSetup
[ -x "$instSetup" ] || Rdie "Can't uninstall previous package: missing file '$instSetup'."
"$instSetup" uninstall "$mainForce" update || Rdie 'Failed to uninstall previous package'
fi
}
function PatchSetup()
{
(grep -q 'TV_MAJOR=12' $instSetup && grep -q '$TV_DBUS_FILE"' $instSetup && grep -q 'TV_DBUS_FILE_GUI' $instSetup) || return
sed -i -e 's|$TV_DBUS_FILE"|$TV_DBUS_FILE_GUI"|g' $instSetup
}
function FinishInstallation()
{
[ -x "$instSetup" ] || Rdie "Can't finish installation: missing file '$instSetup'."
"$instSetup" install "$mainForce" finish
}
function Configure()
{
InitGlobalSettings # before installDaemon
AskPermission 'Install daemon?' "Note: You can (un)install the daemon at any time.
Commands are explained in 'teamviewer help'" 'return'
[ $? = 0 ] && installDaemon
AskPermission 'Create menu entries?' 'Creates menu entries for your desktop environment.' 'return'
[ $? = 0 ] && MakeMenuEntries 'install'
Gecho ' Done!'
echo -e ' TeamViewer TAR has been sucessfully installed.'
echo -e ' Run \E[1mteamviewer help\E[0m for more information.'
echo
}
function CheckCurrentInstallationType()
{
[ -f "$tvwConfig" ] || die 'internal error'
grep -q 'TV_PKGTYPE=.TAR_IN.' "$tvwConfig" && return # previous TAR installation
grep -q 'TV_PKGTYPE=.TAR_NI.' "$tvwConfig" && return # previous TAR installation failed -> InstallFiles()
Rdie "\tTeamViewer seems to be installed already in '$installDir', but with a different package type ($(source "$tvwConfig"; echo $TV_PKGTYPE)).
Please uninstall DEB/RPM package before trying to install from TAR package."
}
function InstallFiles()
{
local -r binSrc="$TV_BIN_DIR"
local -r docSrc="$TV_BASE_DIR/doc"
local -r lnsDst="$installDir/tv_bin/script"
AskPermission 'Installing files...' "Files will be installed in '$installDir'"
mkdir -p "$installDir" || Rdie "could not create $installDir"
ABecho 'Copying files...'
RenameOldDirs
DirLink "/var/log/teamviewer$TV_MAJOR" "$installDir/logfiles" || Rdie 'fail (InstallFiles)'
DirLink '/etc/teamviewer' "$installDir/config" || Rdie 'fail (InstallFiles)'
ln -s "$lnsDst/teamviewer" '/usr/bin/teamviewer' || Rdie 'fail (InstallFiles)'
ln -s "$lnsDst/$TV_DBUS_FILE_GUI" "/usr/share/dbus-1/services/$TV_DBUS_FILE_GUI" # ignore errors - optional file
ln -s "$lnsDst/$TV_DBUS_FILE_DESKTOP" "/usr/share/dbus-1/services/$TV_DBUS_FILE_DESKTOP" # ignore errors - optional file
ln -s "$lnsDst/$TV_POLKIT_FILE" "/usr/share/polkit-1/actions/$TV_POLKIT_FILE" # ignore errors - optional file
cp -r "$binSrc" "$installDir" || Rdie 'fail (InstallFiles)'
cp -r "$docSrc" "$installDir" || Rdie 'fail (InstallFiles)'
echo -e ' done\n'
sed -i 's/TAR_NI/TAR_IN/g' "$tvwConfig" || Rdie "Could not update '$tvwConfig'"
}
function MakeMenuEntries()
{
local -r param="$1"
local -r dtSrc="$TV_DESKTOP_FILE"
local -r dtName="${dtSrc##*/}"
local -r dtSrcPath="${dtSrc%/$dtName}"
local -r dtDst="/usr/share/applications/$dtName"
if [ "$param" == 'install' ]; then
InstallIconFiles
UpdateIconCache # before installing desktop file
cp -i "$dtSrc" "$dtDst" || die 'MakeMenuEntries failed'
else
InstallIconFiles
rm -f "$dtDst" || die 'MakeMenuEntries failed'
UpdateIconCache
fi
cmdExists update-menus && update-menus
cmdExists update-desktop-database && update-desktop-database
}
function InstallIconFiles()
{
InstallIconFile 16
InstallIconFile 20
InstallIconFile 24
InstallIconFile 32
InstallIconFile 48
InstallIconFile 256
}
function InstallIconFile()
{
#expectVariables dtSrcPath param
local -r px="$1"
local -r iconSource="teamviewer_${px}.png"
local -r sysIconDir="/usr/share/icons/hicolor/${px}x${px}/apps"
local -r sysIconPath="$sysIconDir/TeamViewer.png"
if [ "$param" == 'install' ]; then
mkdir -p $sysIconDir
cp -i $dtSrcPath/$iconSource $sysIconPath
else
[ -f $sysIconPath ] && rm -f $sysIconPath
fi
}
function UpdateIconCache()
{
cmdExists update-icon-caches && update-icon-caches /usr/share/icons/hicolor
cmdExists gtk-update-icon-cache && gtk-update-icon-cache /usr/share/icons/hicolor
}
function DirLink()
{
local -r dir="$1"
local -r lnk="$2"
[ -h "$dir" ] && Rdie 'fail (DirLink)'
[ -d "$dir" ] || mkdir -p "$dir" || Rdie 'fail (DirLink)'
if [ -h "$lnk" ]; then
rm "$lnk" || Rdie 'fail (DirLink)'
fi
ln -s "$dir" "$lnk"
}
function RenameOldDirs()
{
MoveDir '/opt/teamviewer/config' || Rdie 'fail (RenameOldDirs)'
MoveDir '/opt/teamviewer/logfiles' || Rdie 'fail (RenameOldDirs)'
RemoveLink '/etc/teamviewer' || Rdie 'fail (RenameOldDirs)'
}
function MoveDir()
{
local -r name="$1"
local -r newName="$name.old"
local cntName="$newName"
local cnt=0
[ -h "$name" ] && return 0
[ -d "$name" ] || return 0
if [ -e "$newName" ]; then
while [ -e "$cntName" ] ; do
cntName="$newName$((++cnt))"
done
mv "$newName" "$cntName" || return 1
fi
mv "$name" "$newName" || return 1
}
function RemoveLink()
{
local -r name="$1"
[ -h "$name" ] || return 0
rm "$name"
}
function AskPermission()
{
local -r head="$1"
local -r msg="$2"
local -r return="$3"
local msel=
local question=' Continue (y) or abort (n) ? [Y/n]? '
[ -n "$return" ] && question=' Continue (y) or skip (n) ? [Y/n]? '
[ -n "$mainForce" ] && return # don't ask
ABecho "$head"
IndentEcho "$msg" " "
read -n 1 -p "$question" msel
echo -en '\n'
[ -z "$msel" ] && return 0 # default = Y
[ "$msel" = Y ] && return 0
[ "$msel" = y ] && return 0
[ -n "$return" ] && return 1
echo
exit 1 # action was not sucessful, inform calling process
}
TVSetup "$@"