|
#!/bin/sh |
|
|
|
available () { |
|
command -v "$1" >/dev/null 2>&1 |
|
} |
|
|
|
updatedbs () { |
|
# Setup menu entries |
|
if available update-desktop-database; then |
|
update-desktop-database -q /usr/local/share/applications |
|
fi |
|
|
|
# Setup icons |
|
touch -c /usr/local/share/icons/hicolor |
|
if available gtk-update-icon-cache; then |
|
gtk-update-icon-cache -tq /usr/local/share/icons/hicolor |
|
fi |
|
} |
|
|
|
# Uninstall function to be used by the removal script |
|
removefiles () { |
|
while read f; do |
|
# '-e' alone would not find broken symlinks |
|
if [ -e "$f" -o -h "$f" ]; then |
|
if [ -d "$f" ]; then |
|
if ! ls -A "$f" | grep -q ^; then |
|
# Don't remove a symlink pointing to a directory, as it could have |
|
# been created by the user or the distribution |
|
if [ ! -h "$f" ]; then |
|
rmdir -v "$f" |
|
fi |
|
fi |
|
else |
|
rm -v "$f" |
|
fi |
|
fi |
|
done |
|
} # |
|
|
|
# Checks if the same Opera version is already installed |
|
checkversion () { |
|
if [ -e "/usr/local/lib$LIBDIRSUFFIX/$(echo $OPERA_STREAM | sed 's/\-stable//')/VERSION_$OPERA_VERSION" ]; then |
|
echo "$OPERA_STREAM ($OPERA_VERSION) is already installed; exiting" |
|
exit 0 |
|
fi |
|
} |
|
|
|
# Binutils is needed for this script to run |
|
if ! available ar; then |
|
echo "You must install GNU Binutils to use this script" >&2 |
|
exit 1 |
|
fi |
|
|
|
# Quit if you can't write to /usr/local |
|
if [ ! -w "/usr/local" ]; then |
|
echo "You do not have write permission to /usr/local" >&2 |
|
echo "Re-run this script as root or prefaced with sudo, e.g." >&2 |
|
echo " \$ sudo $0 $@" >&2 |
|
exit 1 |
|
fi |
|
|
|
# Check if this is being run as a self extractor |
|
if [ -z "$1" ]; then |
|
if [ $(sed '1,/^exit$/d' "$0" | head -n 1 | wc -l) = "1" ]; then |
|
OPERA_DEB=$(mktemp -t opera-deb.XXXXXX) |
|
sed '1,/^exit$/d' "$0" > "$OPERA_DEB" |
|
DESTROY_DEB=Y |
|
fi |
|
fi |
|
|
|
# Check if automatic download has been selected |
|
while [ 0 ]; do |
|
if [ "$1" = "-d" -o "$1" = "--developer" ]; then |
|
OPERA_STREAM=opera-developer |
|
DESTROY_DEB=Y |
|
shift 1 |
|
elif [ "$1" = "-b" -o "$1" = "--beta" ]; then |
|
OPERA_STREAM=opera-beta |
|
DESTROY_DEB=Y |
|
shift 1 |
|
elif [ "$1" = "-s" -o "$1" = "--stable" ]; then |
|
OPERA_STREAM=opera-stable |
|
DESTROY_DEB=Y |
|
shift 1 |
|
else |
|
break |
|
fi |
|
done |
|
|
|
# Run some checks to see if a proper package has been selected |
|
if [ -z "$DESTROY_DEB" -a -n "$1" ]; then |
|
if ! echo "$1" | grep -q 'opera.*\.deb$'; then |
|
echo "$1 is not named like an Opera Debian package" >&2 |
|
exit 1 |
|
fi |
|
if [ -r "$1" ]; then |
|
OPERA_DEB="$1" |
|
DESTROY_DEB=N |
|
OPERA_AUTO_FETCH=N |
|
fi |
|
fi |
|
|
|
# Extract information from control file |
|
if [ -n "$OPERA_DEB" ]; then |
|
OPERA_STREAM_VERSION_DEBARCH=$(ar -p "$OPERA_DEB" control.tar.gz | tar -xzOf- ./control | sed -n 's/^Package: //p;s/^Version: //p;s/^Architecture: //p') |
|
if [ -z "$OPERA_STREAM_VERSION_DEBARCH" ]; then |
|
echo "Could extract the package name and architecture from the control file" >&2 |
|
exit 1 |
|
else |
|
OPERA_STREAM=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f1) |
|
OPERA_VERSION=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f2) |
|
DEBARCH=$(echo $OPERA_STREAM_VERSION_DEBARCH | cut -d' ' -f3) |
|
fi |
|
|
|
# Set the architecture |
|
case "$DEBARCH" in |
|
amd64) ARCH=x86_64; LIBDIRSUFFIX="64" ;; |
|
*) ARCH=$DEBARCH; LIBDIRSUFFIX="" ;; |
|
esac |
|
|
|
checkversion |
|
else |
|
OPERA_STREAM=${OPERA_STREAM:-opera-stable} |
|
DESTROY_DEB=Y |
|
# Set architecture information |
|
ARCH=$(uname -m | sed 's/i.86/i386/') |
|
case "$ARCH" in |
|
x86_64) DEBARCH=amd64; LIBDIRSUFFIX="64" ;; |
|
i386) DEBARCH=$ARCH; LIBDIRSUFFIX="" ;; |
|
*) echo "The architecture $ARCH is not supported." >&2 ; exit 1 ;; |
|
esac |
|
|
|
# Make sure we have wget or curl |
|
if available wget; then |
|
SILENT_DL="wget -qO-" |
|
LOUD_DL="wget" |
|
DL_OUTPUT="-O" |
|
elif available curl; then |
|
SILENT_DL="curl -s" |
|
LOUD_DL="curl" |
|
DL_OUTPUT="-o" |
|
else |
|
echo "Install wget or curl" >&2 |
|
exit 1 |
|
fi |
|
|
|
# Work out the latest Opera version |
|
OPERA_VERSION=$($SILENT_DL http://deb.opera.com/opera/dists/stable/non-free/binary-$DEBARCH/Packages.gz | gzip -d | grep -A1 -x "Package: $OPERA_STREAM" | sed -n "/Version/s/.* //p") |
|
|
|
# Error out if $OPERA_VERISON is unset, e.g. because previous command failed |
|
if [ -z "$OPERA_VERSION" ]; then |
|
echo "Could not work out the latest version of $OPERA_STREAM for $ARCH; exiting" >&2 |
|
exit 1 |
|
fi |
|
|
|
checkversion |
|
|
|
OPERA_DEB=$(mktemp -t opera-deb.XXXXXX) |
|
$LOUD_DL http://deb.opera.com/opera/pool/non-free/o/$OPERA_STREAM/${OPERA_STREAM}_${OPERA_VERSION}_${DEBARCH}.deb $DL_OUTPUT $OPERA_DEB |
|
if ! [ "$?" = 0 ]; then |
|
echo "Download failed!" >&2 |
|
exit 1 |
|
fi |
|
fi |
|
|
|
# If an old Opera is already installed, remove it first |
|
UNINSTALL_OPERA_SCRIPT=/usr/local/bin/remove-$OPERA_STREAM |
|
if [ -x "$UNINSTALL_OPERA_SCRIPT" ]; then |
|
echo "Removing previously installed Opera first" |
|
sleep 1 |
|
. "$UNINSTALL_OPERA_SCRIPT" |
|
fi |
|
|
|
# Stop the script as soon as there is a problem |
|
set -eu |
|
|
|
# Extract files from the Debian package to a temporary location |
|
OPERA_FILES=$(mktemp -d -t opera-files.XXXXXX) |
|
printf "\nUncompressing Opera ...\n" |
|
ar p "$OPERA_DEB" data.tar.xz | xz -d | tar -xf- -C "$OPERA_FILES" \ |
|
--transform="s,^\./usr,./usr/local,;s,/lib/${ARCH}-linux-gnu,/lib$LIBDIRSUFFIX," \ |
|
--exclude="./usr/share/lintian" --exclude="./usr/share/menu" |
|
|
|
# Create the first part of the uninstall script |
|
mkdir -p "$(dirname $OPERA_FILES/$UNINSTALL_OPERA_SCRIPT)" |
|
sed -n '1,/^} #$/p' "$0" > "$OPERA_FILES/$UNINSTALL_OPERA_SCRIPT" |
|
|
|
# Remove the last part of stable stream name |
|
OPERA_STREAM=$(echo $OPERA_STREAM | sed 's/\-stable//') |
|
|
|
# Record the version number in the package |
|
cd "$OPERA_FILES" |
|
touch usr/local/lib$LIBDIRSUFFIX/$OPERA_STREAM/VERSION_$OPERA_VERSION |
|
|
|
# Finish uninstall script |
|
printf 'set -e\nremovefiles << FILE_LIST\n' >> ".$UNINSTALL_OPERA_SCRIPT" |
|
find . ! -type d ! -print | sed 's,\.,,' | grep -vF "$UNINSTALL_OPERA_SCRIPT" >> ".$UNINSTALL_OPERA_SCRIPT" |
|
find . -depth -type d -print | sed 's,\.,,' | \ |
|
grep -vxE '(^$|/usr(/local(/bin|/lib(64)?|/share(/doc|/man(/man1)?)?)?)?)' >> ".$UNINSTALL_OPERA_SCRIPT" |
|
printf "FILE_LIST\nupdatedbs\nrm -v \"$UNINSTALL_OPERA_SCRIPT\"\n" >> ".$UNINSTALL_OPERA_SCRIPT" |
|
chmod 755 ".$UNINSTALL_OPERA_SCRIPT" |
|
|
|
# Install the files only, *not* directories. |
|
# This avoids changing system directory permissions/ownership |
|
printf "Installing Opera ...\n\n" |
|
find . ! -type d | tar -cf- -T- | tar -xf- -C / |
|
|
|
# Note: Originally I used a cpio instead of a tar pipe but some |
|
# systems might not have cpio installed by default. |
|
# find . ! -type d | cpio --quiet -pmd / |
|
|
|
# Remove temporary files |
|
cd - >/dev/null |
|
rm -r "$OPERA_FILES" |
|
if [ "$DESTROY_DEB" = "Y" ]; then |
|
rm "$OPERA_DEB" |
|
fi |
|
|
|
# Correct the Opera sandbox permissions (not needed if you want to run Opera 29+ and have a Linux kernel of 3.17 or newer) |
|
chmod 4755 /usr/local/lib$LIBDIRSUFFIX/$OPERA_STREAM/opera_sandbox |
|
|
|
# Update the desktop and icons databases |
|
updatedbs |
|
|
|
# And ... we're done! ;) |
|
echo 'Opera was successfully installed into "/usr/local/"'. |
|
printf "\nTo uninstall, issue the following as root (or prefaced with sudo):\n\n" |
|
printf " $UNINSTALL_OPERA_SCRIPT\n\n" |
|
exit |
Read Manual Opera Install Instructions, for a summary of how this script works.