diff options
Diffstat (limited to 'indra/viewer_components/updater/scripts')
| -rw-r--r-- | indra/viewer_components/updater/scripts/linux/update_install | 164 | 
1 files changed, 113 insertions, 51 deletions
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 167e2b7881..0f624c4dee 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -13,78 +13,136 @@  # Copyright (c) 2013, Linden Research, Inc.  # $/LicenseInfo$ +# **************************************************************************** +#   script parameters +# ****************************************************************************  tarball="$1"                        # the file to install  markerfile="$2"                     # create this file on failure  mandatory="$3"                      # what to write to markerfile on failure +# **************************************************************************** +#   helper functions +# **************************************************************************** +# empty array +cleanups=() + +# add a cleanup action to execute on exit +function cleanup { +    # wacky bash syntax for appending to array +    cleanups[${#cleanups[*]}]="$*" +} + +# called implicitly on exit +function onexit { +    for action in "${cleanups[@]}" +    do # don't quote, support actions consisting of multiple words +       $action +    done +} +trap 'onexit' EXIT + +# write to log file  function log {      # our log file will be open as stderr -- but until we set up that      # redirection, logging to stderr is better than nothing      echo "$*" 1>&2  } -function status { -    log "$@" -    # Prefix with '#' so xmenity will recognize it as a status message -    echo "#$*" +# We display status by leaving one background xmessage process running. This +# is the pid of that process. +statuspid="" + +function clear_message { +    [ -n "$statuspid" ] && kill $statuspid +    statuspid=""  } +# make sure we remove any message box we might have put up +cleanup clear_message + +# can we use zenity, or must we fall back to xmessage? +zenpath="$(which zenity)" +if [ -n "$zenpath" ] +then # zenity on PATH and is executable +     # display a message box and continue +     function status { +         # clear any previous message +         clear_message +         # put up a new zenity box and capture its pid +         "$zenpath" --info --title "Second Life Viewer Updater" \ +                    --width=320 --height=120 --text="$*" & +         statuspid=$! +     } + +     # display an error box and wait for user +     function errorbox { +         "$zenpath" --error --title "Second Life Viewer Updater" \ +                    --width=320 --height=120 --text="$*" +     } + +else # no zenity, use xmessage instead +     # display a message box and continue +     function status { +         # clear any previous message +         clear_message +         # put up a new xmessage and capture its pid +         xmessage -buttons OK:2 -center "$*" & +         statuspid=$! +     } + +     # display an error box and wait for user +     function errorbox { +         xmessage -buttons OK:2 -center "$*" +     } +fi + +# display an error box and terminate  function fail {      # Log the message      log "$@"      # tell subsequent viewer things went south      echo "$mandatory" > "$markerfile"      # add boilerplate -    local msg="An error occurred while updating Second Life: +    errorbox "An error occurred while updating Second Life:  $*  Please download the latest viewer from www.secondlife.com." -    # Restate test from xmenity to detect whether we can use zenity or must -    # fall back to xmessage -    zenpath="$(which zenity)" -    if [ -n "$zenpath" -a -x "$zenpath" ] -    then "$zenpath" --error --title "Second Life Viewer Updater" \ -                    --width=320 --height=120 --text="$msg" -    else xmessage -buttons -OK:2 -center "$msg" -    fi      exit 1  } +# Find a graphical sudo program and define mysudo function. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr. +gksudo="$(which gksudo)" +kdesu="$(which kdesu)" +if [ -n "$gksudo" ] +then function mysudo { +         # gksudo allows you to specify description +         err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)" +     } +elif [ -n "$kdesu" ] +then function mysudo { +         err="$("$kdesu" "$@" 2>&1)" +     } +else # couldn't find either one, just try it anyway +     function mysudo { +         err="$("$@" 2>&1)" +     } +fi + +# Move directories, using mysudo if we think it necessary. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr.  function sudo_mv {      # If we have write permission to both parent directories, shouldn't need      # sudo.      if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] -    then mv "$1" "$2" -    else # use one of the likely sudo programs -         sudo="$(which gksudo)" -         if [ -z "$sudo" ] -         then sudo="$(which kdesu)" -         fi -         if [ -z "$sudo" ] -         then # couldn't find either one, just try it anyway -              mv "$1" "$2" -         else # even with sudo, could fail, e.g. different filesystems -              "$sudo" mv "$1" "$2" -         fi +    then err="$(mv "$@" 2>&1)" +    else # use available sudo program; mysudo sets $? and $err +         mysudo mv "$@"      fi  } -# empty array -cleanups=() - -function cleanup { -    # wacky bash syntax for appending to array -    cleanups[${#cleanups[*]}]="$*" -} - -function onexit { -    for action in "${cleanups[@]}" -    do # don't quote, support actions consisting of multiple words -       $action -    done -} - -trap 'onexit' EXIT - +# **************************************************************************** +#   main script logic +# ****************************************************************************  mydir="$(dirname "$0")"  # We happen to know that the viewer specifies a marker-file pathname within  # the logs directory. @@ -97,9 +155,6 @@ logname="$logsdir/updater.log"  # Set up redirections for this script such that stderr is logged. (But first  # move the previous stderr to file descriptor 3.)  exec 3>&2- 2> "$logname" -# Piping to xmenity requires that we end with a line consisting of the string -# "100" to terminate zenity progress bar. -cleanup echo 100  # Rather than setting up a special pipeline to timestamp every line of stderr,  # produce header lines into log file indicating timestamp and the arguments @@ -114,17 +169,19 @@ status 'Installing Second Life...'  # Creating tempdir under /tmp means it's possible that tempdir is on a  # different filesystem than INSTALL_DIR. One is tempted to create tempdir on a -# path derived from `dirname INSTALL_DIR`, but then we might need to add -# another sudo prompt to create it. +# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can +# handle moving across filesystems??  tempdir="/tmp/$(basename "$0").$$"  tempinstall="$tempdir/install" -mkdir -p "$tempinstall" || fail "Couldn't create $tempinstall" +# capture the actual error message, if any +err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err"  cleanup rm -rf "$tempdir"  # If we already knew the name of the tarball's top-level directory, we could  # just move that when all was said and done. Since we don't, untarring to the  # 'install' subdir with --strip 1 effectively renames that top-level  # directory. +# untar failures tend to be voluminous -- don't even try to capture, just log  tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed"  INSTALL_DIR="$(cd "$mydir/.." ; pwd)" @@ -138,16 +195,21 @@ then backup="$INSTALL_DIR.backup"       do backup="$INSTALL_DIR.backup.$backupn"          ((backupn += 1))       done -     sudo_mv "$INSTALL_DIR" "$backup" || fail "Couldn't move $INSTALL_DIR to $backup" +     # on error, fail with actual error message from sudo_mv: permissions, +     # cross-filesystem mv, ...? +     sudo_mv "$INSTALL_DIR" "$backup" || fail "$err"  fi  # We unpacked the tarball into tempinstall. Move that.  if ! sudo_mv "$tempinstall" "$INSTALL_DIR"  then # If we failed to move the temp install to INSTALL_DIR, try to restore -     # INSTALL_DIR from backup +     # INSTALL_DIR from backup. Save $err because next sudo_mv will trash it! +     realerr="$err"       sudo_mv "$backup" "$INSTALL_DIR" -     fail "Couldn't move $1 to $2" +     fail "$realerr"  fi +# Removing the tarball here, rather than with a 'cleanup' action, means we +# only remove it if we succeeded.  rm -f "$tarball"  # Launch the updated viewer. Restore original stderr from file descriptor 3,  | 
