From c8c143e7741d2b93b589d770b64c265228293564 Mon Sep 17 00:00:00 2001
From: Glenn Glazer <coyot@lindenlab.com>
Date: Thu, 18 Aug 2016 13:05:30 -0700
Subject: SL-323: first pass at ripping out old updater

---
 .../updater/scripts/darwin/janitor.py              | 133 -------
 .../updater/scripts/darwin/messageframe.py         |  66 ----
 .../updater/scripts/darwin/update_install.py       | 412 ---------------------
 .../updater/scripts/linux/update_install           | 220 -----------
 .../updater/scripts/windows/update_install.bat     |   3 -
 5 files changed, 834 deletions(-)
 delete mode 100644 indra/viewer_components/updater/scripts/darwin/janitor.py
 delete mode 100644 indra/viewer_components/updater/scripts/darwin/messageframe.py
 delete mode 100755 indra/viewer_components/updater/scripts/darwin/update_install.py
 delete mode 100755 indra/viewer_components/updater/scripts/linux/update_install
 delete mode 100644 indra/viewer_components/updater/scripts/windows/update_install.bat

(limited to 'indra/viewer_components/updater/scripts')

diff --git a/indra/viewer_components/updater/scripts/darwin/janitor.py b/indra/viewer_components/updater/scripts/darwin/janitor.py
deleted file mode 100644
index cdf33df731..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/janitor.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/python
-"""\
-@file   janitor.py
-@author Nat Goodspeed
-@date   2011-09-14
-@brief  Janitor class to clean up arbitrary resources
-
-2013-01-04 cloned from vita because it's exactly what update_install.py needs.
-
-$LicenseInfo:firstyear=2011&license=viewerlgpl$
-Copyright (c) 2011, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import sys
-import functools
-import itertools
-
-class Janitor(object):
-    """
-    Usage:
-
-    Basic:
-    self.janitor = Janitor(sys.stdout) # report cleanup actions on stdout
-    ...
-    self.janitor.later(os.remove, some_temp_file)
-    self.janitor.later(os.remove, some_other_file)
-    ...
-    self.janitor.cleanup()          # perform cleanup actions
-
-    Context Manager:
-    with Janitor() as janitor:      # clean up quietly
-        ...
-        janitor.later(shutil.rmtree, some_temp_directory)
-        ...
-    # exiting 'with' block performs cleanup
-
-    Test Class:
-    class TestMySoftware(unittest.TestCase, Janitor):
-        def __init__(self):
-            Janitor.__init__(self)  # quiet cleanup
-            ...
-
-        def setUp(self):
-            ...
-            self.later(os.rename, saved_file, original_location)
-            ...
-
-        def tearDown(self):
-            Janitor.tearDown(self)  # calls cleanup()
-            ...
-            # Or, if you have no other tearDown() logic for
-            # TestMySoftware, you can omit the TestMySoftware.tearDown()
-            # def entirely and let it inherit Janitor.tearDown().
-    """
-    def __init__(self, stream=None):
-        """
-        If you pass stream= (e.g.) sys.stdout or sys.stderr, Janitor will
-        report its cleanup operations as it performs them. If you don't, it
-        will perform them quietly -- unless one or more of the actions throws
-        an exception, in which case you'll get output on stderr.
-        """
-        self.stream   = stream
-        self.cleanups = []
-
-    def later(self, func, *args, **kwds):
-        """
-        Pass the callable you want to call at cleanup() time, plus any
-        positional or keyword args you want to pass it.
-        """
-        # Get a name string for 'func'
-        try:
-            # A free function has a __name__
-            name = func.__name__
-        except AttributeError:
-            try:
-                # A class object (even builtin objects like ints!) support
-                # __class__.__name__
-                name = func.__class__.__name__
-            except AttributeError:
-                # Shrug! Just use repr() to get a string describing this func.
-                name = repr(func)
-        # Construct a description of this operation in Python syntax from
-        # args, kwds.
-        desc = "%s(%s)" % \
-               (name, ", ".join(itertools.chain((repr(a) for a in args),
-                                                ("%s=%r" % (k, v) for (k, v) in kwds.iteritems()))))
-        # Use functools.partial() to bind passed args and keywords to the
-        # passed func so we get a nullary callable that does what caller
-        # wants.
-        bound = functools.partial(func, *args, **kwds)
-        self.cleanups.append((desc, bound))
-
-    def cleanup(self):
-        """
-        Perform all the actions saved with later() calls.
-        """
-        # Typically one allocates resource A, then allocates resource B that
-        # depends on it. In such a scenario it's appropriate to delete B
-        # before A -- so perform cleanup actions in reverse order. (This is
-        # the same strategy used by atexit().)
-        while self.cleanups:
-            # Until our list is empty, pop the last pair.
-            desc, bound = self.cleanups.pop(-1)
-
-            # If requested, report the action.
-            if self.stream is not None:
-                print >>self.stream, desc
-
-            try:
-                # Call the bound callable
-                bound()
-            except Exception, err:
-                # This is cleanup. Report the problem but continue.
-                print >>(self.stream or sys.stderr), "Calling %s\nraised  %s: %s" % \
-                      (desc, err.__class__.__name__, err)
-
-    def tearDown(self):
-        """
-        If a unittest.TestCase subclass (or a nose test class) adds Janitor as
-        one of its base classes, and has no other tearDown() logic, let it
-        inherit Janitor.tearDown().
-        """
-        self.cleanup()
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, type, value, tb):
-        # Perform cleanup no matter how we exit this 'with' statement
-        self.cleanup()
-        # Propagate any exception from the 'with' statement, don't swallow it
-        return False
diff --git a/indra/viewer_components/updater/scripts/darwin/messageframe.py b/indra/viewer_components/updater/scripts/darwin/messageframe.py
deleted file mode 100644
index 8f58848882..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/messageframe.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/python
-"""\
-@file   messageframe.py
-@author Nat Goodspeed
-@date   2013-01-03
-@brief  Define MessageFrame class for popping up messages from a command-line
-        script.
-
-$LicenseInfo:firstyear=2013&license=viewerlgpl$
-Copyright (c) 2013, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import Tkinter as tk
-import os
-
-# Tricky way to obtain the filename of the main script (default title string)
-import __main__
-
-# This class is intended for displaying messages from a command-line script.
-# Getting the base class right took a bit of trial and error.
-# If you derive from tk.Frame, the destroy() method doesn't actually close it.
-# If you derive from tk.Toplevel, it pops up a separate Tk frame too. destroy()
-# closes this frame, but not that one.
-# Deriving from tk.Tk appears to do the right thing.
-class MessageFrame(tk.Tk):
-    def __init__(self, text="", title=os.path.splitext(os.path.basename(__main__.__file__))[0],
-                 width=320, height=120):
-        tk.Tk.__init__(self)
-        self.grid()
-        self.title(title)
-        self.var = tk.StringVar()
-        self.var.set(text)
-        self.msg = tk.Label(self, textvariable=self.var)
-        self.msg.grid()
-        # from http://stackoverflow.com/questions/3352918/how-to-center-a-window-on-the-screen-in-tkinter :
-        self.update_idletasks()
-
-        # The constants below are to adjust for typical overhead from the
-        # frame borders.
-        xp = (self.winfo_screenwidth()  / 2) - (width  / 2) - 8
-        yp = (self.winfo_screenheight() / 2) - (height / 2) - 20
-        self.geometry('{0}x{1}+{2}+{3}'.format(width, height, xp, yp))
-        self.update()
-
-    def set(self, text):
-        self.var.set(text)
-        self.update()
-
-if __name__ == "__main__":
-    # When run as a script, just test the MessageFrame.
-    import sys
-    import time
-
-    frame = MessageFrame("something in the way she moves....")
-    time.sleep(3)
-    frame.set("smaller")
-    time.sleep(3)
-    frame.set("""this has
-several
-lines""")
-    time.sleep(3)
-    frame.destroy()
-    print "Destroyed!"
-    sys.stdout.flush()
-    time.sleep(3)
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install.py b/indra/viewer_components/updater/scripts/darwin/update_install.py
deleted file mode 100755
index 08f4f0ebb9..0000000000
--- a/indra/viewer_components/updater/scripts/darwin/update_install.py
+++ /dev/null
@@ -1,412 +0,0 @@
-#!/usr/bin/python
-"""\
-@file   update_install.py
-@author Nat Goodspeed
-@date   2012-12-20
-@brief  Update the containing Second Life application bundle to the version in
-        the specified disk image file.
-
-        This Python implementation is derived from the previous mac-updater
-        application, a funky mix of C++, classic C and Objective-C.
-
-$LicenseInfo:firstyear=2012&license=viewerlgpl$
-Copyright (c) 2012, Linden Research, Inc.
-$/LicenseInfo$
-"""
-
-import os
-import sys
-import cgitb
-from contextlib import contextmanager
-import errno
-import glob
-import plistlib
-import re
-import shutil
-import subprocess
-import tempfile
-import time
-from janitor import Janitor
-from messageframe import MessageFrame
-import Tkinter, tkMessageBox
-
-TITLE = "Second Life Viewer Updater"
-# Magic bundle identifier used by all Second Life viewer bundles
-BUNDLE_IDENTIFIER = "com.secondlife.indra.viewer"
-# Magic OS directory name that causes Cocoa viewer to crash on OS X 10.7.5
-# (see MAINT-3331)
-STATE_DIR = os.path.join(
-    os.environ["HOME"], "Library", "Saved Application State",
-    BUNDLE_IDENTIFIER + ".savedState")
-
-# Global handle to the MessageFrame so we can update message
-FRAME = None
-# Global handle to logfile, once it's open
-LOGF  = None
-
-# ****************************************************************************
-#   Logging and messaging
-#
-#   This script is normally run implicitly by the old viewer to update to the
-#   new viewer. Its UI consists of a MessageFrame and possibly a Tk error box.
-#   Log details to updater.log -- especially uncaught exceptions!
-# ****************************************************************************
-def log(message):
-    """write message only to LOGF (also called by status() and fail())"""
-    # If we don't even have LOGF open yet, at least write to Console log
-    logf = LOGF or sys.stderr
-    logf.writelines((time.strftime("%Y-%m-%dT%H:%M:%SZ ", time.gmtime()), message, '\n'))
-    logf.flush()
-
-def status(message):
-    """display and log normal progress message"""
-    log(message)
-
-    global FRAME
-    if not FRAME:
-        FRAME = MessageFrame(message, TITLE)
-    else:
-        FRAME.set(message)
-
-def fail(message):
-    """log message, produce error box, then terminate with nonzero rc"""
-    log(message)
-
-    # If we haven't yet called status() (we don't yet have a FRAME), perform a
-    # bit of trickery to bypass the spurious "main window" that Tkinter would
-    # otherwise pop up if the first call is showerror().
-    if not FRAME:
-        root = Tkinter.Tk()
-        root.withdraw()
-
-    # If we do have a LOGF available, mention it in the error box.
-    if LOGF:
-        message = "%s\n(Updater log in %s)" % (message, LOGF.name)
-
-    # We explicitly specify the WARNING icon because, at least on the Tkinter
-    # bundled with the system-default Python 2.7 on Mac OS X 10.7.4, the
-    # ERROR, QUESTION and INFO icons are all the silly Tk rocket ship. At
-    # least WARNING has an exclamation in a yellow triangle, even though
-    # overlaid by a smaller image of the rocket ship.
-    tkMessageBox.showerror(TITLE,
-"""An error occurred while updating Second Life:
-%s
-Please download the latest viewer from www.secondlife.com.""" % message,
-                           icon=tkMessageBox.WARNING)
-    sys.exit(1)
-
-def exception(err):
-    """call fail() with an exception instance"""
-    fail("%s exception: %s" % (err.__class__.__name__, str(err)))
-
-def excepthook(type, value, traceback):
-    """
-    Store this hook function into sys.excepthook until we have a logfile.
-    """
-    # At least in older Python versions, it could be tricky to produce a
-    # string from 'type' and 'value'. For instance, an OSError exception would
-    # pass type=OSError and value=some_tuple. Empirically, this funky
-    # expression seems to work.
-    exception(type(*value))
-sys.excepthook = excepthook
-
-class ExceptHook(object):
-    """
-    Store an instance of this class into sys.excepthook once we have a logfile
-    open.
-    """
-    def __init__(self, logfile):
-        # There's no magic to the cgitb.enable() function -- it merely stores
-        # an instance of cgitb.Hook into sys.excepthook, passing enable()'s
-        # params into Hook.__init__(). Sadly, enable() doesn't forward all its
-        # params using (*args, **kwds) syntax -- another story. But the point
-        # is that all the goodness is in the cgitb.Hook class. Capture an
-        # instance.
-        self.hook = cgitb.Hook(file=logfile, format="text")
-
-    def __call__(self, type, value, traceback):
-        # produce nice text traceback to logfile
-        self.hook(type, value, traceback)
-        # Now display an error box.
-        excepthook(type, value, traceback)
-
-def write_marker(markerfile, markertext):
-    log("writing %r to %s" % (markertext, markerfile))
-    try:
-        with open(markerfile, "w") as markerf:
-            markerf.write(markertext)
-    except IOError, err:
-        # write_marker() is invoked by fail(), and fail() is invoked by other
-        # error-handling functions. If we try to invoke any of those, we'll
-        # get infinite recursion. If for any reason we can't write markerfile,
-        # try to log it -- otherwise shrug.
-        log("%s exception: %s" % (err.__class__.__name__, err))
-
-# ****************************************************************************
-#   Utility
-# ****************************************************************************
-@contextmanager
-def allow_errno(errn):
-    """
-    Execute body of 'with' statement, accepting OSError with specific errno
-    'errn'. Propagate any other exception, or an OSError with any other errno.
-    """
-    try:
-        # run the body of the 'with' statement
-        yield
-    except OSError, err:
-        # unless errno == passed errn, re-raise the exception
-        if err.errno != errn:
-            raise
-
-# ****************************************************************************
-#   Main script logic
-# ****************************************************************************
-def main(dmgfile, markerfile, markertext):
-    # Should we fail, we're supposed to write 'markertext' to 'markerfile'.
-    # Wrap the fail() function so we do that.
-    global fail
-    oldfail = fail
-    def fail(message):
-        write_marker(markerfile, markertext)
-        oldfail(message)
-
-    try:
-        # Starting with the Cocoafied viewer, we'll find viewer logs in
-        # ~/Library/Application Support/$CFBundleIdentifier/logs rather than in
-        # ~/Library/Application Support/SecondLife/logs as before. This could be
-        # obnoxious -- but we Happen To Know that markerfile is a path specified
-        # within the viewer's logs directory. Use that.
-        logsdir = os.path.dirname(markerfile)
-
-        # Move the old updater.log file out of the way
-        logname = os.path.join(logsdir, "updater.log")
-        # Nonexistence is okay. Anything else, not so much.
-        with allow_errno(errno.ENOENT):
-            os.rename(logname, logname + ".old")
-
-        # Open new updater.log.
-        global LOGF
-        LOGF = open(logname, "w")
-
-        # Now that LOGF is in fact open for business, use it to log any further
-        # uncaught exceptions.
-        sys.excepthook = ExceptHook(LOGF)
-
-        # log how this script was invoked
-        log(' '.join(repr(arg) for arg in sys.argv))
-
-        # prepare for other cleanup
-        with Janitor(LOGF) as janitor:
-
-            # Under some circumstances, this script seems to be invoked with a
-            # nonexistent pathname. Check for that.
-            if not os.path.isfile(dmgfile):
-                fail(dmgfile + " has been deleted")
-
-            # Try to derive the name of the running viewer app bundle from our
-            # own pathname. (Hopefully the old viewer won't copy this script
-            # to a temp dir before running!)
-            # Somewhat peculiarly, this script is currently packaged in
-            # Appname.app/Contents/MacOS with the viewer executable. But even
-            # if we decide to move it to Appname.app/Contents/Resources, we'll
-            # still find Appname.app two levels up from dirname(__file__).
-            appdir = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                                  os.pardir, os.pardir))
-            if not appdir.endswith(".app"):
-                # This can happen if either this script has been copied before
-                # being executed, or if it's in an unexpected place in the app
-                # bundle.
-                fail(appdir + " is not an application directory")
-
-            # We need to install into appdir's parent directory -- can we?
-            installdir = os.path.abspath(os.path.join(appdir, os.pardir))
-            if not os.access(installdir, os.W_OK):
-                fail("Can't modify " + installdir)
-
-            # invent a temporary directory
-            tempdir = tempfile.mkdtemp()
-            log("created " + tempdir)
-            # clean it up when we leave
-            janitor.later(shutil.rmtree, tempdir)
-
-            status("Mounting image...")
-
-            mntdir = os.path.join(tempdir, "mnt")
-            log("mkdir " + mntdir)
-            os.mkdir(mntdir)
-            command = ["hdiutil", "attach", dmgfile, "-mountpoint", mntdir]
-            log(' '.join(command))
-            # Instantiating subprocess.Popen launches a child process with the
-            # specified command line. stdout=PIPE passes a pipe to its stdout.
-            hdiutil = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=LOGF)
-            # Popen.communicate() reads that pipe until the child process
-            # terminates, returning (stdout, stderr) output. Select just stdout.
-            hdiutil_out = hdiutil.communicate()[0]
-            if hdiutil.returncode != 0:
-                fail("Couldn't mount " + dmgfile)
-            # hdiutil should report the devnode. Find that.
-            found = re.search(r"/dev/[^ ]*\b", hdiutil_out)
-            if not found:
-                # If we don't spot the devnode, log it and continue -- we only
-                # use it to detach it. Don't fail the whole update if we can't
-                # clean up properly.
-                log("Couldn't spot devnode in hdiutil output:\n" + hdiutil_out)
-            else:
-                # If we do spot the devnode, detach it when done.
-                janitor.later(subprocess.call, ["hdiutil", "detach", found.group(0)],
-                              stdout=LOGF, stderr=subprocess.STDOUT)
-
-            status("Searching for app bundle...")
-
-            for candidate in glob.glob(os.path.join(mntdir, "*.app")):
-                log("Considering " + candidate)
-                try:
-                    # By convention, a valid Mac app bundle has a
-                    # Contents/Info.plist file containing at least
-                    # CFBundleIdentifier.
-                    CFBundleIdentifier = \
-                        plistlib.readPlist(os.path.join(candidate, "Contents",
-                                                        "Info.plist"))["CFBundleIdentifier"]
-                except Exception, err:
-                    # might be IOError, xml.parsers.expat.ExpatError, KeyError
-                    # Any of these means it's not a valid app bundle. Instead
-                    # of aborting, just skip this candidate and continue.
-                    log("%s not a valid app bundle: %s: %s" %
-                        (candidate, err.__class__.__name__, err))
-                    continue
-
-                if CFBundleIdentifier == BUNDLE_IDENTIFIER:
-                    break
-
-                log("unrecognized CFBundleIdentifier: " + CFBundleIdentifier)
-
-            else:
-                fail("Could not find Second Life viewer in " + dmgfile)
-
-            # Here 'candidate' is the new viewer to install
-            log("Found " + candidate)
-
-            # This logic was changed to make Mac updates behave more like
-            # Windows. Most of the time, the user doesn't change the name of
-            # the app bundle on our .dmg installer (e.g. "Second Life Beta
-            # Viewer.app"). Most of the time, the version manager directs a
-            # given viewer to update to another .dmg containing an app bundle
-            # with THE SAME name. In that case, everything behaves as usual.
-
-            # The case that was changed is when the version manager offers (or
-            # mandates) an update to a .dmg containing a different app bundle
-            # name. This can happen, for instance, to a user who's downloaded
-            # a "project beta" viewer, and the project subsequently publishes
-            # a Release Candidate viewer. Say the project beta's app bundle
-            # name is something like "Second Life Beta Neato.app". Anyone
-            # launching that viewer will be offered an update to the
-            # corresponding Release Candidate viewer -- which will be built as
-            # a release viewer, with app bundle name "Second Life Viewer.app".
-
-            # On Windows, we run the NSIS installer, which will update/replace
-            # the embedded install directory name, e.g. Second Life Viewer.
-            # But the Mac installer used to locate the app bundle name in the
-            # mounted .dmg file, then ignore that name, copying its contents
-            # into the app bundle directory of the running viewer. That is,
-            # we'd install the Release Candidate from the .dmg's "Second
-            # Life.app" into "/Applications/Second Life Beta Neato.app". This
-            # is undesired behavior.
-
-            # Instead, having found the app bundle name on the mounted .dmg,
-            # we try to install that app bundle name into the parent directory
-            # of the running app bundle.
-
-            # Are we installing a different app bundle name? If so, call it
-            # out, both in the log and for the user -- this is an odd case.
-            # (Presumably they've already agreed to a similar notification in
-            # the viewer before the viewer launched this script, but still.)
-            bundlename = os.path.basename(candidate)
-            if os.path.basename(appdir) == bundlename:
-                # updating the running app bundle, which we KNOW exists
-                appexists = True
-            else:
-                # installing some other app bundle
-                newapp = os.path.join(installdir, bundlename)
-                appexists = os.path.exists(newapp)
-                message = "Note: %s %s %s" % \
-                          (appdir, "updating" if appexists else "installing new", newapp)
-                status(message)
-                # okay, we have no further need of the name of the running app
-                # bundle.
-                appdir = newapp
-
-            status("Preparing to copy files...")
-
-            if appexists:
-                # move old viewer to temp location in case copy from .dmg fails
-                aside = os.path.join(tempdir, os.path.basename(appdir))
-                log("mv %r %r" % (appdir, aside))
-                # Use shutil.move() instead of os.rename(). move() first tries
-                # os.rename(), but falls back to shutil.copytree() if the dest is
-                # on a different filesystem.
-                shutil.move(appdir, aside)
-
-            status("Copying files...")
-
-            # shutil.copytree()'s target must not already exist. But we just
-            # moved appdir out of the way.
-            log("cp -p %r %r" % (candidate, appdir))
-            try:
-                # The viewer app bundle does include internal symlinks. Keep them
-                # as symlinks.
-                shutil.copytree(candidate, appdir, symlinks=True)
-            except Exception, err:
-                # copy failed -- try to restore previous viewer before crumping
-                type, value, traceback = sys.exc_info()
-                if appexists:
-                    log("exception response: mv %r %r" % (aside, appdir))
-                    shutil.move(aside, appdir)
-                # let our previously-set sys.excepthook handle this
-                raise type, value, traceback
-
-            status("Cleaning up...")
-
-            log("touch " + appdir)
-            os.utime(appdir, None)      # set to current time
-
-            # MAINT-3331: remove STATE_DIR. Empirically, this resolves a
-            # persistent, mysterious crash after updating our viewer on an OS
-            # X 10.7.5 system.
-            log("rm -rf '%s'" % STATE_DIR)
-            with allow_errno(errno.ENOENT):
-                shutil.rmtree(STATE_DIR)
-
-            command = ["open", appdir]
-            log(' '.join(command))
-            subprocess.check_call(command, stdout=LOGF, stderr=subprocess.STDOUT)
-
-        # If all the above succeeded, delete the .dmg file. We don't do this
-        # as a janitor.later() operation because we only want to do it if we
-        # get this far successfully. Note that this is out of the scope of the
-        # Janitor: we must detach the .dmg before removing it!
-        log("rm " + dmgfile)
-        os.remove(dmgfile)
-
-    except Exception, err:
-        # Because we carefully set sys.excepthook -- and even modify it to log
-        # the problem once we have our log file open -- you might think we
-        # could just let exceptions propagate. But when we do that, on
-        # exception in this block, we FIRST restore the no-side-effects fail()
-        # and THEN implicitly call sys.excepthook(), which calls the (no-side-
-        # effects) fail(). Explicitly call sys.excepthook() BEFORE restoring
-        # fail(). Only then do we get the enriched fail() behavior.
-        sys.excepthook(*sys.exc_info())
-
-    finally:
-        # When we leave main() -- for whatever reason -- reset fail() the way
-        # it was before, because the bound markerfile, markertext params
-        # passed to this main() call are no longer applicable.
-        fail = oldfail
-
-if __name__ == "__main__":
-    # We expect this script to be invoked with:
-    # - the pathname to the .dmg we intend to install;
-    # - the pathname to an update-error marker file to create on failure;
-    # - the content to write into the marker file.
-    main(*sys.argv[1:])
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
deleted file mode 100755
index 03089f192e..0000000000
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ /dev/null
@@ -1,220 +0,0 @@
-#! /bin/bash
-
-# @file   update_install
-# @author Nat Goodspeed
-# @date   2013-01-09
-# @brief  Update the containing Second Life application bundle to the version in
-#         the specified tarball.
-# 
-#         This bash implementation is derived from the previous linux-updater.bin
-#         application.
-# 
-# $LicenseInfo:firstyear=2013&license=viewerlgpl$
-# 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
-}
-
-# 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="$*" &
-         # MAINT-2333: use bouncing progress bar
-         "$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
-                    --width=320 --height=120 --text "$*" </dev/null &
-         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
-    errorbox "An error occurred while updating Second Life:
-$*
-Please download the latest viewer from www.secondlife.com."
-    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 err="$(mv "$@" 2>&1)"
-    else # use available sudo program; mysudo sets $? and $err
-         mysudo mv "$@"
-    fi
-}
-
-# ****************************************************************************
-#   main script logic
-# ****************************************************************************
-mydir="$(dirname "$0")"
-# We happen to know that the viewer specifies a marker-file pathname within
-# the logs directory.
-logsdir="$(dirname "$markerfile")"
-logname="$logsdir/updater.log"
-
-# move aside old updater.log; we're about to create a new one
-[ -f "$logname" ] && mv "$logname" "$logname.old"
-
-# 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"
-
-# Rather than setting up a special pipeline to timestamp every line of stderr,
-# produce header lines into log file indicating timestamp and the arguments
-# with which we were invoked.
-date 1>&2
-log "$0 $*"
-
-# Log every command we execute, along with any stderr it might produce
-set -x
-
-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 it seems modern 'mv' can
-# handle moving across filesystems??
-tempdir="$(mktemp -d)"
-tempinstall="$tempdir/install"
-# 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)"
-
-# Considering we're launched from a subdirectory of INSTALL_DIR, would be
-# surprising if it did NOT already exist...
-if [ -e "$INSTALL_DIR" ]
-then backup="$INSTALL_DIR.backup"
-     backupn=1
-     while [ -e "$backup" ]
-     do backup="$INSTALL_DIR.backup.$backupn"
-        ((backupn += 1))
-     done
-     # 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. Save $err because next sudo_mv will trash it!
-     realerr="$err"
-     sudo_mv "$backup" "$INSTALL_DIR"
-     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,
-# though -- otherwise updater.log gets cluttered with the viewer log!
-"$INSTALL_DIR/secondlife" 2>&3- &
diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
deleted file mode 100644
index 96687226a8..0000000000
--- a/indra/viewer_components/updater/scripts/windows/update_install.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-start /WAIT %1 /SKIP_DIALOGS
-IF ERRORLEVEL 1 ECHO %3 > %2
-DEL %1
-- 
cgit v1.2.3