From e48c70392cffb047c7471221b7c6fcbf32d41d06 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 30 Mar 2016 11:41:29 -0700 Subject: [PATCH 001/183] SL-321: prototype python launcher --- indra/newview/CMakeLists.txt | 2 + indra/newview/Info-SecondLife.plist | 2 +- indra/newview/viewer_manifest.py | 14 +------ indra/viewer_components/manager/SL_Launcher | 41 +++++++++++++++++++++ 4 files changed, 46 insertions(+), 13 deletions(-) create mode 100755 indra/viewer_components/manager/SL_Launcher diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 05483c4608..3056b5d749 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2051,6 +2051,8 @@ endif (LINUX) if (DARWIN) # These all get set with PROPERTIES set(product "Second Life") + # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist + set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher") set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer") set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns") set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer") diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 9b8136a827..8aabd6818b 100755 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} + ${MACOSX_WRAPPER_EXECUTABLE_NAME} CFBundleGetInfoString ${MACOSX_BUNDLE_INFO_STRING} CFBundleIconFile diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f7992dba90..60042706e4 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -703,6 +703,8 @@ class Darwin_i386_Manifest(ViewerManifest): if self.prefix(dst="MacOS"): self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") + #this copies over the python wrapper script, see SL-322 + self.path2basename("../viewer_components/manager","SL_Launcher") self.end_prefix() # most everything goes in the Resources directory @@ -885,12 +887,6 @@ class Darwin_i386_Manifest(ViewerManifest): self.run_command('strip -S %(viewer_binary)r' % { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')}) - def copy_finish(self): - # Force executable permissions to be set for scripts - # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 - for script in 'Contents/MacOS/update_install.py',: - self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) - def package_finish(self): global CHANNEL_VENDOR_BASE # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning. @@ -1091,12 +1087,6 @@ class LinuxManifest(ViewerManifest): self.path("featuretable_linux.txt") - def copy_finish(self): - # Force executable permissions to be set for scripts - # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 - for script in 'secondlife', 'bin/update_install': - self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script)) - def package_finish(self): installer_name = self.installer_base_name() diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher new file mode 100755 index 0000000000..3c5d45d6e5 --- /dev/null +++ b/indra/viewer_components/manager/SL_Launcher @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +import argparse +import os +import sys +import subprocess +import Tkinter as tk + +viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),"Second Life") + +#to prove we are launching from the script, launch a Tkinter window first +root = tk.Tk() +w = tk.Label(root, text=viewer_binary) +w.pack() +root.after(10000, lambda: root.destroy()) # Destroy the widget after 10 seconds +root.mainloop() + +parser = argparse.ArgumentParser() +#parser.add_argument('--f', action='store_const', const=42) +args = parser.parse_known_args(sys.argv) +args_list_to_pass = args[1][1:] +args_list_to_pass.insert(0,viewer_binary) +#print args_list_to_pass + +viewer_process = subprocess.Popen(args_list_to_pass) \ No newline at end of file From c1951b49a6e6f625a4b5894313f98f57443b94c8 Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC" Date: Thu, 7 Apr 2016 16:04:24 +0100 Subject: [PATCH 002/183] SL-321: Changes for VMP Windows Prototype --- indra/newview/CMakeLists.txt | 16 ++++++++ .../installers/windows/installer_template.nsi | 10 ++--- indra/newview/viewer_manifest.py | 4 +- indra/viewer_components/manager/SL_Launcher | 40 ++++++++++++++----- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3056b5d749..c81de43068 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1782,6 +1782,22 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll ) endif (FMODEX) + + get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY) + + # http://pythonhosted.org/PyInstaller/#options + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SL_Launcher.exe + COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe + ARGS + --onefile + --log-level WARN + --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher + COMMENT "Performing pyinstaller compile of SL_Launcher" + ) + + add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index b8677fd9e4..d833af8742 100755 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -276,7 +276,7 @@ StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT" SetOutPath "$INSTDIR" CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \ @@ -294,15 +294,15 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ # Other shortcuts SetOutPath "$INSTDIR" CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ '"$INSTDIR\uninst.exe"' '' -# Create *.bat file to specify lang params on first run from installer - see MAINT-5259 +# Create *.bat file to specify lang params on first run from installer - see MAINT-5259S FileOpen $9 "$INSTDIR\autorun.bat" w -FileWrite $9 'start "$INSTDIR\$INSTEXE" "$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM$\r$\n' +FileWrite $9 'start "$INSTDIR\$INSTEXE" /d "$INSTDIR" "$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM$\r$\n' FileClose $9 # Write registry diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 60042706e4..f56dcd3f34 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -338,6 +338,8 @@ class Windows_i686_Manifest(ViewerManifest): if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) + # include the compiled launcher script so that it gets included in the file_list + self.path(src='%s/SL_Launcher.exe' % self.args['configuration'], dst="SL_Launcher.exe") # Plugin host application self.path2basename(os.path.join(os.pardir, @@ -611,7 +613,7 @@ class Windows_i686_Manifest(ViewerManifest): substitution_strings['installer_file'] = installer_file version_vars = """ - !define INSTEXE "%(final_exe)s" + !define INSTEXE "SL_Launcher.exe" !define VERSION "%(version_short)s" !define VERSION_LONG "%(version)s" !define VERSION_DASHES "%(version_dashes)s" diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 3c5d45d6e5..fb07d3b991 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -22,7 +22,36 @@ import sys import subprocess import Tkinter as tk -viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),"Second Life") +parser = argparse.ArgumentParser() +#parser.add_argument('--f', action='store_const', const=42) +args = parser.parse_known_args(sys.argv) +args_list_to_pass = args[1][1:] +args_list_to_pass.insert(0,viewer_binary) +#print "COYOT: arrrrrghs to pass", args_list_to_pass + +cwd = os.path.dirname(os.path.realpath(__file__)) + +executable_name = "" +if sys.platform.startswith('darwin'): + executable_name = "Second Life" +elif sys.platform.startswith("win") or sys.platform.startswith("cyg"): + if os.path.isfile(os.path.join(cwd,"SecondLifeViewer.exe")): + executable_name = "SecondLifeViewer.exe" + elif os.path.isfile(os.path.join(cwd,"SecondLifeTest.exe")): + executable_name = "SecondLifeTest.exe" + else: + #unsupported by prototypeS + sys.exit("Can't find Windows viewer binary") +elif sys.platform.startswith("linux"): + executable_name = "secondlife" +else: + #SL doesn't run on VMS or punch cards + sys.exit("Unsupported platform") + +#print "COYOT: executable name ", executable_name +#print "COYOT: path ", os.path.dirname(os.path.abspath(sys.argv[0])) + +viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name) #to prove we are launching from the script, launch a Tkinter window first root = tk.Tk() @@ -31,11 +60,4 @@ w.pack() root.after(10000, lambda: root.destroy()) # Destroy the widget after 10 seconds root.mainloop() -parser = argparse.ArgumentParser() -#parser.add_argument('--f', action='store_const', const=42) -args = parser.parse_known_args(sys.argv) -args_list_to_pass = args[1][1:] -args_list_to_pass.insert(0,viewer_binary) -#print args_list_to_pass - -viewer_process = subprocess.Popen(args_list_to_pass) \ No newline at end of file +viewer_process = subprocess.Popen(args_list_to_pass) From 0494a502aafac73800352dc26c4eb3a27b02a8ce Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 7 Apr 2016 12:08:33 -0700 Subject: [PATCH 003/183] fix tabs --- indra/newview/CMakeLists.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c81de43068..d3b4057c8c 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1786,18 +1786,18 @@ if (WINDOWS) get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY) # http://pythonhosted.org/PyInstaller/#options - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SL_Launcher.exe - COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe - ARGS - --onefile - --log-level WARN - --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher - COMMENT "Performing pyinstaller compile of SL_Launcher" - ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SL_Launcher.exe + COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe + ARGS + --onefile + --log-level WARN + --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher + COMMENT "Performing pyinstaller compile of SL_Launcher" +) - add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) +add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat From 41fa1e31581f716296f4616de4312f4bd17514f1 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 5 Apr 2016 13:50:16 -0400 Subject: [PATCH 004/183] upgrade llphysicsextenstions to work around a new clang recursion check --- autobuild.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6c29d5cb18..43bad77d25 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1528,11 +1528,11 @@ archive hash - 468e88a527e610804c3eecf07f4ed70b + 01a7cc9d0e56238a9abedd7a41ccd0a3 hash_algorithm md5 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source_llphysicsextensions-update/rev/298369/arch/Darwin/installer/llphysicsextensions_source-1.0.298369-darwin-298369.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/Darwin/installer/llphysicsextensions_source-1.0.313564-darwin-313564.tar.bz2 name darwin @@ -1542,9 +1542,9 @@ archive hash - 793964e49c935b414c4bdbb8a0d14ad1 + c94dc7ab6efe59c0d5d04fc447257c57 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source_llphysicsextensions-update/rev/298369/arch/Linux/installer/llphysicsextensions_source-1.0.298369-linux-298369.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/Linux/installer/llphysicsextensions_source-1.0.313564-linux-313564.tar.bz2 name linux @@ -1554,16 +1554,16 @@ archive hash - 922aad5261aac150e5ce3c094e57f373 + 4a9dbeb437d0e1546b93d16073ff1442 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source_llphysicsextensions-update/rev/298369/arch/CYGWIN/installer/llphysicsextensions_source-1.0.298369-windows-298369.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions/rev/313564/arch/CYGWIN/installer/llphysicsextensions_source-1.0.313564-windows-313564.tar.bz2 name windows version - 1.0.298369 + 1.0.313564 llphysicsextensions_stub @@ -1582,11 +1582,11 @@ archive hash - 1175977a191ffc936fd0ccca433c8278 + c8c6e5867d1ead7ad452a3359b22cf44 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub_llphysicsextensions-update/rev/298370/arch/Darwin/installer/llphysicsextensions_stub-1.0.298370-darwin-298370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/Darwin/installer/llphysicsextensions_stub-1.0.313563-darwin-313563.tar.bz2 name darwin @@ -1596,9 +1596,9 @@ archive hash - d13d7927692eab2d6a63e36166b72a8a + e99afb25a4fd5b08c5cd3060ae9c1d59 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub_llphysicsextensions-update/rev/298370/arch/Linux/installer/llphysicsextensions_stub-1.0.298370-linux-298370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/Linux/installer/llphysicsextensions_stub-1.0.313563-linux-313563.tar.bz2 name linux @@ -1608,16 +1608,16 @@ archive hash - 9594f6fd79ee924fe675a4a23e30516e + 6f4307a35c692e44b872125d7932df8e url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub_llphysicsextensions-update/rev/298370/arch/CYGWIN/installer/llphysicsextensions_stub-1.0.298370-windows-298370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions/rev/313563/arch/CYGWIN/installer/llphysicsextensions_stub-1.0.313563-windows-313563.tar.bz2 name windows version - 1.0.298370 + 1.0.313563 mesa From db2fdaf469613a366dd2b469ebbf0d2f979c2ef5 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 8 Apr 2016 08:52:15 -0700 Subject: [PATCH 005/183] compiler shift fix --- indra/llkdu/llimagej2ckdu.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 6a8959517d..72919c9c40 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1034,7 +1034,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (kdu_int32)(sp->fval*scale16); val = (val+128)>>8; // May be faster than true rounding val += 128; - if (val & ((-1)<<8)) + if (val & (((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1052,7 +1052,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1075,7 +1075,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val += (1<<(KDU_FIX_POINT-8))>>1; val >>= (KDU_FIX_POINT-8); val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1094,7 +1094,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (val+offset)>>downshift; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1<ival; val = (val+offset)>>downshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } @@ -1132,7 +1132,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = sp->ival; val <<= upshift; val += 128; - if (val & ((-1)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 256 - (1< Date: Fri, 8 Apr 2016 09:57:18 -0700 Subject: [PATCH 006/183] fix paren --- indra/llkdu/llimagej2ckdu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 72919c9c40..282c859e9e 100755 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -1034,7 +1034,7 @@ all necessary level shifting, type conversion, rounding and truncation. */ val = (kdu_int32)(sp->fval*scale16); val = (val+128)>>8; // May be faster than true rounding val += 128; - if (val & (((0xffffffffU)<<8)) + if (val & ((0xffffffffU)<<8)) { val = (val < 0 ? 0 : 255); } From 23863db4144fa72868f3712b8e798fea882b0cb6 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 8 Apr 2016 10:26:33 -0700 Subject: [PATCH 007/183] SL-321: move arg parsing past platform discovery --- indra/viewer_components/manager/SL_Launcher | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index fb07d3b991..e715546821 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -22,13 +22,6 @@ import sys import subprocess import Tkinter as tk -parser = argparse.ArgumentParser() -#parser.add_argument('--f', action='store_const', const=42) -args = parser.parse_known_args(sys.argv) -args_list_to_pass = args[1][1:] -args_list_to_pass.insert(0,viewer_binary) -#print "COYOT: arrrrrghs to pass", args_list_to_pass - cwd = os.path.dirname(os.path.realpath(__file__)) executable_name = "" @@ -53,6 +46,13 @@ else: viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name) +parser = argparse.ArgumentParser() +#parser.add_argument('--f', action='store_const', const=42) +args = parser.parse_known_args(sys.argv) +args_list_to_pass = args[1][1:] +args_list_to_pass.insert(0,viewer_binary) +#print "COYOT: arrrrrghs to pass", args_list_to_pass + #to prove we are launching from the script, launch a Tkinter window first root = tk.Tk() w = tk.Label(root, text=viewer_binary) From a670914c6d43dcde0677680375f53f8a67a89cf6 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 11 Apr 2016 07:36:19 -0700 Subject: [PATCH 008/183] fix unused variable compiler error --- indra/newview/llmaniprotate.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index ed40483029..3a0f96cd37 100755 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -67,9 +67,6 @@ const F32 RADIUS_PIXELS = 100.f; // size in screen space const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS; const F32 WIDTH_PIXELS = 8; const S32 CIRCLE_STEPS = 100; -const F32 DELTA = F_TWO_PI / CIRCLE_STEPS; -const F32 SIN_DELTA = sin( DELTA ); -const F32 COS_DELTA = cos( DELTA ); const F32 MAX_MANIP_SELECT_DISTANCE = 100.f; const F32 SNAP_ANGLE_INCREMENT = 5.625f; const F32 SNAP_ANGLE_DETENTE = SNAP_ANGLE_INCREMENT; From c68def40b15c3f2a24f9ea6f5703a3513875f608 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 23 May 2016 10:31:09 -0700 Subject: [PATCH 009/183] debug print statement to be removed later --- indra/newview/viewer_manifest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2c694132ea..d91faddb1a 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -116,6 +116,7 @@ class ViewerManifest(LLManifest): settings_install['CmdLineChannel'] = settings_template['CmdLineChannel'].copy() settings_install['CmdLineChannel']['Value'] = self.channel_with_pkg_suffix() print "Set CmdLineChannel in settings_install.xml to '%s'" % self.channel_with_pkg_suffix() + print "COYOT: channel set or not: %s" % self.channel_with_pkg_suffix() if 'grid' in self.args and self.args['grid']: settings_install['CmdLineGridChoice'] = settings_template['CmdLineGridChoice'].copy() From 9908fcf4ac43537728d1b34e30650735cfb36147 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 25 May 2016 07:51:58 -0700 Subject: [PATCH 010/183] Backed out changeset 9adcab4d611b --- indra/newview/viewer_manifest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index d91faddb1a..2c694132ea 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -116,7 +116,6 @@ class ViewerManifest(LLManifest): settings_install['CmdLineChannel'] = settings_template['CmdLineChannel'].copy() settings_install['CmdLineChannel']['Value'] = self.channel_with_pkg_suffix() print "Set CmdLineChannel in settings_install.xml to '%s'" % self.channel_with_pkg_suffix() - print "COYOT: channel set or not: %s" % self.channel_with_pkg_suffix() if 'grid' in self.args and self.args['grid']: settings_install['CmdLineGridChoice'] = settings_template['CmdLineGridChoice'].copy() From 8bee0a61a5bd70183ace8ae6207f626d17875d51 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 16 Jun 2016 09:04:19 -0700 Subject: [PATCH 011/183] SL-407: create Tkinter UI --- .../manager/InstallerUserMessage.py | 258 ++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 indra/viewer_components/manager/InstallerUserMessage.py diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py new file mode 100644 index 0000000000..bef2bf28a6 --- /dev/null +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -0,0 +1,258 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +""" +@file InstallerUserMessage.py +@author coyot +@date 2016-05-16 +""" + +""" +This does everything the old updater/scripts/darwin/messageframe.py script did and some more bits. +Pushed up the manager directory to be multiplatform. +""" + +import os +import Queue +import threading +import time +import Tkinter as tk +import ttk + + +class InstallerUserMessage(tk.Tk): + #Goals for this class: + # Provide a uniform look and feel + # Provide an easy to use convenience class for other scripts + # Provide windows that automatically disappear when done (for differing notions of done) + # Provide a progress bar that isn't a glorified spinner, but based on download progress + #Non-goals: + # No claim to threadsafety is made or warranted. Your mileage may vary. + # Please consult a doctor if you experience thread pain. + def __init__(self, text="", title="", width=500, height=200, fillcolor='#487A7B', *args, **kwargs): + tk.Tk.__init__(self) + self.grid() + self.title(title) + self.choice = tk.BooleanVar() + self.config(background = 'black') + # background="..." doesn't work on MacOS for radiobuttons or progress bars + # http://tinyurl.com/tkmacbuttons + ttk.Style().configure('Linden.TLabel', foreground='#487A7B', background='black') + ttk.Style().configure('Linden.TButton', foreground='#487A7B', background='black') + ttk.Style().configure("black.Horizontal.TProgressbar", foreground='#487A7B', background='black') + + # The constants below are to adjust for typical overhead from the + # frame borders. + self.xp = (self.winfo_screenwidth() / 2) - (width / 2) - 8 + self.yp = (self.winfo_screenheight() / 2) - (height / 2) - 20 + self.geometry('{0}x{1}+{2}+{3}'.format(width, height, self.xp, self.yp)) + self.script_dir = os.path.dirname(os.path.realpath(__file__)) + self.icon_dir = os.path.abspath(os.path.join(self.script_dir, 'icons')) + #defines what to do when window is closed + self.protocol("WM_DELETE_WINDOW", self._delete_window) + + def _delete_window(self): + #capture and discard all destroy events before the choice is set + if not ((self.choice == None) or (self.choice == "")): + try: + self.destroy() + except: + #tk may try to destroy the same object twice + pass + + def set_colors(self, widget): + # #487A7B is "Linden Green" + widget.config(foreground = '#487A7B') + widget.config(background='black') + + def find_icon(self, icon_path = None, icon_name = None): + #we do this in each message, let's do it just once instead. + if not icon_path: + icon_path = self.icon_dir + icon_path = os.path.join(icon_path, icon_name) + if os.path.exists(icon_path): + icon = tk.PhotoImage(file=icon_path) + self.image_label = tk.Label(image = icon) + self.image_label.image = icon + else: + #default to text if image not available + self.image_label = tk.Label(text = "Second Life") + + def auto_resize(self, row_count = 0, column_count = 0, heavy_row = None, heavy_column = None): + #auto resize window to fit all rows and columns + #"heavy" gets extra weight + for x in range(column_count): + if x == heavy_column: + self.columnconfigure(x, weight = 2) + else: + self.columnconfigure(x, weight=1) + + for y in range(row_count): + if y == heavy_row: + self.rowconfigure(y, weight = 2) + else: + self.rowconfigure(x, weight=1) + + def basic_message(self, message, icon_path = None, icon_name = None): + #message: text to be displayed + #icon_path: directory holding the icon, defaults to icons subdir of script dir + #icon_name: filename of icon to be displayed + self.choice.set(True) + self.find_icon(icon_path, icon_name) + self.text_label = tk.Label(text = message) + self.set_colors(self.text_label) + self.set_colors(self.image_label) + #pad, direction and weight are all experimentally derived by retrying various values + self.image_label.grid(row = 1, column = 1, sticky = 'W') + self.text_label.grid(row = 1, column = 2, sticky = 'W', padx =100) + self.auto_resize(1, 2) + self.mainloop() + + def binary_choice_message(self, message, icon_path = None, icon_name = None, one = 'Yes', two = 'No'): + #one: first option, returns True + #two: second option, returns False + #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice + #usage: + # frame = InstallerUserMessage.InstallerUserMessage( ... ) + # frame = frame.binary_choice_message( ... ) + # (wait for user to click) + # value = frame.choice.get() + self.find_icon(icon_path, icon_name) + self.text_label = tk.Label(text = message) + #command registers the callback to the method named. We want the frame to go away once clicked. + #button 1 returns True/1, button 2 returns False/0 + self.button_one = ttk.Radiobutton(text = one, variable = self.choice, value = True, + command = self._delete_window, style = 'Linden.TButton') + self.button_two = ttk.Radiobutton(text = two, variable = self.choice, value = False, + command = self._delete_window, style = 'Linden.TButton') + self.set_colors(self.text_label) + self.set_colors(self.image_label) + #pad, direction and weight are all experimentally derived by retrying various values + self.image_label.grid(row = 1, column = 1, rowspan = 3, sticky = 'W') + self.text_label.grid(row = 1, column = 2, rowspan = 3) + self.button_one.grid(row = 1, column = 3, sticky = 'W', pady = 40) + self.button_two.grid(row = 2, column = 3, sticky = 'W', pady = 0) + self.auto_resize(row_count = 2, column_count = 3, heavy_column = 3) + #self.button_two.deselect() + self.update() + self.mainloop() + + def progress_bar(self, message = None, icon_path = None, icon_name = None, size = 0, interval = 100, pb_queue = None): + #Best effort attempt at a real progress bar + # This is what Tk calls "determinate mode" rather than "indeterminate mode" + #size: denominator of percent complete + #interval: frequency, in ms, of how often to poll the file for progress + #pb_queue: queue object used to send updates to the bar + self.find_icon(icon_path, icon_name) + self.text_label = tk.Label(text = message) + self.set_colors(self.text_label) + self.set_colors(self.image_label) + self.image_label.grid(row = 1, column = 1, sticky = 'NSEW') + self.text_label.grid(row = 2, column = 1, sticky = 'NSEW') + self.progress = ttk.Progressbar(self, style = 'black.Horizontal.TProgressbar', orient="horizontal", length=100, mode="determinate") + self.progress.grid(row = 3, column = 1, sticky = 'NSEW') + self.value = 0 + self.progress["maximum"] = size + self.auto_resize(1, 3) + self.queue = pb_queue + self.check_scheduler() + + def check_scheduler(self): + if self.value < self.progress["maximum"]: + self.check_queue() + self.after(100, self.check_scheduler) + + def check_queue(self): + while self.queue.qsize(): + try: + msg = float(self.queue.get(0)) + #custom signal, time to tear down + if msg == -1: + self.choice.set(True) + self.destroy() + else: + self.progress.step(msg) + self.value = msg + except Queue.Empty: + pass + +class ThreadedClient(threading.Thread): + #for test only, not part of the functional code + def __init__(self, queue): + threading.Thread.__init__(self) + self.queue = queue + + def run(self): + for x in range(1, 90, 10): + time.sleep(1) + print "run " + str(x) + self.queue.put(10) + #tkk progress bars wrap at exactly 100 percent, look full at 99% + print "leftovers" + self.queue.put(9) + time.sleep(5) + # -1 is a custom signal to the progress_bar to quit + self.queue.put(-1) + +if __name__ == "__main__": + #When run as a script, just test the InstallUserMessage. + #To proceed with the test, close the first window, select on the second. The third will close by itself. + from contextlib import closing + from multiprocessing import Process + + import sys + import tempfile + + def set_and_check(frame, value): + print "value: " + str(value) + frame.progress.step(value) + if frame.progress["value"] < frame.progress["maximum"]: + print "In Progress" + else: + print "Over now" + + #basic message window test + frame2 = InstallerUserMessage(text = "Something in the way she moves....", title = "Beatles Quotes for 100") + frame2.basic_message(message = "...attracts me like no other.", icon_name="head-sl-logo.gif") + print "Destroyed!" + sys.stdout.flush() + + #binary choice test. User destroys window when they select. + frame3 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200") + frame3.binary_choice_message(message = "And all I have to do is think of her.", icon_name="head-sl-logo.gif", + one = "Don't want to leave her now", two = 'You know I believe and how') + print frame3.choice.get() + sys.stdout.flush() + + #progress bar + queue = Queue.Queue() + thread = ThreadedClient(queue) + thread.start() + print "thread started" + + frame4 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 300") + frame4.progress_bar(message = "You're asking me will my love grow", icon_name="head-sl-logo.gif", size = 100, pb_queue = queue) + print "frame defined" + + frame4.mainloop() + + + + From dd18fb215f76b36c96da00a6516ada096b11262c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 17 Jun 2016 08:49:26 -0700 Subject: [PATCH 012/183] SL-407: post review --- .../manager/InstallerUserMessage.py | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index bef2bf28a6..cf0a9da2a1 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -46,7 +46,11 @@ class InstallerUserMessage(tk.Tk): #Non-goals: # No claim to threadsafety is made or warranted. Your mileage may vary. # Please consult a doctor if you experience thread pain. - def __init__(self, text="", title="", width=500, height=200, fillcolor='#487A7B', *args, **kwargs): + + #Linden standard green color, from Marketing + linden_green = "#487A7B" + + def __init__(self, text="", title="", width=500, height=200, icon_name = None, icon_path = None, **kwargs): tk.Tk.__init__(self) self.grid() self.title(title) @@ -56,15 +60,22 @@ class InstallerUserMessage(tk.Tk): # http://tinyurl.com/tkmacbuttons ttk.Style().configure('Linden.TLabel', foreground='#487A7B', background='black') ttk.Style().configure('Linden.TButton', foreground='#487A7B', background='black') - ttk.Style().configure("black.Horizontal.TProgressbar", foreground='#487A7B', background='black') + ttk.Style().configure("black.Horizontal.TProgressbar", foreground=InstallerUserMessage.linden_green, background='black') + #This bit of configuration centers the window on the screen # The constants below are to adjust for typical overhead from the # frame borders. self.xp = (self.winfo_screenwidth() / 2) - (width / 2) - 8 self.yp = (self.winfo_screenheight() / 2) - (height / 2) - 20 self.geometry('{0}x{1}+{2}+{3}'.format(width, height, self.xp, self.yp)) + + #find a few things self.script_dir = os.path.dirname(os.path.realpath(__file__)) self.icon_dir = os.path.abspath(os.path.join(self.script_dir, 'icons')) + + #finds the icon and creates the widget + self.find_icon(icon_path, icon_name) + #defines what to do when window is closed self.protocol("WM_DELETE_WINDOW", self._delete_window) @@ -79,7 +90,7 @@ class InstallerUserMessage(tk.Tk): def set_colors(self, widget): # #487A7B is "Linden Green" - widget.config(foreground = '#487A7B') + widget.config(foreground = InstallerUserMessage.linden_green) widget.config(background='black') def find_icon(self, icon_path = None, icon_name = None): @@ -110,22 +121,21 @@ class InstallerUserMessage(tk.Tk): else: self.rowconfigure(x, weight=1) - def basic_message(self, message, icon_path = None, icon_name = None): + def basic_message(self, message, icon_name = None): #message: text to be displayed #icon_path: directory holding the icon, defaults to icons subdir of script dir #icon_name: filename of icon to be displayed self.choice.set(True) - self.find_icon(icon_path, icon_name) self.text_label = tk.Label(text = message) self.set_colors(self.text_label) self.set_colors(self.image_label) #pad, direction and weight are all experimentally derived by retrying various values self.image_label.grid(row = 1, column = 1, sticky = 'W') self.text_label.grid(row = 1, column = 2, sticky = 'W', padx =100) - self.auto_resize(1, 2) + self.auto_resize(row_count = 1, column_count = 2) self.mainloop() - def binary_choice_message(self, message, icon_path = None, icon_name = None, one = 'Yes', two = 'No'): + def binary_choice_message(self, message, true = 'Yes', false = 'No'): #one: first option, returns True #two: second option, returns False #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice @@ -134,7 +144,7 @@ class InstallerUserMessage(tk.Tk): # frame = frame.binary_choice_message( ... ) # (wait for user to click) # value = frame.choice.get() - self.find_icon(icon_path, icon_name) + self.text_label = tk.Label(text = message) #command registers the callback to the method named. We want the frame to go away once clicked. #button 1 returns True/1, button 2 returns False/0 @@ -154,13 +164,12 @@ class InstallerUserMessage(tk.Tk): self.update() self.mainloop() - def progress_bar(self, message = None, icon_path = None, icon_name = None, size = 0, interval = 100, pb_queue = None): + def progress_bar(self, message = None, size = 0, interval = 100, pb_queue = None): #Best effort attempt at a real progress bar # This is what Tk calls "determinate mode" rather than "indeterminate mode" #size: denominator of percent complete #interval: frequency, in ms, of how often to poll the file for progress #pb_queue: queue object used to send updates to the bar - self.find_icon(icon_path, icon_name) self.text_label = tk.Label(text = message) self.set_colors(self.text_label) self.set_colors(self.image_label) @@ -170,7 +179,7 @@ class InstallerUserMessage(tk.Tk): self.progress.grid(row = 3, column = 1, sticky = 'NSEW') self.value = 0 self.progress["maximum"] = size - self.auto_resize(1, 3) + self.auto_resize(row_count = 1, column_count = 3) self.queue = pb_queue self.check_scheduler() @@ -191,7 +200,8 @@ class InstallerUserMessage(tk.Tk): self.progress.step(msg) self.value = msg except Queue.Empty: - pass + #nothing to do + return class ThreadedClient(threading.Thread): #for test only, not part of the functional code @@ -214,9 +224,6 @@ class ThreadedClient(threading.Thread): if __name__ == "__main__": #When run as a script, just test the InstallUserMessage. #To proceed with the test, close the first window, select on the second. The third will close by itself. - from contextlib import closing - from multiprocessing import Process - import sys import tempfile @@ -229,15 +236,15 @@ if __name__ == "__main__": print "Over now" #basic message window test - frame2 = InstallerUserMessage(text = "Something in the way she moves....", title = "Beatles Quotes for 100") - frame2.basic_message(message = "...attracts me like no other.", icon_name="head-sl-logo.gif") + frame2 = InstallerUserMessage(text = "Something in the way she moves....", title = "Beatles Quotes for 100", icon_name="head-sl-logo.gif") + frame2.basic_message(message = "...attracts me like no other.") print "Destroyed!" sys.stdout.flush() #binary choice test. User destroys window when they select. - frame3 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200") - frame3.binary_choice_message(message = "And all I have to do is think of her.", icon_name="head-sl-logo.gif", - one = "Don't want to leave her now", two = 'You know I believe and how') + frame3 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") + frame3.binary_choice_message(message = "And all I have to do is think of her.", + true = "Don't want to leave her now", false = 'You know I believe and how') print frame3.choice.get() sys.stdout.flush() @@ -247,8 +254,8 @@ if __name__ == "__main__": thread.start() print "thread started" - frame4 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 300") - frame4.progress_bar(message = "You're asking me will my love grow", icon_name="head-sl-logo.gif", size = 100, pb_queue = queue) + frame4 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 300", icon_name="head-sl-logo.gif") + frame4.progress_bar(message = "You're asking me will my love grow", size = 100, pb_queue = queue) print "frame defined" frame4.mainloop() From f38439f4761abb73f6c7c93d52697cd9fa9f8368 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 17 Jun 2016 08:53:46 -0700 Subject: [PATCH 013/183] SL-407: post review change testing --- indra/viewer_components/manager/InstallerUserMessage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index cf0a9da2a1..e6dba78169 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -121,7 +121,7 @@ class InstallerUserMessage(tk.Tk): else: self.rowconfigure(x, weight=1) - def basic_message(self, message, icon_name = None): + def basic_message(self, message): #message: text to be displayed #icon_path: directory holding the icon, defaults to icons subdir of script dir #icon_name: filename of icon to be displayed @@ -148,9 +148,9 @@ class InstallerUserMessage(tk.Tk): self.text_label = tk.Label(text = message) #command registers the callback to the method named. We want the frame to go away once clicked. #button 1 returns True/1, button 2 returns False/0 - self.button_one = ttk.Radiobutton(text = one, variable = self.choice, value = True, + self.button_one = ttk.Radiobutton(text = true, variable = self.choice, value = True, command = self._delete_window, style = 'Linden.TButton') - self.button_two = ttk.Radiobutton(text = two, variable = self.choice, value = False, + self.button_two = ttk.Radiobutton(text = false, variable = self.choice, value = False, command = self._delete_window, style = 'Linden.TButton') self.set_colors(self.text_label) self.set_colors(self.image_label) From 53fe427e6fd2bf4701f98fb9896d69cfef9042b6 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 17 Jun 2016 09:58:28 -0700 Subject: [PATCH 014/183] SL-407: remove kwargs --- indra/viewer_components/manager/InstallerUserMessage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index e6dba78169..0ab7eafc78 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -50,7 +50,7 @@ class InstallerUserMessage(tk.Tk): #Linden standard green color, from Marketing linden_green = "#487A7B" - def __init__(self, text="", title="", width=500, height=200, icon_name = None, icon_path = None, **kwargs): + def __init__(self, text="", title="", width=500, height=200, icon_name = None, icon_path = None): tk.Tk.__init__(self) self.grid() self.title(title) From eb9cc511de84f2dd54478ffd517eb34bcc6e3d1d Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 17 Jun 2016 11:01:36 -0700 Subject: [PATCH 015/183] SL-321: retrofit launcher to use InstallerUserMessage --- indra/viewer_components/manager/SL_Launcher | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index e715546821..fd7d00be0f 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -15,12 +15,13 @@ # WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, # COMPLETENESS OR PERFORMANCE. # $/LicenseInfo$ +# Copyright (c) 2013, Linden Research, Inc. import argparse import os import sys import subprocess -import Tkinter as tk +import InstallerUserMessage cwd = os.path.dirname(os.path.realpath(__file__)) @@ -51,13 +52,10 @@ parser = argparse.ArgumentParser() args = parser.parse_known_args(sys.argv) args_list_to_pass = args[1][1:] args_list_to_pass.insert(0,viewer_binary) -#print "COYOT: arrrrrghs to pass", args_list_to_pass +print "COYOT: arrrrrghs to pass", args_list_to_pass #to prove we are launching from the script, launch a Tkinter window first -root = tk.Tk() -w = tk.Label(root, text=viewer_binary) -w.pack() -root.after(10000, lambda: root.destroy()) # Destroy the widget after 10 seconds -root.mainloop() +frame2 = InstallerUserMessage(title = "Second Life") +frame2.basic_message(message = viewer_binary, icon_name="head-sl-logo.gif") -viewer_process = subprocess.Popen(args_list_to_pass) +#viewer_process = subprocess.Popen(args_list_to_pass) From 5d900a4d8d01ffa2113cc8c763075bcd0968560f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 23 Jun 2016 08:05:31 -0700 Subject: [PATCH 016/183] SL-321 add trinary widget to InstallerUserMessage --- .../manager/InstallerUserMessage.py | 52 +++++++++++++++---- indra/viewer_components/manager/SL_Launcher | 1 - 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index 0ab7eafc78..2ec71df030 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -58,8 +58,8 @@ class InstallerUserMessage(tk.Tk): self.config(background = 'black') # background="..." doesn't work on MacOS for radiobuttons or progress bars # http://tinyurl.com/tkmacbuttons - ttk.Style().configure('Linden.TLabel', foreground='#487A7B', background='black') - ttk.Style().configure('Linden.TButton', foreground='#487A7B', background='black') + ttk.Style().configure('Linden.TLabel', foreground=InstallerUserMessage.linden_green, background='black') + ttk.Style().configure('Linden.TButton', foreground=InstallerUserMessage.linden_green, background='black') ttk.Style().configure("black.Horizontal.TProgressbar", foreground=InstallerUserMessage.linden_green, background='black') #This bit of configuration centers the window on the screen @@ -136,8 +136,8 @@ class InstallerUserMessage(tk.Tk): self.mainloop() def binary_choice_message(self, message, true = 'Yes', false = 'No'): - #one: first option, returns True - #two: second option, returns False + #true: first option, returns True + #false: second option, returns False #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice #usage: # frame = InstallerUserMessage.InstallerUserMessage( ... ) @@ -164,6 +164,38 @@ class InstallerUserMessage(tk.Tk): self.update() self.mainloop() + def trinary_choice_message(self, message, one = 1, two = 2, three = 3): + #one: first option, returns 1 + #two: second option, returns 2 + #three: third option, returns 3 + #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice + #usage: + # frame = InstallerUserMessage.InstallerUserMessage( ... ) + # frame = frame.binary_choice_message( ... ) + # (wait for user to click) + # value = frame.choice.get() + + self.text_label = tk.Label(text = message) + #command registers the callback to the method named. We want the frame to go away once clicked. + self.button_one = ttk.Radiobutton(text = one, variable = self.choice, value = 1, + command = self._delete_window, style = 'Linden.TButton') + self.button_two = ttk.Radiobutton(text = two, variable = self.choice, value = 2, + command = self._delete_window, style = 'Linden.TButton') + self.button_three = ttk.Radiobutton(text = three, variable = self.choice, value = 3, + command = self._delete_window, style = 'Linden.TButton') + self.set_colors(self.text_label) + self.set_colors(self.image_label) + #pad, direction and weight are all experimentally derived by retrying various values + self.image_label.grid(row = 1, column = 1, rowspan = 4, sticky = 'W') + self.text_label.grid(row = 1, column = 2, rowspan = 4, padx = 5) + self.button_one.grid(row = 1, column = 3, sticky = 'W', pady = 5) + self.button_two.grid(row = 2, column = 3, sticky = 'W', pady = 5) + self.button_three.grid(row = 3, column = 3, sticky = 'W', pady = 5) + self.auto_resize(row_count = 3, column_count = 3, heavy_column = 3) + #self.button_two.deselect() + self.update() + self.mainloop() + def progress_bar(self, message = None, size = 0, interval = 100, pb_queue = None): #Best effort attempt at a real progress bar # This is what Tk calls "determinate mode" rather than "indeterminate mode" @@ -248,6 +280,13 @@ if __name__ == "__main__": print frame3.choice.get() sys.stdout.flush() + #trinary choice test. User destroys window when they select. + frame3a = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") + frame3a.trinary_choice_message(message = "And all I have to do is think of her.", + one = "Don't want to leave her now", two = 'You know I believe and how', three = 'John is Dead') + print frame3a.choice.get() + sys.stdout.flush() + #progress bar queue = Queue.Queue() thread = ThreadedClient(queue) @@ -257,9 +296,4 @@ if __name__ == "__main__": frame4 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 300", icon_name="head-sl-logo.gif") frame4.progress_bar(message = "You're asking me will my love grow", size = 100, pb_queue = queue) print "frame defined" - frame4.mainloop() - - - - diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index fd7d00be0f..6eaccc8b13 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -34,7 +34,6 @@ elif sys.platform.startswith("win") or sys.platform.startswith("cyg"): elif os.path.isfile(os.path.join(cwd,"SecondLifeTest.exe")): executable_name = "SecondLifeTest.exe" else: - #unsupported by prototypeS sys.exit("Can't find Windows viewer binary") elif sys.platform.startswith("linux"): executable_name = "secondlife" From e01f6168993af377b2a625176efff95b498b5d21 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 27 Jun 2016 15:30:57 -0700 Subject: [PATCH 017/183] SL-323: multithreaded downloader with progress bar --- .../manager/download_update.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 indra/viewer_components/manager/download_update.py diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py new file mode 100755 index 0000000000..aa8555cd21 --- /dev/null +++ b/indra/viewer_components/manager/download_update.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +""" +@file download_update.py +@author coyot +@date 2016-06-23 +""" + +""" +Performs a download of an update. In a separate script from update_manager so that we can +call it with subprocess. +""" + +import argparse +import InstallerUserMessage as IUM +import os +import Queue +import requests +import threading + + +def download_update(url = None, download_dir = None, size = None, progressbar = False, chunk_size = 1024): + #url to download from + #download_dir to download to + #total size (for progressbar) of download + #progressbar: whether to display one (not used for background downloads) + #chunk_size is in bytes + #in_queue is to communicate between download_update and the thread + #out_queue is to communicate between the thread and the progressbar + #if progressbar: + #out_queue = Queue.Queue() + #buffer_thread = ThreadedBuffer(size, in_queue, out_queue) + #buffer_thread.start() + #pb_thread = ThreadedBar(size, out_queue) + #pb_thread.start() + + queue = Queue.Queue() + filename = os.path.join(download_dir, url.split('/')[-1]) + req = requests.get(url, stream=True) + down_thread = ThreadedDownload(req, filename, chunk_size, progressbar, queue) + down_thread.start() + + if progressbar: + frame = IUM.InstallerUserMessage(title = "Second Life Downloader", icon_name="head-sl-logo.gif") + frame.progress_bar(message = "Download Progress", size = size, pb_queue = queue) + frame.mainloop() + +class ThreadedDownload(threading.Thread): + def __init__(self, req, filename, chunk_size, progressbar, in_queue): + threading.Thread.__init__(self) + self.req = req + self.filename = filename + self.chunk_size = int(chunk_size) + self.progressbar = progressbar + self.in_queue = in_queue + + def run(self): + with open(self.filename, 'wb') as fd: + for chunk in self.req.iter_content(self.chunk_size): + fd.write(chunk) + if self.progressbar: + self.in_queue.put(len(chunk)) + self.in_queue.put(-1) + +def main(): + parser = argparse.ArgumentParser("Download URI to directory") + parser.add_argument('--url', dest='url', help='URL of file to be downloaded', required=True) + parser.add_argument('--dir', dest='download_dir', help='directory to be downloaded to', required=True) + parser.add_argument('--pb', dest='progressbar', help='whether or not to show a progressbar', action="store_true", default = False) + parser.add_argument('--size', dest='size', help='size of download for progressbar') + parser.add_argument('--chunk_size', dest='chunk_size', help='max portion size of download to be loaded in memory in bytes.') + args = parser.parse_args() + + download_update(url = args.url, download_dir = args.download_dir, size = args.size, progressbar = args.progressbar, chunk_size = args.chunk_size) + + +if __name__ == "__main__": + main() From cb90597b4e6fa64db706d6341039ade3c6d09a5b Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 27 Jun 2016 16:20:10 -0700 Subject: [PATCH 018/183] remove extraneous comments --- indra/viewer_components/manager/download_update.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py index aa8555cd21..71da5c97c2 100755 --- a/indra/viewer_components/manager/download_update.py +++ b/indra/viewer_components/manager/download_update.py @@ -43,14 +43,6 @@ def download_update(url = None, download_dir = None, size = None, progressbar = #total size (for progressbar) of download #progressbar: whether to display one (not used for background downloads) #chunk_size is in bytes - #in_queue is to communicate between download_update and the thread - #out_queue is to communicate between the thread and the progressbar - #if progressbar: - #out_queue = Queue.Queue() - #buffer_thread = ThreadedBuffer(size, in_queue, out_queue) - #buffer_thread.start() - #pb_thread = ThreadedBar(size, out_queue) - #pb_thread.start() queue = Queue.Queue() filename = os.path.join(download_dir, url.split('/')[-1]) From 9bc49fb4bd94814482846106954e198e504d802a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 28 Jun 2016 11:34:05 -0700 Subject: [PATCH 019/183] SL-323: post review comments on downloader --- .../viewer_components/manager/download_update.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py index 71da5c97c2..cd4e6680b0 100755 --- a/indra/viewer_components/manager/download_update.py +++ b/indra/viewer_components/manager/download_update.py @@ -1,7 +1,5 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# # Copyright (c) 2016, Linden Research, Inc. # # The following source code is PROPRIETARY AND CONFIDENTIAL. Use of @@ -14,8 +12,8 @@ # ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO # WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, # COMPLETENESS OR PERFORMANCE. -# $LicenseInfo:firstyear=2013&license=viewerlgpl$ -# Copyright (c) 2013, Linden Research, Inc. +# $LicenseInfo:firstyear=2016&license=viewerlgpl$ +# Copyright (c) 2016, Linden Research, Inc. # $/LicenseInfo$ """ @@ -36,8 +34,10 @@ import Queue import requests import threading +#module default +CHUNK_SIZE = 1024 -def download_update(url = None, download_dir = None, size = None, progressbar = False, chunk_size = 1024): +def download_update(url = None, download_dir = None, size = None, progressbar = False, chunk_size = CHUNK_SIZE): #url to download from #download_dir to download to #total size (for progressbar) of download @@ -54,6 +54,9 @@ def download_update(url = None, download_dir = None, size = None, progressbar = frame = IUM.InstallerUserMessage(title = "Second Life Downloader", icon_name="head-sl-logo.gif") frame.progress_bar(message = "Download Progress", size = size, pb_queue = queue) frame.mainloop() + else: + #nothing for the main thread to do + down_thread.join() class ThreadedDownload(threading.Thread): def __init__(self, req, filename, chunk_size, progressbar, in_queue): @@ -78,7 +81,7 @@ def main(): parser.add_argument('--dir', dest='download_dir', help='directory to be downloaded to', required=True) parser.add_argument('--pb', dest='progressbar', help='whether or not to show a progressbar', action="store_true", default = False) parser.add_argument('--size', dest='size', help='size of download for progressbar') - parser.add_argument('--chunk_size', dest='chunk_size', help='max portion size of download to be loaded in memory in bytes.') + parser.add_argument('--chunk_size', dest='chunk_size', default=CHUNK_SIZE, help='max portion size of download to be loaded in memory in bytes.') args = parser.parse_args() download_update(url = args.url, download_dir = args.download_dir, size = args.size, progressbar = args.progressbar, chunk_size = args.chunk_size) From 924e80142fd3ef1454dab1e9a002e5be9e66db94 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 5 Jul 2016 08:06:03 -0700 Subject: [PATCH 020/183] SL-323: apply update code --- .../viewer_components/manager/apply_update.py | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100755 indra/viewer_components/manager/apply_update.py diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py new file mode 100755 index 0000000000..1cf394e008 --- /dev/null +++ b/indra/viewer_components/manager/apply_update.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python + +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $LicenseInfo:firstyear=2016&license=viewerlgpl$ +# Copyright (c) 2016, Linden Research, Inc. +# $/LicenseInfo$ + +""" +@file apply_update.py +@author coyot +@date 2016-06-28 +""" + +""" +Applies an already downloaded update. +""" + +import argparse +import fnmatch +import InstallerUserMessage as IUM +import os +import os.path +import plistlib +import shutil +import subprocess +import sys +import tarfile +import tempfile + +LNX_REGEX = '*' + '.bz2' +MAC_REGEX = '*' + '.dmg' +MAC_APP_REGEX = '*' + '.app' +WIN_REGEX = '*' + '.exe' + +INSTALL_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + +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") + +def silent_write(log_file_handle, text): + #if we have a log file, write. If not, do nothing. + if (log_file_handle): + #prepend text for easy grepping + log_file_handle.write("APPLY UPDATE: " + text + "\n") + +def get_filename(download_dir = None): + #given a directory that supposedly has the download, find the installable + for filename in os.listdir(download_dir): + if (fnmatch.fnmatch(filename, LNX_REGEX) + or fnmatch.fnmatch(filename, MAC_REGEX) + or fnmatch.fnmatch(filename, WIN_REGEX)): + return os.path.join(download_dir, filename) + else: + return None + +def try_dismount(log_file_handle = None, installable = None, tmpdir = None): + #best effort cleanup try to dismount the dmg file if we have mounted one + #the French judge gave it a 5.8 + try: + command = ["df", os.path.join(tmpdir, "Second Life Installer")] + output = subprocess.check_output(command) + mnt_dev = output.split('\n')[1].split()[0] + command = ["hdiutil", "detach", "-force", mnt_dev] + output = subprocess.check_output(command) + silent_write(log_file_handle, "hdiutil detach succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not detach dmg file %s. Error messages: %s" % (installable, e.message)) + +def apply_update(download_dir = None, platform_key = None, log_file_handle = None): + #for lnx and mac, returns path to newly installed viewer and "True" for Windows + #returns None on failure for all three + installable = get_filename(download_dir) + if not installable: + #could not find download + raise ValueError("Could not find installable in " + download_dir) + + if platform_key == 'lnx': + installed = apply_linux_update(installable, log_file_handle) + elif platform_key == 'mac': + installed = apply_mac_update(installable, log_file_handle) + elif platform_key == 'win': + installed = apply_windows_update(installable, log_file_handle) + else: + #wtf? + raise ValueError("Unknown Platform: " + platform_key) + + if not installed: + done_filename = os.path.join(os.path.dirname(installable), ".done") + open(done_filename, 'w+').close() + + return installed + +def apply_linux_update(installable = None, log_file_handle = None): + try: + #untar to tmpdir + tmpdir = tempfile.mkdtemp() + tar = tarfile.open(name = installable, mode="r:bz2") + tar.extractall(path = tmpdir) + #rename current install dir + shutil.move(INSTALL_DIR,install_dir + ".bak") + #mv new to current + shutil.move(tmpdir, INSTALL_DIR) + #delete tarball on success + os.remove(installable) + except Exception, e: + silent_write(log_file_handle, "Update failed due to " + repr(e)) + return None + return INSTALL_DIR + +def apply_mac_update(installable = None, log_file_handle = None): + #verify dmg file + try: + output = subprocess.check_output(["hdiutil", "verify", installable], stderr=subprocess.STDOUT) + silent_write(log_file_handle, "dmg verification succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not verify dmg file %s. Error messages: %s" % (installable, e.message)) + return None + #make temp dir and mount & attach dmg + tmpdir = tempfile.mkdtemp() + try: + output = subprocess.check_output(["hdiutil", "attach", installable, "-mountroot", tmpdir]) + silent_write(log_file_handle, "hdiutil attach succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not attach dmg file %s. Error messages: %s" % (installable, e.message)) + return None + #verify plist + appdir = None + for top_dir in os.listdir(tmpdir): + for appdir in os.listdir(os.path.join(tmpdir, top_dir)): + appdir = os.path.join(os.path.join(tmpdir, top_dir), appdir) + if fnmatch.fnmatch(appdir, MAC_APP_REGEX): + try: + plist = os.path.join(appdir, "Contents", "Info.plist") + CFBundleIdentifier = plistlib.readPlist(plist)["CFBundleIdentifier"] + except: + #there is no except for this try because there are multiple directories that legimately don't have what we are looking for + pass + if not appdir: + silent_write(log_file_handle, "Could not find app bundle in dmg %s." % (installable,)) + return None + if CFBundleIdentifier != BUNDLE_IDENTIFIER: + silent_write(log_file_handle, "Wrong or null bundle identifier for dmg %s. Bundle identifier: %s" % (installable, CFBundleIdentifier)) + try_dismount(log_file_handle, installable, tmpdir) + return None + #do the install, finally + # swap out old install directory + bundlename = os.path.basename(appdir) + #INSTALL_DIR is something like /Applications/Second Life Viewer.app/Contents/MacOS, need to jump up two levels + installed_test = os.path.dirname(INSTALL_DIR) + installed_test = os.path.dirname(installed_test) + if os.path.exists(installed_test): + silent_write(log_file_handle, "Updating %s" % installed_test) + swapped_out = os.path.join(tmpdir, INSTALL_DIR.lstrip('/')) + shutil.move(installed_test, swapped_out) + else: + silent_write(log_file_handle, "Installing %s" % installed_test) + + # copy over the new bits + try: + shutil.copytree(appdir, installed_test, symlinks=True) + retcode = 0 + except Exception, e: + # try to restore previous viewer + if os.path.exists(swapped_out): + silent_write(log_file_handle, "Install of %s failed, rolling back to previous viewer." % installable) + shutil.move(swapped_out, installed_test) + retcode = 1 + finally: + try_dismount(log_file_handle, installable, tmpdir) + if retcode: + return None + + #see MAINT-3331 + with allow_errno(errno.ENOENT): + shutil.rmtree(STATE_DIR) + + os.remove(installable) + return INSTALL_DIR + +def apply_windows_update(installable = None, log_file_handle = None): + #the windows install is just running the NSIS installer executable + #from VMP's perspective, it is a black box + try: + output = subprocess.check_output(installable, stderr=subprocess.STDOUT) + silent_write(log_file_handle, "Install of %s succeeded." % installable) + silent_write(log_file_handle, output) + except subprocess.CalledProcessError, cpe: + silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." % + (cpe.cmd, cpe.returncode, cpe.message)) + return None + return True + +def main(): + parser = argparse.ArgumentParser("Apply Downloaded Update") + parser.add_argument('--dir', dest = 'download_dir', help = 'directory to find installable', required=True) + parser.add_argument('--pkey', dest = 'platform_key', help =' OS: lnx|mac|win', required=True) + parser.add_argument('--log_file', dest = 'log_file', default = None, help = 'file to write messages to') + args = parser.parse_args() + + if args.log_file: + try: + f = open(args.log_file,'w+') + except: + print "%s could not be found or opened" % args.log_file + sys.exit(1) + + result = apply_update(download_dir = args.download_dir, platform_key = args.platform_key, log_file_handle = f) + if not result: + sys.exit("Update failed") + else: + sys.exit(0) + + +if __name__ == "__main__": + main() From 7e120a61d1ce670b2bab8ab6b1a814ed4af0dc12 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 5 Jul 2016 13:43:50 -0700 Subject: [PATCH 021/183] remove first version of apply_update --- .../viewer_components/manager/apply_update.py | 232 ------------------ 1 file changed, 232 deletions(-) delete mode 100755 indra/viewer_components/manager/apply_update.py diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py deleted file mode 100755 index 1cf394e008..0000000000 --- a/indra/viewer_components/manager/apply_update.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $LicenseInfo:firstyear=2016&license=viewerlgpl$ -# Copyright (c) 2016, Linden Research, Inc. -# $/LicenseInfo$ - -""" -@file apply_update.py -@author coyot -@date 2016-06-28 -""" - -""" -Applies an already downloaded update. -""" - -import argparse -import fnmatch -import InstallerUserMessage as IUM -import os -import os.path -import plistlib -import shutil -import subprocess -import sys -import tarfile -import tempfile - -LNX_REGEX = '*' + '.bz2' -MAC_REGEX = '*' + '.dmg' -MAC_APP_REGEX = '*' + '.app' -WIN_REGEX = '*' + '.exe' - -INSTALL_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) - -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") - -def silent_write(log_file_handle, text): - #if we have a log file, write. If not, do nothing. - if (log_file_handle): - #prepend text for easy grepping - log_file_handle.write("APPLY UPDATE: " + text + "\n") - -def get_filename(download_dir = None): - #given a directory that supposedly has the download, find the installable - for filename in os.listdir(download_dir): - if (fnmatch.fnmatch(filename, LNX_REGEX) - or fnmatch.fnmatch(filename, MAC_REGEX) - or fnmatch.fnmatch(filename, WIN_REGEX)): - return os.path.join(download_dir, filename) - else: - return None - -def try_dismount(log_file_handle = None, installable = None, tmpdir = None): - #best effort cleanup try to dismount the dmg file if we have mounted one - #the French judge gave it a 5.8 - try: - command = ["df", os.path.join(tmpdir, "Second Life Installer")] - output = subprocess.check_output(command) - mnt_dev = output.split('\n')[1].split()[0] - command = ["hdiutil", "detach", "-force", mnt_dev] - output = subprocess.check_output(command) - silent_write(log_file_handle, "hdiutil detach succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not detach dmg file %s. Error messages: %s" % (installable, e.message)) - -def apply_update(download_dir = None, platform_key = None, log_file_handle = None): - #for lnx and mac, returns path to newly installed viewer and "True" for Windows - #returns None on failure for all three - installable = get_filename(download_dir) - if not installable: - #could not find download - raise ValueError("Could not find installable in " + download_dir) - - if platform_key == 'lnx': - installed = apply_linux_update(installable, log_file_handle) - elif platform_key == 'mac': - installed = apply_mac_update(installable, log_file_handle) - elif platform_key == 'win': - installed = apply_windows_update(installable, log_file_handle) - else: - #wtf? - raise ValueError("Unknown Platform: " + platform_key) - - if not installed: - done_filename = os.path.join(os.path.dirname(installable), ".done") - open(done_filename, 'w+').close() - - return installed - -def apply_linux_update(installable = None, log_file_handle = None): - try: - #untar to tmpdir - tmpdir = tempfile.mkdtemp() - tar = tarfile.open(name = installable, mode="r:bz2") - tar.extractall(path = tmpdir) - #rename current install dir - shutil.move(INSTALL_DIR,install_dir + ".bak") - #mv new to current - shutil.move(tmpdir, INSTALL_DIR) - #delete tarball on success - os.remove(installable) - except Exception, e: - silent_write(log_file_handle, "Update failed due to " + repr(e)) - return None - return INSTALL_DIR - -def apply_mac_update(installable = None, log_file_handle = None): - #verify dmg file - try: - output = subprocess.check_output(["hdiutil", "verify", installable], stderr=subprocess.STDOUT) - silent_write(log_file_handle, "dmg verification succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not verify dmg file %s. Error messages: %s" % (installable, e.message)) - return None - #make temp dir and mount & attach dmg - tmpdir = tempfile.mkdtemp() - try: - output = subprocess.check_output(["hdiutil", "attach", installable, "-mountroot", tmpdir]) - silent_write(log_file_handle, "hdiutil attach succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not attach dmg file %s. Error messages: %s" % (installable, e.message)) - return None - #verify plist - appdir = None - for top_dir in os.listdir(tmpdir): - for appdir in os.listdir(os.path.join(tmpdir, top_dir)): - appdir = os.path.join(os.path.join(tmpdir, top_dir), appdir) - if fnmatch.fnmatch(appdir, MAC_APP_REGEX): - try: - plist = os.path.join(appdir, "Contents", "Info.plist") - CFBundleIdentifier = plistlib.readPlist(plist)["CFBundleIdentifier"] - except: - #there is no except for this try because there are multiple directories that legimately don't have what we are looking for - pass - if not appdir: - silent_write(log_file_handle, "Could not find app bundle in dmg %s." % (installable,)) - return None - if CFBundleIdentifier != BUNDLE_IDENTIFIER: - silent_write(log_file_handle, "Wrong or null bundle identifier for dmg %s. Bundle identifier: %s" % (installable, CFBundleIdentifier)) - try_dismount(log_file_handle, installable, tmpdir) - return None - #do the install, finally - # swap out old install directory - bundlename = os.path.basename(appdir) - #INSTALL_DIR is something like /Applications/Second Life Viewer.app/Contents/MacOS, need to jump up two levels - installed_test = os.path.dirname(INSTALL_DIR) - installed_test = os.path.dirname(installed_test) - if os.path.exists(installed_test): - silent_write(log_file_handle, "Updating %s" % installed_test) - swapped_out = os.path.join(tmpdir, INSTALL_DIR.lstrip('/')) - shutil.move(installed_test, swapped_out) - else: - silent_write(log_file_handle, "Installing %s" % installed_test) - - # copy over the new bits - try: - shutil.copytree(appdir, installed_test, symlinks=True) - retcode = 0 - except Exception, e: - # try to restore previous viewer - if os.path.exists(swapped_out): - silent_write(log_file_handle, "Install of %s failed, rolling back to previous viewer." % installable) - shutil.move(swapped_out, installed_test) - retcode = 1 - finally: - try_dismount(log_file_handle, installable, tmpdir) - if retcode: - return None - - #see MAINT-3331 - with allow_errno(errno.ENOENT): - shutil.rmtree(STATE_DIR) - - os.remove(installable) - return INSTALL_DIR - -def apply_windows_update(installable = None, log_file_handle = None): - #the windows install is just running the NSIS installer executable - #from VMP's perspective, it is a black box - try: - output = subprocess.check_output(installable, stderr=subprocess.STDOUT) - silent_write(log_file_handle, "Install of %s succeeded." % installable) - silent_write(log_file_handle, output) - except subprocess.CalledProcessError, cpe: - silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." % - (cpe.cmd, cpe.returncode, cpe.message)) - return None - return True - -def main(): - parser = argparse.ArgumentParser("Apply Downloaded Update") - parser.add_argument('--dir', dest = 'download_dir', help = 'directory to find installable', required=True) - parser.add_argument('--pkey', dest = 'platform_key', help =' OS: lnx|mac|win', required=True) - parser.add_argument('--log_file', dest = 'log_file', default = None, help = 'file to write messages to') - args = parser.parse_args() - - if args.log_file: - try: - f = open(args.log_file,'w+') - except: - print "%s could not be found or opened" % args.log_file - sys.exit(1) - - result = apply_update(download_dir = args.download_dir, platform_key = args.platform_key, log_file_handle = f) - if not result: - sys.exit("Update failed") - else: - sys.exit(0) - - -if __name__ == "__main__": - main() From bb19a1e9cc2d11f1db89a92eb17f98641736cd1e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 5 Jul 2016 13:44:43 -0700 Subject: [PATCH 022/183] SL-323: apply update code, v2 --- .../viewer_components/manager/apply_update.py | 254 ++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100755 indra/viewer_components/manager/apply_update.py diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py new file mode 100755 index 0000000000..362d57c94e --- /dev/null +++ b/indra/viewer_components/manager/apply_update.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python + +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $LicenseInfo:firstyear=2016&license=viewerlgpl$ +# Copyright (c) 2016, Linden Research, Inc. +# $/LicenseInfo$ + +""" +@file apply_update.py +@author coyot +@date 2016-06-28 +""" + +""" +Applies an already downloaded update. +""" + +import argparse +import errno +import fnmatch +import InstallerUserMessage as IUM +import os +import os.path +import plistlib +import shutil +import subprocess +import sys +import tarfile +import tempfile + +#fnmatch expressions +LNX_REGEX = '*' + '.bz2' +MAC_REGEX = '*' + '.dmg' +MAC_APP_REGEX = '*' + '.app' +WIN_REGEX = '*' + '.exe' + +#which install the updater is run from +INSTALL_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + +#whether the update is to the INSTALL_DIR or not. Most of the time this is the case. +IN_PLACE = True + +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") + +def silent_write(log_file_handle, text): + #if we have a log file, write. If not, do nothing. + if (log_file_handle): + #prepend text for easy grepping + log_file_handle.write("APPLY UPDATE: " + text + "\n") + +def get_filename(download_dir = None): + #given a directory that supposedly has the download, find the installable + for filename in os.listdir(download_dir): + if (fnmatch.fnmatch(filename, LNX_REGEX) + or fnmatch.fnmatch(filename, MAC_REGEX) + or fnmatch.fnmatch(filename, WIN_REGEX)): + return os.path.join(download_dir, filename) + #someone gave us a bad directory + return None + +def try_dismount(log_file_handle = None, installable = None, tmpdir = None): + #best effort cleanup try to dismount the dmg file if we have mounted one + #the French judge gave it a 5.8 + try: + command = ["df", os.path.join(tmpdir, "Second Life Installer")] + output = subprocess.check_output(command) + #first word of second line of df output is the device name + mnt_dev = output.split('\n')[1].split()[0] + command = ["hdiutil", "detach", "-force", mnt_dev] + output = subprocess.check_output(command) + silent_write(log_file_handle, "hdiutil detach succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not detach dmg file %s. Error messages: %s" % (installable, e.message)) + +def apply_update(download_dir = None, platform_key = None, log_file_handle = None): + #for lnx and mac, returns path to newly installed viewer + #for win, return the name of the executable + #returns None on failure for all three + #throws an exception if it can't find an installable at all + + installable = get_filename(download_dir) + if not installable: + #could not find download + raise ValueError("Could not find installable in " + download_dir) + + if platform_key == 'lnx': + installed = apply_linux_update(installable, log_file_handle) + elif platform_key == 'mac': + installed = apply_mac_update(installable, log_file_handle) + elif platform_key == 'win': + installed = apply_windows_update(installable, log_file_handle) + else: + #wtf? + raise ValueError("Unknown Platform: " + platform_key) + + if not installed: + #only mark the download as done when everything is done + done_filename = os.path.join(os.path.dirname(installable), ".done") + open(done_filename, 'w+').close() + + return installed + +def apply_linux_update(installable = None, log_file_handle = None): + try: + #untar to tmpdir + tmpdir = tempfile.mkdtemp() + tar = tarfile.open(name = installable, mode="r:bz2") + tar.extractall(path = tmpdir) + if IN_PLACE: + #rename current install dir + shutil.move(INSTALL_DIR,install_dir + ".bak") + #mv new to current + shutil.move(tmpdir, INSTALL_DIR) + #delete tarball on success + os.remove(installable) + except Exception, e: + silent_write(log_file_handle, "Update failed due to " + repr(e)) + return None + return INSTALL_DIR + +def apply_mac_update(installable = None, log_file_handle = None): + #INSTALL_DIR is something like /Applications/Second Life Viewer.app/Contents/MacOS, need to jump up two levels for the install base + install_base = os.path.dirname(INSTALL_DIR) + install_base = os.path.dirname(install_base) + + #verify dmg file + try: + output = subprocess.check_output(["hdiutil", "verify", installable], stderr=subprocess.STDOUT) + silent_write(log_file_handle, "dmg verification succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not verify dmg file %s. Error messages: %s" % (installable, e.message)) + return None + #make temp dir and mount & attach dmg + tmpdir = tempfile.mkdtemp() + try: + output = subprocess.check_output(["hdiutil", "attach", installable, "-mountroot", tmpdir]) + silent_write(log_file_handle, "hdiutil attach succeeded") + silent_write(log_file_handle, output) + except Exception, e: + silent_write(log_file_handle, "Could not attach dmg file %s. Error messages: %s" % (installable, e.message)) + return None + #verify plist + mounted_appdir = None + for top_dir in os.listdir(tmpdir): + for appdir in os.listdir(os.path.join(tmpdir, top_dir)): + appdir = os.path.join(os.path.join(tmpdir, top_dir), appdir) + if fnmatch.fnmatch(appdir, MAC_APP_REGEX): + try: + plist = os.path.join(appdir, "Contents", "Info.plist") + CFBundleIdentifier = plistlib.readPlist(plist)["CFBundleIdentifier"] + mounted_appdir = appdir + except: + #there is no except for this try because there are multiple directories that legimately don't have what we are looking for + pass + if not mounted_appdir: + silent_write(log_file_handle, "Could not find app bundle in dmg %s." % (installable,)) + return None + if CFBundleIdentifier != BUNDLE_IDENTIFIER: + silent_write(log_file_handle, "Wrong or null bundle identifier for dmg %s. Bundle identifier: %s" % (installable, CFBundleIdentifier)) + try_dismount(log_file_handle, installable, tmpdir) + return None + #do the install, finally + if IN_PLACE: + # swap out old install directory + bundlename = os.path.basename(mounted_appdir) + silent_write(log_file_handle, "Updating %s" % bundlename) + swapped_out = os.path.join(tmpdir, INSTALL_DIR.lstrip('/')) + shutil.move(install_base, swapped_out) + else: + silent_write(log_file_handle, "Installing %s" % install_base) + + # copy over the new bits + try: + shutil.copytree(mounted_appdir, install_base, symlinks=True) + retcode = 0 + except Exception, e: + # try to restore previous viewer + if os.path.exists(swapped_out): + silent_write(log_file_handle, "Install of %s failed, rolling back to previous viewer." % installable) + shutil.move(swapped_out, installed_test) + retcode = 1 + finally: + try_dismount(log_file_handle, installable, tmpdir) + if retcode: + return None + + #see MAINT-3331 + try: + shutil.rmtree(STATE_DIR) + except Exception, e: + #if we fail to delete something that isn't there, that's okay + if e[0] == errno.ENOENT: + pass + else: + raise e + + os.remove(installable) + return install_base + +def apply_windows_update(installable = None, log_file_handle = None): + #the windows install is just running the NSIS installer executable + #from VMP's perspective, it is a black box + try: + output = subprocess.check_output(installable, stderr=subprocess.STDOUT) + silent_write(log_file_handle, "Install of %s succeeded." % installable) + silent_write(log_file_handle, output) + except subprocess.CalledProcessError, cpe: + silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." % + (cpe.cmd, cpe.returncode, cpe.message)) + return None + return installable + +def main(): + parser = argparse.ArgumentParser("Apply Downloaded Update") + parser.add_argument('--dir', dest = 'download_dir', help = 'directory to find installable', required = True) + parser.add_argument('--pkey', dest = 'platform_key', help =' OS: lnx|mac|win', required = True) + parser.add_argument('--in_place', action = 'store_false', help = 'This upgrade is for a different channel', default = True) + parser.add_argument('--log_file', dest = 'log_file', default = None, help = 'file to write messages to') + args = parser.parse_args() + + if args.log_file: + try: + f = open(args.log_file,'w+') + except: + print "%s could not be found or opened" % args.log_file + sys.exit(1) + + IN_PLACE = args.in_place + result = apply_update(download_dir = args.download_dir, platform_key = args.platform_key, log_file_handle = f) + if not result: + sys.exit("Update failed") + else: + sys.exit(0) + + +if __name__ == "__main__": + main() From 03bcad61115b7128b3b1a5ede3cd7f2bf309fd39 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 11 Jul 2016 11:24:45 -0700 Subject: [PATCH 023/183] SLS-323: integrate update manager with lanucher, various fixes, CMake changes --- indra/newview/CMakeLists.txt | 33 ++ .../manager/InstallerUserMessage.py | 14 +- indra/viewer_components/manager/SL_Launcher | 59 ++- .../viewer_components/manager/apply_update.py | 29 +- .../manager/download_update.py | 16 +- .../manager/update_manager.py | 455 ++++++++++++++++++ 6 files changed, 582 insertions(+), 24 deletions(-) create mode 100755 indra/viewer_components/manager/update_manager.py diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 767a280beb..9ee7b656c0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1774,9 +1774,42 @@ if (WINDOWS) --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher COMMENT "Performing pyinstaller compile of SL_Launcher" + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/apply_update.exe + COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe + ARGS + --onefile + --log-level WARN + --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + ${CMAKE_SOURCE_DIR}/viewer_components/manager/apply_update.py + COMMENT "Performing pyinstaller compile of updater" + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/download_update.exe + COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe + ARGS + --onefile + --log-level WARN + --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + ${CMAKE_SOURCE_DIR}/viewer_components/manager/download_update.py + COMMENT "Performing pyinstaller compile of update downloader" + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/update_manager.exe + COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe + ARGS + --onefile + --log-level WARN + --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + ${CMAKE_SOURCE_DIR}/viewer_components/manager/update_manager.py + COMMENT "Performing pyinstaller compile of update manager" ) add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) +add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/apply_update.exe) +add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/download_update.exe) +add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/update_manager.exe) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index 2ec71df030..f66af81d06 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -280,13 +280,6 @@ if __name__ == "__main__": print frame3.choice.get() sys.stdout.flush() - #trinary choice test. User destroys window when they select. - frame3a = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") - frame3a.trinary_choice_message(message = "And all I have to do is think of her.", - one = "Don't want to leave her now", two = 'You know I believe and how', three = 'John is Dead') - print frame3a.choice.get() - sys.stdout.flush() - #progress bar queue = Queue.Queue() thread = ThreadedClient(queue) @@ -297,3 +290,10 @@ if __name__ == "__main__": frame4.progress_bar(message = "You're asking me will my love grow", size = 100, pb_queue = queue) print "frame defined" frame4.mainloop() + + #trinary choice test. User destroys window when they select. + frame3a = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") + frame3a.trinary_choice_message(message = "And all I have to do is think of her.", + one = "Don't want to leave her now", two = 'You know I believe and how', three = 'John is Dead') + print frame3a.choice.get() + sys.stdout.flush() diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 6eaccc8b13..ecf88a1105 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -18,10 +18,19 @@ # Copyright (c) 2013, Linden Research, Inc. import argparse +import InstallerUserMessage import os import sys import subprocess -import InstallerUserMessage +import update_manager + +def after_frame(my_message, timeout = 10000): + #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds + #note that this blocks the caller for the duration of timeout + frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") + #this is done before basic_message so that we aren't blocked by mainloop() + frame.after(timout, lambda: frame._delete_window) + frame.basic_message(message = my_message) cwd = os.path.dirname(os.path.realpath(__file__)) @@ -40,21 +49,47 @@ elif sys.platform.startswith("linux"): else: #SL doesn't run on VMS or punch cards sys.exit("Unsupported platform") + +#check for an update +#TODO -#print "COYOT: executable name ", executable_name -#print "COYOT: path ", os.path.dirname(os.path.abspath(sys.argv[0])) - +#find the viewer to be lauched viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name) parser = argparse.ArgumentParser() -#parser.add_argument('--f', action='store_const', const=42) args = parser.parse_known_args(sys.argv) args_list_to_pass = args[1][1:] -args_list_to_pass.insert(0,viewer_binary) -print "COYOT: arrrrrghs to pass", args_list_to_pass +#make a copy by value, not by reference +command = list(args_list_to_pass) -#to prove we are launching from the script, launch a Tkinter window first -frame2 = InstallerUserMessage(title = "Second Life") -frame2.basic_message(message = viewer_binary, icon_name="head-sl-logo.gif") - -#viewer_process = subprocess.Popen(args_list_to_pass) +(success, state, condition) = update_manager.update_manager() +# From update_manager: +# (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) +# (False, 'download', version): we failed to download the new version +# (False, 'apply', version): we failed to apply the new version +# (True, None, None): No update found +# (True, 'in place', True): update applied in place +# (True, 'in place', path_to_new_launcher): Update applied by a new install to a new location +# (True, 'background', True): background download initiated +#These boil down three cases: +# Success is False, then pop up a message and launch the current viewer +# No update, update succeeded in place in foreground, or background update started: silently launch the current viewer channel +# Updated succeed to a different channel, launch that viewer and exit +if not success: + msg = 'Update failed in the %s process. Please check logs. Viewer will launch starting momentarily.' + after_frame(msg) + command.insert(0,viewer_binary) + viewer_process = subprocess.Popen(command) + #at the moment, we just exit here. Later, the crash monitor will be launched at this point +elif (success == True and + (state == None + or (state == 'background' and condition == True) + or (state == 'in_place' and condition == True))): + command.insert(0,viewer_binary) + viewer_process = subprocess.Popen(command) + #at the moment, we just exit here. Later, the crash monitor will be launched at this point +else: + #'condition' is the path to the new launcher. + command.insert(0,condition) + viewer_process = subprocess.Popen(command) + sys.exit(0) diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py index 362d57c94e..643e4ad2bc 100755 --- a/indra/viewer_components/manager/apply_update.py +++ b/indra/viewer_components/manager/apply_update.py @@ -33,12 +33,15 @@ import InstallerUserMessage as IUM import os import os.path import plistlib +import re import shutil import subprocess import sys import tarfile import tempfile +#Module level variables + #fnmatch expressions LNX_REGEX = '*' + '.bz2' MAC_REGEX = '*' + '.dmg' @@ -65,6 +68,9 @@ def silent_write(log_file_handle, text): def get_filename(download_dir = None): #given a directory that supposedly has the download, find the installable + #if you are on platform X and you give the updater a directory with an installable + #for platform Y, you are either trying something fancy or get what you deserve + #or both for filename in os.listdir(download_dir): if (fnmatch.fnmatch(filename, LNX_REGEX) or fnmatch.fnmatch(filename, MAC_REGEX) @@ -77,10 +83,14 @@ def try_dismount(log_file_handle = None, installable = None, tmpdir = None): #best effort cleanup try to dismount the dmg file if we have mounted one #the French judge gave it a 5.8 try: + #use the df command to find the device name + #Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on + #/dev/disk1s2 2047936 643280 1404656 32% 80408 175582 31% /private/tmp/mnt/Second Life Installer command = ["df", os.path.join(tmpdir, "Second Life Installer")] output = subprocess.check_output(command) #first word of second line of df output is the device name mnt_dev = output.split('\n')[1].split()[0] + #do the dismount command = ["hdiutil", "detach", "-force", mnt_dev] output = subprocess.check_output(command) silent_write(log_file_handle, "hdiutil detach succeeded") @@ -88,17 +98,20 @@ def try_dismount(log_file_handle = None, installable = None, tmpdir = None): except Exception, e: silent_write(log_file_handle, "Could not detach dmg file %s. Error messages: %s" % (installable, e.message)) -def apply_update(download_dir = None, platform_key = None, log_file_handle = None): +def apply_update(download_dir = None, platform_key = None, log_file_handle = None, in_place = True): #for lnx and mac, returns path to newly installed viewer #for win, return the name of the executable #returns None on failure for all three #throws an exception if it can't find an installable at all + IN_PLACE = in_place + installable = get_filename(download_dir) if not installable: - #could not find download + #could not find the download raise ValueError("Could not find installable in " + download_dir) + #apply update using the platform specific tools if platform_key == 'lnx': installed = apply_linux_update(installable, log_file_handle) elif platform_key == 'mac': @@ -225,7 +238,17 @@ def apply_windows_update(installable = None, log_file_handle = None): silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." % (cpe.cmd, cpe.returncode, cpe.message)) return None - return installable + #Due to the black box nature of the install, we have to derive the application path from the + #name of the installable. This is essentially reverse-engineering app_name()/app_name_oneword() + #in viewer_manifest.py + #the format of the filename is: Second_Life_{Project Name}_A-B-C-XXXXXX_i686_Setup.exe + #which deploys to C:\Program Files (x86)\SecondLifeProjectName\ + #so we want all but the last four phrases and tack on Viewer if there is no project + if re.search('Project', installable): + winstall = os.path.join("C:\\Program Files (x86)\\", "".join(installable.split("_")[:-3])) + else: + winstall = os.path.join("C:\\Program Files (x86)\\", "".join(installable.split("_")[:-3])+"Viewer") + return winstall def main(): parser = argparse.ArgumentParser("Apply Downloaded Update") diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py index cd4e6680b0..23f784c6c1 100755 --- a/indra/viewer_components/manager/download_update.py +++ b/indra/viewer_components/manager/download_update.py @@ -42,9 +42,10 @@ def download_update(url = None, download_dir = None, size = None, progressbar = #download_dir to download to #total size (for progressbar) of download #progressbar: whether to display one (not used for background downloads) - #chunk_size is in bytes + #chunk_size is in bytes, amount to download at once queue = Queue.Queue() + #the url split provides the basename of the filename filename = os.path.join(download_dir, url.split('/')[-1]) req = requests.get(url, stream=True) down_thread = ThreadedDownload(req, filename, chunk_size, progressbar, queue) @@ -60,6 +61,11 @@ def download_update(url = None, download_dir = None, size = None, progressbar = class ThreadedDownload(threading.Thread): def __init__(self, req, filename, chunk_size, progressbar, in_queue): + #req is a python request object + #target filename to download to + #chunk_size is in bytes, amount to download at once + #progressbar: whether to display one (not used for background downloads) + #in_queue mediates communication between this thread and the progressbar threading.Thread.__init__(self) self.req = req self.filename = filename @@ -69,13 +75,19 @@ class ThreadedDownload(threading.Thread): def run(self): with open(self.filename, 'wb') as fd: + #keep downloading until we run out of chunks, then download the last bit for chunk in self.req.iter_content(self.chunk_size): fd.write(chunk) if self.progressbar: - self.in_queue.put(len(chunk)) + #this will increment the progress bar by len(chunk)/size units + self.in_queue.put(len(chunk)) + #signal value saying to the progress bar that it is done and can destroy itself + #if len(chunk) is ever -1, we get to file a bug against Python self.in_queue.put(-1) def main(): + #main method is for standalone use such as support and QA + #VMP will import this module and run download_update directly parser = argparse.ArgumentParser("Download URI to directory") parser.add_argument('--url', dest='url', help='URL of file to be downloaded', required=True) parser.add_argument('--dir', dest='download_dir', help='directory to be downloaded to', required=True) diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py new file mode 100755 index 0000000000..ec6df17a6c --- /dev/null +++ b/indra/viewer_components/manager/update_manager.py @@ -0,0 +1,455 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ +# Copyright (c) 2013, Linden Research, Inc. + +""" +@file update_manager.py +@author coyot +@date 2016-05-16 +""" + +from llbase import llrest +from llbase import llsd +from urlparse import urljoin + +import apply_update +import download_update +import errno +import fnmatch +import hashlib +import InstallerUserMessage +import json +import os +import platform +import re +import shutil +import subprocess +import sys +import tempfile +import thread +import urllib + +def silent_write(log_file_handle, text): + #if we have a log file, write. If not, do nothing. + #this is so we don't have to keep trapping for an exception with a None handle + #oh and because it is best effort, it is also a holey_write ;) + if (log_file_handle): + #prepend text for easy grepping + log_file_handle.write("UPDATE MANAGER: " + text + "\n") + +def after_frame(my_message, timeout = 10000): + #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds + #note that this blocks the caller for the duration of timeout + frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") + #this is done before basic_message so that we aren't blocked by mainloop() + frame.after(timout, lambda: frame._delete_window) + frame.basic_message(message = my_message) + +def convert_version_file_style(version): + #converts a version string a.b.c.d to a_b_c_d as used in downloaded filenames + #re will throw a TypeError if it gets None, just return that. + try: + pattern = re.compile('\.') + return pattern.sub('_', version) + except TypeError, te: + return None + +def get_platform_key(): + #this is the name that is inserted into the VVM URI + #and carried forward through the rest of the updater to determine + #platform specific actions as appropriate + platform_dict = {'Darwin':'mac', 'Linux':'lnx', 'Windows':'win'} + platform_uname = platform.system() + try: + return platform_dict[platform_uname] + except KeyError: + return None + +def get_summary(platform_name, launcher_path): + #get the contents of the summary.json file. + #for linux and windows, this file is in the same directory as the script + #for mac, the script is in ../Contents/MacOS/ and the file is in ../Contents/Resources/ + script_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + if (platform_name == 'mac'): + summary_dir = os.path.abspath(os.path.join(script_dir, "../Resources")) + else: + summary_dir = script_dir + summary_file = os.path.join(summary_dir,"summary.json") + with open(summary_file) as summary_handle: + return json.load(summary_handle) + +def get_parent_path(platform_name): + #find the parent of the logs and user_settings directories + if (platform_name == 'mac'): + settings_dir = os.path.join(os.path.expanduser('~'),'Library','Application Support','SecondLife') + elif (platform_name == 'lnx'): + settings_dir = os.path.join(os.path.expanduser('~'),'.secondlife') + #using list format of join is important here because the Windows pathsep in a string escapes the next char + elif (platform_name == 'win'): + settings_dir = os.path.join(os.path.expanduser('~'),'AppData','Roaming','SecondLife') + else: + settings_dir = None + return settings_dir + +def make_download_dir(parent_dir, new_version): + #make a canonical download dir if it does not already exist + #format: ../user_settings/downloads/1.2.3.456789 + #we do this so that multiple viewers on the same host can update separately + #this also functions as a getter + try: + download_dir = os.path.join(parent_dir, "downloads", new_version) + os.makedirs(download_dir) + except OSError, hell: + #Directory already exists, that's okay. Other OSErrors are not okay. + if hell[0] == errno.EEXIST: + pass + else: + raise hell + return download_dir + +def check_for_completed_download(download_dir): + #there will be two files on completion, the download and a marker file called "".done"" + #for optional upgrades, there may also be a .skip file to skip this particular upgrade + #or .next to install on next run + completed = None + marker_regex = '*' + '.done' + skip_regex = '*' + '.skip' + next_regex = '*' + '.next' + for filename in os.listdir(download_dir): + if fnmatch.fnmatch(filename, marker_regex): + completed = 'done' + elif fnmatch.fnmatch(filename, skip_regex): + completed = 'skip' + elif fnmatch.fnmatch(filename, next_regex): + #so we don't skip infinitely + os.remove(filename) + completed = 'next' + if not completed: + #cleanup + shutil.rmtree(download_dir) + return completed + +def get_settings(log_file_handle, parent_dir): + #return the settings file parsed into a dict + try: + settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) + settings = llsd.parse((open(settings_file)).read()) + except llsd.LLSDParseError as lpe: + silent_write(log_file_handle, "Could not parse settings file %s" % lpe) + return None + return settings + +def get_log_file_handle(parent_dir): + #return a write handle on the log file + #plus log rotation and not dying on failure + log_file = os.path.join(parent_dir, 'update_manager.log') + old_file = log_file + '.old' + #if someone's log files are present but not writable, they've screwed up their install. + if os.access(log_file, os.W_OK): + if os.access(old_file, os.W_OK): + os.unlink(old_file) + os.rename(log_file, old_file) + elif not os.path.exists(log_file): + #reimplement TOUCH(1) in Python + #perms default to 644 which is fine + open(log_file, 'w+').close() + try: + f = open(log_file,'w+') + except Exception as e: + #we don't have a log file to write to, make a best effort and sally onward + print "Could not open update manager log file %s" % log_file + f = None + return f + +def make_VVM_UUID_hash(platform_key): + #NOTE: There is no python library support for a persistent machine specific UUID + # AND all three platforms do this a different way, so exec'ing out is really the best we can do + #Lastly, this is a best effort service. If we fail, we should still carry on with the update + uuid = None + if (platform_key == 'lnx'): + uuid = subprocess.check_output(['/usr/bin/hostid']).rstrip() + elif (platform_key == 'mac'): + #this is absurdly baroque + #/usr/sbin/system_profiler SPHardwareDataType | fgrep 'Serial' | awk '{print $NF}' + uuid = subprocess.check_output(["/usr/sbin/system_profiler", "SPHardwareDataType"]) + #findall[0] does the grep for the value we are looking for: "Serial Number (system): XXXXXXXX" + #split(:)[1] gets us the XXXXXXX part + #lstrip shaves off the leading space that was after the colon + uuid = re.split(":", re.findall('Serial Number \(system\): \S*', uuid)[0])[1].lstrip() + elif (platform_key == 'win'): + # wmic csproduct get UUID | grep -v UUID + uuid = subprocess.check_output(['wmic','csproduct','get','UUID']) + #outputs in two rows: + #UUID + #XXXXXXX-XXXX... + uuid = re.split('\n',uuid)[1].rstrip() + if uuid is not None: + return hashlib.md5(uuid).hexdigest() + else: + #fake it + return hashlib.md5(str(uuid.uuid1())).hexdigest() + +def query_vvm(log_file_handle, platform_key, settings, summary_dict): + result_data = None + #URI template /update/v1.1/channelname/version/platformkey/platformversion/willing-to-test/uniqueid + #https://wiki.lindenlab.com/wiki/Viewer_Version_Manager_REST_API#Viewer_Update_Query + base_URI = 'https://update.secondlife.com/update/' + channelname = summary_dict['Channel'] + #this is kind of a mess because the settings value a) in a map and b) is both the cohort and the version + version = summary_dict['Version'] + platform_version = platform.release() + #this will always return something usable, error handling in method + hashed_UUID = make_VVM_UUID_hash(platform_key) + #note that this will not normally be in a settings.xml file and is only here for test builds. + #for test builds, add this key to the ../user_settings/settings.xml + """ + test + + Comment + Tell update manager you aren't willing to test. + Type + String + Value + testno + + + """ + try: + test_ok = settings['test']['Value'] + except KeyError as ke: + #normal case, no testing key + test_ok = 'testok' + UUID = make_VVM_UUID_hash(platform_key) + #because urljoin can't be arsed to take multiple elements + query_string = '/v1.0/' + channelname + '/' + version + '/' + platform_key + '/' + platform_version + '/' + test_ok + '/' + UUID + VVMService = llrest.SimpleRESTService(name='VVM', baseurl=base_URI) + try: + result_data = VVMService.get(query_string) + except RESTError as re: + silent_write.write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string, re))) + return None + return result_data + +def download(url = None, version = None, download_dir = None, size = 0, background = False): + download_tries = 0 + download_success = False + #for background execution + path_to_downloader = os.path.join(os.path.dirname(os.path.realpath(__file__)), "download_update.py") + #three strikes and you're out + while download_tries < 3 and not download_success: + #323: Check for a partial update of the required update; in either event, display an alert that a download is required, initiate the download, and then install and launch + if download_tries == 0: + after_frame(message = "Downloading new version " + version + " Please wait.") + else: + after_frame(message = "Trying again to download new version " + version + " Please wait.") + if not background: + try: + download_update.download_update(url = url, download_dir = download_dir, size = size, progressbar = True) + download_success = True + except: + download_tries += 1 + silent_write(log_file_handle, "Failed to download new version " + version + ". Trying again.") + else: + try: + #Python does not have a facility to multithread a method, so we make the method a standalone + #and subprocess that + subprocess.call(path_to_downloader, "--url = %s --dir = %s --pb --size= %s" % (url, download_dir, size)) + download_success = True + except: + download_tries += 1 + silent_write(log_file_handle, "Failed to download new version " + version + ". Trying again.") + if not download_success: + silent_write(log_file_handle, "Failed to download new version " + version) + after_frame(message = "Failed to download new version " + version + " Please check connectivity.") + return False + return True + +def install(platform_key = None, download_dir = None, log_file_handle = None, in_place = None, downloaded = None): + #user said no to this one + if downloaded != 'skip': + after_frame(message = "New version downloaded. Installing now, please wait.") + success = apply_update.apply_update(download_dir, platform_key, log_file_handle, in_place) + if success: + silent_write(log_file_handle, "successfully updated to " + version) + shutil.rmtree(download_dir) + #this is either True for in place or the path to the new install for not in place + return success + else: + after_frame(message = "Failed to apply " + version) + silent_write(log_file_handle, "Failed to update viewer to " + version) + return False + +def download_and_install(downloaded = None, url = None, version = None, download_dir = None, size = None, platform_key = None, log_file_handle = None, in_place = None): + #extracted to a method because we do it twice in update_manager() and this makes the logic clearer + if not downloaded: + #do the download, exit if we fail + if not download(url = url, version = version, download_dir = download_dir, size = size): + return (False, 'download', version) + #do the install + path_to_new_launcher = install(platform_key = platform_key, download_dir = download_dir, + log_file_handle = log_file_handle, in_place = in_place, downloaded = downloaded) + if path_to_new_launcher: + #if we succeed, propagate the success type upwards + if in_place: + return (True, 'in place', True) + else: + return (True, 'in place', path_to_new_launcher) + else: + #propagate failure + return (False, 'apply', version) + +def update_manager(): + #comments that begin with '323:' are steps taken from the algorithm in the description of SL-323. + # Note that in the interest of efficiency, such as determining download success once at the top + # The code does follow precisely the same order as the algorithm. + #return values rather than exit codes. All of them are to communicate with launcher + #we print just before we return so that __main__ outputs something - returns are swallowed + # (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) + # (False, 'download', version): we failed to download the new version + # (False, 'apply', version): we failed to apply the new version + # (True, None, None): No update found + # (True, 'in place, True): update applied in place + # (True, 'in place', path_to_new_launcher): Update applied by a new install to a new location + # (True, 'background', True): background download initiated + + #setup and getting initial parameters + platform_key = get_platform_key() + parent_dir = get_parent_path(platform_key) + log_file_handle = get_log_file_handle(parent_dir) + + #check to see if user has install rights + #get the owner of the install and the current user + script_owner_id = os.stat(os.path.realpath(__file__)).st_uid + user_id = os.geteuid() + #if we are on lnx or mac, we can pretty print the IDs as names using the pwd module + #win does not provide this support and Python will throw an ImportError there, so just use raw IDs + if script_owner_id != user_id: + if platform_key != 'win': + import pwd + script_owner_name = pwd.getpwuid(script_owner_id)[0] + username = pwd.getpwuid(user_id)[0] + else: + username = user_id + script_owner_name = script_owner_id + silent_write(log_file_handle, "Upgrade notification attempted by userid " + username) + frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") + frame.binary_choice_message(message = "Second Life was installed by userid " + script_owner_name + + ". Do you have privileges to install?", true = "Yes", false = 'No') + if not frame.choice.get(): + silent_write(log_file_handle, "Upgrade attempt declined by userid " + username) + after_frame(message = "Please find a system admin to upgrade Second Life") + print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) + return (False, 'setup', None) + + settings = get_settings(log_file_handle, parent_dir) + if settings is None: + silent_write(log_file_handle, "Failed to load viewer settings") + print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) + return (False, 'setup', None) + + #323: If a complete download of that update is found, check the update preference: + #settings['UpdaterServiceSetting'] = 0 is manual install + """ + UpdaterServiceSetting + + Comment + Configure updater service. + Type + U32 + Value + 0 + + """ + try: + install_automatically = settings['UpdaterServiceSetting']['Value'] + #because, for some godforsaken reason, we delete the setting rather than changing the value + except KeyError: + install_automatically = 1 + + #get channel and version + try: + summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) + except: + silent_write(log_file_handle, "Could not obtain channel and version, exiting.") + print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) + return (False, 'setup', None) + + #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. + result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict) + #nothing to do or error + if not result_data: + silent_write.write(og_file_handle, "No update found.") + print "Update manager exited with (%s, %s, %s)" % (True, None, None) + return (True, None, None) + + #get download directory, if there are perm issues or similar problems, give up + try: + download_dir = make_download_dir(parent_dir, result_data['version']) + except Exception, e: + print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) + return (False, 'setup', None) + + #if the channel name of the response is the same as the channel we are launched from, the update is "in place" + #and launcher will launch the viewer in this install location. Otherwise, it will launch the Launcher from + #the new location and kill itself. + in_place = (summary_dict['Channel'] == result_data['channel']) + + #determine if we've tried this download before + downloaded = check_for_completed_download(download_dir) + + #323: If the response indicates that there is a required update: + if result_data['required'] or (not result_data['required'] and install_automatically): + #323: Check for a completed download of the required update; if found, display an alert, install the required update, and launch the newly installed viewer. + #323: If [optional download and] Install Automatically: display an alert, install the update and launch updated viewer. + return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, + size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place) + else: + #323: If the update response indicates that there is an optional update: + #323: Check to see if the optional update has already been downloaded. + #323: If a complete download of that update is found, check the update preference: + #note: automatic install handled above as the steps are the same as required upgrades + #323: If Install Manually: display a message with the update information and ask the user whether or not to install the update with three choices: + #323: Skip this update: create a marker that subsequent launches should not prompt for this update as long as it is optional, + # but leave the download in place so that if it becomes required it will be there. + #323: Install next time: create a marker that skips the prompt and installs on the next launch + #323: Install and launch now: do it. + if downloaded is not None and downloaded != 'skip': + frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") + #The choices are reordered slightly to encourage immediate install and slightly discourage skipping + frame.trinary_message(message = "Please make a selection", + one = "Install new version now.", two = 'Install the next time the viewer is launched.', three = 'Skip this update.') + choice = frame.choice.get() + if choice == 1: + return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, + size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place) + elif choice == 2: + tempfile.mkstmp(suffix = ".next", dir = download_dir) + return (True, None, None) + else: + tempfile.mkstmp(suffix = ".skip", dir = download_dir) + return (True, None, None) + else: + #multithread a download + download(url = result_data['url'], version = result_data['version'], download_dir = download_dir, size = result_data['size'], background = True) + print "Update manager exited with (%s, %s, %s)" % (True, 'background', True) + return (True, 'background', True) + + +if __name__ == '__main__': + #there is no argument parsing or other main() work to be done + update_manager() From f915751736bf2e40c56f7499d2a111f19dc7a6c0 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 11 Jul 2016 12:52:44 -0700 Subject: [PATCH 024/183] fix closing parens in CMakeLists.txt --- indra/newview/CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9ee7b656c0..cd7c58e97b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1774,7 +1774,8 @@ if (WINDOWS) --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher COMMENT "Performing pyinstaller compile of SL_Launcher" - +) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/apply_update.exe COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe @@ -1784,7 +1785,8 @@ if (WINDOWS) --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${CMAKE_SOURCE_DIR}/viewer_components/manager/apply_update.py COMMENT "Performing pyinstaller compile of updater" - +) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/download_update.exe COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe @@ -1794,7 +1796,8 @@ if (WINDOWS) --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} ${CMAKE_SOURCE_DIR}/viewer_components/manager/download_update.py COMMENT "Performing pyinstaller compile of update downloader" - +) + add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/update_manager.exe COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe From 8bf0890f212ced40e24995f8b4353c7cc7ad2053 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 11 Jul 2016 19:00:56 -0700 Subject: [PATCH 025/183] fix cmake add_custom_target --- indra/newview/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index cd7c58e97b..132b57eb44 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1810,9 +1810,9 @@ if (WINDOWS) ) add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) -add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/apply_update.exe) -add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/download_update.exe) -add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/update_manager.exe) +add_custom_target(compile_w_viewer_updater ALL DEPENDS ${CMAKE_CFG_INTDIR}/apply_update.exe) +add_custom_target(compile_w_viewer_downloader ALL DEPENDS ${CMAKE_CFG_INTDIR}/download_update.exe) +add_custom_target(compile_w_viewer_update_manager ALL DEPENDS ${CMAKE_CFG_INTDIR}/update_manager.exe) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat From 9c2633cba85f8dae95ff2b748a027dcfb7729848 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 13 Jul 2016 07:36:12 -0700 Subject: [PATCH 026/183] SL-323: adding in unit tests --- indra/viewer_components/manager/SL_Launcher | 90 +- .../manager/tests/data/settings.xml | 1184 +++++++++++++++++ .../manager/tests/summary.json | 1 + .../manager/tests/test_InstallerError.py | 39 + .../test_check_for_completed_download.py | 53 + .../tests/test_convert_version_file_style.py | 55 + .../manager/tests/test_get_filename.py | 60 + .../manager/tests/test_get_log_file_handle.py | 63 + .../manager/tests/test_get_parent_path.py | 79 ++ .../manager/tests/test_get_platform_key.py | 40 + .../manager/tests/test_get_settings.py | 82 ++ .../manager/tests/test_make_VVM_UUID_hash.py | 42 + .../manager/tests/test_make_download_dir.py | 42 + .../manager/tests/test_query_vvm.py | 67 + .../manager/tests/test_silent_write.py | 43 + .../manager/tests/test_summary.py | 39 + .../manager/tests/with_setup_args.py | 66 + .../manager/update_manager.py | 71 +- 18 files changed, 2093 insertions(+), 23 deletions(-) create mode 100644 indra/viewer_components/manager/tests/data/settings.xml create mode 100644 indra/viewer_components/manager/tests/summary.json create mode 100644 indra/viewer_components/manager/tests/test_InstallerError.py create mode 100644 indra/viewer_components/manager/tests/test_check_for_completed_download.py create mode 100644 indra/viewer_components/manager/tests/test_convert_version_file_style.py create mode 100644 indra/viewer_components/manager/tests/test_get_filename.py create mode 100644 indra/viewer_components/manager/tests/test_get_log_file_handle.py create mode 100644 indra/viewer_components/manager/tests/test_get_parent_path.py create mode 100644 indra/viewer_components/manager/tests/test_get_platform_key.py create mode 100644 indra/viewer_components/manager/tests/test_get_settings.py create mode 100644 indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py create mode 100644 indra/viewer_components/manager/tests/test_make_download_dir.py create mode 100644 indra/viewer_components/manager/tests/test_query_vvm.py create mode 100644 indra/viewer_components/manager/tests/test_silent_write.py create mode 100644 indra/viewer_components/manager/tests/test_summary.py create mode 100644 indra/viewer_components/manager/tests/with_setup_args.py diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index ecf88a1105..1d4c19fa86 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -18,8 +18,11 @@ # Copyright (c) 2013, Linden Research, Inc. import argparse +import collections import InstallerUserMessage +import llsd import os +import platform import sys import subprocess import update_manager @@ -31,7 +34,88 @@ def after_frame(my_message, timeout = 10000): #this is done before basic_message so that we aren't blocked by mainloop() frame.after(timout, lambda: frame._delete_window) frame.basic_message(message = my_message) + +def get_cmd_line(): + platform_name = platform.system() + #find the parent of the logs and user_settings directories + if (platform_name == 'mac'): + settings_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'Resources/app_settings/cmd_line.xml') + elif (platform_name == 'lnx'): + settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') + #using list format of join is important here because the Windows pathsep in a string escapes the next char + elif (platform_name == 'win'): + settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') + else: + settings_dir = None + + try: + cmd_line = llsd.parse((open(settings_file)).read()) + except: + cmd_line = None + + return cmd_line +def get_settings(): + #return the settings file parsed into a dict + try: + settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) + settings = llsd.parse((open(settings_file)).read()) + except llsd.LLSDParseError as lpe: + silent_write(log_file_handle, "Could not parse settings file %s" % lpe) + return None + return settings + + +def capture_vmp_args(arg_list = None, cmd_line = None): + #expected input format: arg_list = ['--set', 'foo', 'bar', '-X', '-Y', 'qux'] + #take a copy of the viewer parameters that are of interest to VMP. + #the regex for a parameter is -- {opt1} {opt2} + cli_overrides = {} + cmd_line = get_cmd_line() + + vmp_params = {'--channel':'channel', '--settings':'settings', '--update-service':'update-service', '--set':'set'} + #the settings set with --set. All such settings have only one argument. + vmp_setters = ('UpdaterMaximumBandwidth', 'UpdaterServiceCheckPeriod', 'UpdaterServicePath', 'UpdaterServiceSetting', 'UpdaterServiceURL', 'UpdaterWillingToTest') + + #Here turn the list into a queue, popping off the left as we go. Note that deque() makes a copy by value, not by reference + #Because of the complexity introduced by the uncertainty of how many options a parameter can take, this is far less complicated code than the more + #pythonic (x,y) = since we will sometimes have (x), sometimes (x,y) and sometimes (x,y,z) + #also, because the pop is destructive, we prevent ourselves from iterating back over list elements that iterator methods would peek ahead at + vmp_queue = collections.deque(arg_list) + while (len(vmp_queue)): + param = vmp_queue.popleft() + #if it is not one of ours, pop through args until we get to the next parameter + if param in vmp_params.keys(): + if param == '--set': + setting_name = vmp_queue.popleft() + setting_value = vmp_queue.popleft() + if setting_name in vmp_setters: + cli_overrides[vmp_params[param]] = (setting_name, setting_value) + else: + #find out how many args this parameter has + count = cmd_line[param]['count'] + param_args = [] + if count: + for argh in range(1,count): + param_args.append(vmp_queue.popleft()) + #the parameter name is the key, the (possibly empty) list of args is the value + cli_overrides[vmp_params[param]] = param_args + + #to prevent KeyErrors on missing keys, set the remainder to None + for key in vmp_params: + if key != '--set': + try: + cli_overrides[key] + except KeyError: + cli_overrides[key] = None + else: + for arg in vmp_setters: + try: + cli_overrides[key][arg] + except KeyError: + cli_overrides[key][arg] = None + return cli_overrides + cwd = os.path.dirname(os.path.realpath(__file__)) executable_name = "" @@ -58,11 +142,15 @@ viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),execu parser = argparse.ArgumentParser() args = parser.parse_known_args(sys.argv) +print args[1] +sys.exit() +#args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname args_list_to_pass = args[1][1:] +vmp_args = capture_vmp_args(args_list_to_pass) #make a copy by value, not by reference command = list(args_list_to_pass) -(success, state, condition) = update_manager.update_manager() +(success, state, condition) = update_manager.update_manager(cli_overrides) # From update_manager: # (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) # (False, 'download', version): we failed to download the new version diff --git a/indra/viewer_components/manager/tests/data/settings.xml b/indra/viewer_components/manager/tests/data/settings.xml new file mode 100644 index 0000000000..07e420dcb3 --- /dev/null +++ b/indra/viewer_components/manager/tests/data/settings.xml @@ -0,0 +1,1184 @@ + + + AllowMultipleViewers + + Comment + Allow multiple viewers. + Type + Boolean + Value + 1 + + AllowTapTapHoldRun + + Comment + Tapping a direction key twice and holding it down makes avatar run + Type + Boolean + Value + 0 + + AppearanceCameraMovement + + Comment + When entering appearance editing mode, camera zooms in on currently selected portion of avatar + Type + Boolean + Value + 0 + + AudioLevelMedia + + Comment + Audio level of Quicktime movies + Type + F32 + Value + 0.699999988079071044921875 + + AudioLevelMic + + Comment + Audio level of microphone input + Type + F32 + Value + 0.1749999970197677612304688 + + AudioLevelMusic + + Comment + Audio level of streaming music + Type + F32 + Value + 0 + + AudioLevelSFX + + Comment + Audio level of in-world sound effects + Type + F32 + Value + 0.699999988079071044921875 + + AudioLevelVoice + + Comment + Audio level of voice chat + Type + F32 + Value + 1 + + AudioStreamingMedia + + Comment + Enable streaming + Type + Boolean + Value + 0 + + AvatarAxisDeadZone0 + + Comment + Avatar axis 0 dead zone. + Type + F32 + Value + 0.1000000014901161193847656 + + AvatarAxisDeadZone1 + + Comment + Avatar axis 1 dead zone. + Type + F32 + Value + 0.1000000014901161193847656 + + AvatarAxisDeadZone2 + + Comment + Avatar axis 2 dead zone. + Type + F32 + Value + 0.1000000014901161193847656 + + AvatarAxisDeadZone3 + + Comment + Avatar axis 3 dead zone. + Type + F32 + Value + 1 + + AvatarAxisDeadZone4 + + Comment + Avatar axis 4 dead zone. + Type + F32 + Value + 0.01999999955296516418457031 + + AvatarAxisDeadZone5 + + Comment + Avatar axis 5 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + AvatarAxisScale3 + + Comment + Avatar axis 3 scaler. + Type + F32 + Value + 0 + + AvatarAxisScale4 + + Comment + Avatar axis 4 scaler. + Type + F32 + Value + 2 + + AvatarAxisScale5 + + Comment + Avatar axis 5 scaler. + Type + F32 + Value + 2 + + AvatarFeathering + + Comment + Avatar feathering (less is softer) + Type + F32 + Value + 6 + + AvatarFileName + + Comment + Alternative avatar file name + Type + String + Value + avatar_lad_tentacles.xml + + BuildAxisDeadZone0 + + Comment + Build axis 0 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisDeadZone1 + + Comment + Build axis 1 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisDeadZone2 + + Comment + Build axis 2 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisDeadZone3 + + Comment + Build axis 3 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisDeadZone4 + + Comment + Build axis 4 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisDeadZone5 + + Comment + Build axis 5 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + BuildAxisScale0 + + Comment + Build axis 0 scaler. + Type + F32 + Value + 6 + + BuildAxisScale1 + + Comment + Build axis 1 scaler. + Type + F32 + Value + 6 + + BuildAxisScale2 + + Comment + Build axis 2 scaler. + Type + F32 + Value + 6 + + BuildAxisScale3 + + Comment + Build axis 3 scaler. + Type + F32 + Value + 6 + + BuildAxisScale4 + + Comment + Build axis 4 scaler. + Type + F32 + Value + 6 + + BuildAxisScale5 + + Comment + Build axis 5 scaler. + Type + F32 + Value + 6 + + BuildFeathering + + Comment + Build feathering (less is softer) + Type + F32 + Value + 12 + + BulkChangeEveryoneCopy + + Comment + Bulk changed objects can be copied by everyone + Type + Boolean + Value + 1 + + BulkChangeNextOwnerCopy + + Comment + Bulk changed objects can be copied by next owner + Type + Boolean + Value + 1 + + BulkChangeNextOwnerModify + + Comment + Bulk changed objects can be modified by next owner + Type + Boolean + Value + 1 + + BulkChangeShareWithGroup + + Comment + Bulk changed objects are shared with the currently active group + Type + Boolean + Value + 1 + + CacheValidateCounter + + Comment + Used to distribute cache validation + Type + U32 + Value + 122 + + CameraPosOnLogout + + Comment + Camera position when last logged out (global coordinates) + Type + Vector3D + Value + + 288290.4477181434631347656 + 275988.5277819633483886719 + 49.10921102762222290039062 + + + ClickToWalk + + Comment + Click in world to walk to location + Type + Boolean + Value + 0 + + ConversationSortOrder + + Comment + Specifies sort key for conversations + Type + U32 + Value + 0 + + CurrentGrid + + Comment + Currently Selected Grid + Type + String + Value + util.agni.lindenlab.com + + Cursor3D + + Comment + Treat Joystick values as absolute positions (not deltas). + Type + Boolean + Value + 0 + + FirstLoginThisInstall + + Comment + Specifies that you have not logged in with the viewer since you performed a clean install + Type + Boolean + Value + 0 + + FirstRunThisInstall + + Comment + Specifies that you have not run the viewer since you performed a clean install + Type + Boolean + Value + 0 + + FlycamAxisDeadZone0 + + Comment + Flycam axis 0 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone1 + + Comment + Flycam axis 1 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone2 + + Comment + Flycam axis 2 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone3 + + Comment + Flycam axis 3 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone4 + + Comment + Flycam axis 4 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone5 + + Comment + Flycam axis 5 dead zone. + Type + F32 + Value + 0.009999999776482582092285156 + + FlycamAxisDeadZone6 + + Comment + Flycam axis 6 dead zone. + Type + F32 + Value + 1 + + FlycamAxisScale0 + + Comment + Flycam axis 0 scaler. + Type + F32 + Value + 42 + + FlycamAxisScale1 + + Comment + Flycam axis 1 scaler. + Type + F32 + Value + 40 + + FlycamAxisScale2 + + Comment + Flycam axis 2 scaler. + Type + F32 + Value + 40 + + FlycamAxisScale3 + + Comment + Flycam axis 3 scaler. + Type + F32 + Value + 0 + + FlycamAxisScale4 + + Comment + Flycam axis 4 scaler. + Type + F32 + Value + 2 + + FlycamAxisScale5 + + Comment + Flycam axis 5 scaler. + Type + F32 + Value + 3 + + FlycamAxisScale6 + + Comment + Flycam axis 6 scaler. + Type + F32 + Value + 0 + + FlycamFeathering + + Comment + Flycam feathering (less is softer) + Type + F32 + Value + 5 + + FocusPosOnLogout + + Comment + Camera focus point when last logged out (global coordinates) + Type + Vector3D + Value + + 288287.8830481640761718154 + 275991.5973855691263452172 + 47.96361158013021963597566 + + + ForceShowGrid + + Comment + Always show grid dropdown on login screen + Type + Boolean + Value + 1 + + HttpProxyType + + Comment + Proxy type to use for HTTP operations + Type + String + Value + None + + JoystickInitialized + + Comment + Whether or not a joystick has been detected and initiailized. + Type + String + Value + UnknownDevice + + LSLFindCaseInsensitivity + + Comment + Use case insensitivity when searching in LSL editor + Type + Boolean + Value + 1 + + LastFeatureVersion + + Comment + [DO NOT MODIFY] Feature Table Version number for tracking rendering system changes + Type + S32 + Value + 37 + + LastGPUString + + Comment + [DO NOT MODIFY] previous GPU id string for tracking hardware changes + Type + String + Value + NVIDIA Corporation NVIDIA GeForce GT 750M OpenGL Engine + + LastPrefTab + + Comment + Last selected tab in preferences window + Type + S32 + Value + 1 + + LastRunVersion + + Comment + Version number of last instance of the viewer that you ran + Type + String + Value + Second Life Project Bento 5.0.0.315657 + + LocalCacheVersion + + Comment + Version number of cache + Type + S32 + Value + 7 + + LoginLocation + + Comment + Default Login location ('last', 'home') preference + Type + String + Value + home + + MapScale + + Comment + World map zoom level (pixels per region) + Type + F32 + Value + 256 + + MaxJointsPerMeshObject + + Comment + Maximum joints per rigged mesh object + Type + U32 + Value + 51 + + MediaEnablePopups + + Comment + If true, enable targeted links and javascript in media to open new media browser windows without a prompt. + Type + Boolean + Value + 1 + + MediaShowOnOthers + + Comment + Whether or not to show media on other avatars + Type + Boolean + Value + 1 + + MigrateCacheDirectory + + Comment + Check for old version of disk cache to migrate to current location + Type + Boolean + Value + 0 + + NavBarShowParcelProperties + + Comment + Show parcel property icons in navigation bar + Type + Boolean + Value + 0 + + NextLoginLocation + + Comment + Location to log into for this session - set from command line or the login panel, cleared following a successfull login. + Type + String + Value + home + + NotificationConferenceIMOptions + + Comment + + Specifies how the UI responds to Conference IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + + Type + String + Value + none + + NotificationFriendIMOptions + + Comment + + Specifies how the UI responds to Friend IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + + Type + String + Value + openconversations + + NotificationGroupChatOptions + + Comment + + Specifies how the UI responds to Group Chat Notifications. + Allowed values: [openconversations,toast,flash,noaction] + + Type + String + Value + none + + NotificationNearbyChatOptions + + Comment + + Specifies how the UI responds to Nearby Chat Notifications. + Allowed values: [openconversations,toast,flash,noaction] + + Type + String + Value + none + + NotificationNonFriendIMOptions + + Comment + + Specifies how the UI responds to Non Friend IM Notifications. + Allowed values: [openconversations,toast,flash,noaction] + + Type + String + Value + openconversations + + NumSessions + + Comment + Number of successful logins to Second Life + Type + S32 + Value + 1674 + + PlayTypingAnim + + Comment + Your avatar plays the typing animation whenever you type in the chat bar + Type + Boolean + Value + 0 + + PoolSizeExpCache + + Comment + Coroutine Pool size for ExpCache + Type + U32 + Value + 5 + + PreferredBrowserBehavior + + Comment + Use system browser for any links (0), use builtin browser for SL links and system one for others (1) or use builtin browser only (2). + Type + U32 + Value + 0 + + PreferredMaturity + + Comment + Setting for the user's preferred maturity level (consts in indra_constants.h) + Type + U32 + Value + 42 + + PresetGraphicActive + + Comment + Name of currently selected preference + Type + String + Value + Default + + ProbeHardwareOnStartup + + Comment + Query current hardware configuration on application startup + Type + Boolean + Value + 0 + + QAMode + + Comment + Enable Testing Features. + Type + Boolean + Value + 1 + + RenderAnisotropic + + Comment + Render textures using anisotropic filtering + Type + Boolean + Value + 1 + + RenderAvatarCloth + + Comment + Controls if avatars use wavy cloth + Type + Boolean + Value + 0 + + RenderAvatarLODFactor + + Comment + Controls level of detail of avatars (multiplier for current screen area when calculated level of detail) + Type + F32 + Value + 1 + + RenderFSAASamples + + Comment + Number of samples to use for FSAA (0 = no AA). + Type + U32 + Value + 2 + + RenderFarClip + + Comment + Distance of far clip plane from camera (meters) + Type + F32 + Value + 128 + + RenderMaxPartCount + + Comment + Maximum number of particles to display on screen + Type + S32 + Value + 2048 + + RenderQualityPerformance + + Comment + Which graphics settings you've chosen + Type + U32 + Value + 4 + + RenderReflectionDetail + + Comment + Detail of reflection render pass. + Type + S32 + Value + 0 + + RenderTerrainLODFactor + + Comment + Controls level of detail of terrain (multiplier for current screen area when calculated level of detail) + Type + F32 + Value + 2 + + RenderVBOEnable + + Comment + Use GL Vertex Buffer Objects + Type + Boolean + Value + 0 + + RenderVolumeLODFactor + + Comment + Controls level of detail of primitives (multiplier for current screen area when calculated level of detail) + Type + F32 + Value + 1.125 + + ShowAdvancedGraphicsSettings + + Comment + Show advanced graphics settings + Type + Boolean + Value + 1 + + ShowBanLines + + Comment + Show in-world ban/access borders + Type + Boolean + Value + 0 + + ShowStartLocation + + Comment + Display starting location menu on login screen + Type + Boolean + Value + 1 + + SkeletonFileName + + Comment + Alternative skeleton file name + Type + String + Value + avatar_skeleton_tentacles.xml + + SkyPresetName + + Comment + Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName). + Type + String + Value + Sunset + + SnapshotConfigURL + + Comment + URL to fetch Snapshot Sharing configuration data from. + Type + String + Value + http://photos.apps.avatarsunited.com/viewer_config + + SnapshotFormat + + Comment + Save snapshots in this format (0 = PNG, 1 = JPEG, 2 = BMP) + Type + S32 + Value + 1 + + SnapshotQuality + + Comment + Quality setting of postcard JPEGs (0 = worst, 100 = best) + Type + S32 + Value + 100 + + SpellCheck + + Comment + Enable spellchecking on line and text editors + Type + Boolean + Value + 0 + + SpellCheckDictionary + + Comment + Current primary and secondary dictionaries used for spell checking + Type + String + Value + English (United States) + + TextureMemory + + Comment + Amount of memory to use for textures in MB (0 = autodetect) + Type + S32 + Value + 256 + + UseDayCycle + + Comment + Whether to use use a day cycle or a fixed sky. + Type + Boolean + Value + 0 + + UseDebugMenus + + Comment + Turns on "Debug" menu + Type + Boolean + Value + 1 + + UseEnvironmentFromRegion + + Comment + Choose whether to use the region's environment settings, or override them with the local settings. + Type + Boolean + Value + 0 + + VFSOldSize + + Comment + [DO NOT MODIFY] Controls resizing of local file cache + Type + U32 + Value + 102 + + VFSSalt + + Comment + [DO NOT MODIFY] Controls local file caching behavior + Type + U32 + Value + 260093998 + + VersionChannelName + + Comment + Version information generated by running the viewer + Type + String + Value + Second Life Release + + VertexShaderEnable + + Comment + Enable/disable all GLSL shaders (debug) + Type + Boolean + Value + 1 + + VoiceInputAudioDevice + + Comment + Audio input device to use for voice + Type + String + Value + C-Media USB Audio Device + + VoiceOutputAudioDevice + + Comment + Audio output device to use for voice + Type + String + Value + C-Media USB Audio Device + + WLSkyDetail + + Comment + Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies. + Type + U32 + Value + 48 + + WebProfileFloaterRect + + Comment + Web profile floater dimensions + Type + Rect + Value + + 1189 + 957 + 1674 + 277 + + + WindowHeight + + Comment + SL viewer window height + Type + U32 + Value + 1000 + + WindowWidth + + Comment + SL viewer window width + Type + U32 + Value + 1626 + + WindowX + + Comment + X coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels) + Type + S32 + Value + 50 + + WindowY + + Comment + Y coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels) + Type + S32 + Value + 50 + + + diff --git a/indra/viewer_components/manager/tests/summary.json b/indra/viewer_components/manager/tests/summary.json new file mode 100644 index 0000000000..b78859d427 --- /dev/null +++ b/indra/viewer_components/manager/tests/summary.json @@ -0,0 +1 @@ +{"Type":"viewer","Version":"4.0.5.315117","Channel":"Second Life Release"} diff --git a/indra/viewer_components/manager/tests/test_InstallerError.py b/indra/viewer_components/manager/tests/test_InstallerError.py new file mode 100644 index 0000000000..d722208b7f --- /dev/null +++ b/indra/viewer_components/manager/tests/test_InstallerError.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_InstallerError.py +@author coyot +@date 2016-06-01 +""" + +from nose.tools import assert_equal + +import InstallerError +import os + +def test_InstallerError(): + try: + #try to make our own homedir, this will fail on all three platforms + homedir = os.path.abspath(os.path.expanduser('~')) + os.mkdir(homedir) + except OSError, oe: + ie = InstallerError.InstallerError(oe, "Installer failed to create a homedir that already exists.") + + assert_equal( str(ie), + "[Errno [Errno 17] File exists: '%s'] Installer failed to create a homedir that already exists." % homedir) diff --git a/indra/viewer_components/manager/tests/test_check_for_completed_download.py b/indra/viewer_components/manager/tests/test_check_for_completed_download.py new file mode 100644 index 0000000000..388bc900e9 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_check_for_completed_download.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_check_for_completed_download.py +@author coyot +@date 2016-06-03 +""" + +from nose.tools import * +from nose import with_setup + +import os +import shutil +import tempfile +import update_manager +import with_setup_args + +def check_for_completed_download_setup(): + tmpdir1 = tempfile.mkdtemp(prefix = 'test1') + tmpdir2 = tempfile.mkdtemp(prefix = 'test2') + tempfile.mkstemp(suffix = '.done', dir = tmpdir1) + + return [tmpdir1,tmpdir2], {} + +def check_for_completed_download_teardown(tmpdir1,tmpdir2): + shutil.rmtree(tmpdir1, ignore_errors = True) + shutil.rmtree(tmpdir2, ignore_errors = True) + +@with_setup_args.with_setup_args(check_for_completed_download_setup, check_for_completed_download_teardown) +def test_completed_check_for_completed_download(tmpdir1,tmpdir2): + assert_equal(update_manager.check_for_completed_download(tmpdir1), 'done'), "Failed to find completion marker" + +@with_setup_args.with_setup_args(check_for_completed_download_setup, check_for_completed_download_teardown) +def test_incomplete_check_for_completed_download(tmpdir1,tmpdir2): + #should return False + incomplete = not update_manager.check_for_completed_download(tmpdir2) + assert incomplete, "False positive, should not mark complete without a marker" \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_convert_version_file_style.py b/indra/viewer_components/manager/tests/test_convert_version_file_style.py new file mode 100644 index 0000000000..d700f91b84 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_convert_version_file_style.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_convert_version_file_style.py +@author coyot +@date 2016-06-01 +""" + +from nose.tools import assert_equal + +import update_manager + +def test_normal_form(): + version = '1.2.3.456789' + golden = '1_2_3_456789' + converted = update_manager.convert_version_file_style(version) + + assert_equal(golden, converted) + +def test_short_form(): + version = '1.23' + golden = '1_23' + converted = update_manager.convert_version_file_style(version) + + assert_equal(golden, converted) + +def test_idempotent(): + version = '123' + golden = '123' + converted = update_manager.convert_version_file_style(version) + + assert_equal(golden, converted) + +def test_none(): + version = None + golden = None + converted = update_manager.convert_version_file_style(version) + + assert_equal(golden, converted) \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_filename.py b/indra/viewer_components/manager/tests/test_get_filename.py new file mode 100644 index 0000000000..95771d75dc --- /dev/null +++ b/indra/viewer_components/manager/tests/test_get_filename.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_get_filename.py +@author coyot +@date 2016-06-30 +""" + +from nose.tools import * +from nose import with_setup + +import os +import shutil +import tempfile +import apply_update +import with_setup_args + +def get_filename_setup(): + tmpdir1 = tempfile.mkdtemp(prefix = 'lnx') + tmpdir2 = tempfile.mkdtemp(prefix = 'mac') + tmpdir3 = tempfile.mkdtemp(prefix = 'win') + tmpdir4 = tempfile.mkdtemp(prefix = 'bad') + tempfile.mkstemp(suffix = '.bz2', dir = tmpdir1) + tempfile.mkstemp(suffix = '.dmg', dir = tmpdir2) + tempfile.mkstemp(suffix = '.exe', dir = tmpdir3) + + return [tmpdir1,tmpdir2, tmpdir3, tmpdir4], {} + +def get_filename_teardown(tmpdir1,tmpdir2, tmpdir3, tmpdir4): + shutil.rmtree(tmpdir1, ignore_errors = True) + shutil.rmtree(tmpdir2, ignore_errors = True) + shutil.rmtree(tmpdir3, ignore_errors = True) + shutil.rmtree(tmpdir4, ignore_errors = True) + +@with_setup_args.with_setup_args(get_filename_setup, get_filename_teardown) +def test_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): + assert_is_not_none(apply_update.get_filename(tmpdir1)), "Failed to find installable" + assert_is_not_none(apply_update.get_filename(tmpdir2)), "Failed to find installable" + assert_is_not_none(apply_update.get_filename(tmpdir3)), "Failed to find installable" + +@with_setup_args.with_setup_args(get_filename_setup, get_filename_teardown) +def test_missing_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): + not_found = not apply_update.get_filename(tmpdir4) + assert not_found, "False positive, should not find an installable in an empty dir" \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_log_file_handle.py b/indra/viewer_components/manager/tests/test_get_log_file_handle.py new file mode 100644 index 0000000000..c5b3c89550 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_get_log_file_handle.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_get_log_file_handle.py +@author coyot +@date 2016-06-08 +""" + +from nose.tools import * + +import os +import shutil +import tempfile +import update_manager +import with_setup_args + +def get_log_file_handle_setup(): + tmpdir1 = tempfile.mkdtemp(prefix = 'test1') + tmpdir2 = tempfile.mkdtemp(prefix = 'test2') + log_file_path = os.path.abspath(os.path.join(tmpdir1,"update_manager.log")) + #not using tempfile because we want a particular filename + open(log_file_path, 'w+').close + + return [tmpdir1,tmpdir2,log_file_path], {} + +def get_log_file_handle_teardown(tmpdir1,tmpdir2,log_file_path): + shutil.rmtree(tmpdir1, ignore_errors = True) + shutil.rmtree(tmpdir2, ignore_errors = True) + +@with_setup_args.with_setup_args(get_log_file_handle_setup, get_log_file_handle_teardown) +def test_existing_get_log_file_handle(tmpdir1,tmpdir2,log_file_path): + handle = update_manager.get_log_file_handle(tmpdir1) + if not handle: + print "Failed to find existing log file" + assert False + elif not os.path.exists(os.path.abspath(log_file_path+".old")): + print "Failed to rotate update manager log" + assert False + assert True + +@with_setup_args.with_setup_args(get_log_file_handle_setup, get_log_file_handle_teardown) +def test_missing_get_log_file_handle(tmpdir1,tmpdir2,log_file_path): + handle = update_manager.get_log_file_handle(tmpdir2) + if not os.path.exists(log_file_path): + print "Failed to touch new log file" + assert False + assert True \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_parent_path.py b/indra/viewer_components/manager/tests/test_get_parent_path.py new file mode 100644 index 0000000000..3cfd72310e --- /dev/null +++ b/indra/viewer_components/manager/tests/test_get_parent_path.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_get_parent_path.py +@author coyot +@date 2016-06-02 +""" + +from nose.tools import * +from nose import with_setup + +import os +import shutil +import update_manager +import with_setup_args + +def get_parent_path_setup(): + key = update_manager.get_platform_key() + try: + if key == 'mac': + settings_dir = os.path.join(os.path.expanduser('~'),'Library','Application Support','SecondLife') + elif key == 'lnx': + settings_dir = os.path.join(os.path.expanduser('~'),'.secondlife') + elif key == 'win': + settings_dir = os.path.join(os.path.expanduser('~'),'AppData','Roaming','SecondLife') + else: + raise Exception("Invalid Platform Key") + + #preserve existing settings dir if any + if os.path.exists(settings_dir): + old_dir = settings_dir + ".tmp" + if os.path.exists(old_dir): + shutil.rmtree(old_dir, ignore_errors = True) + os.rename(settings_dir, old_dir) + os.makedirs(settings_dir) + except Exception, e: + print "get_parent_path_setup failed due to: %s" % str(e) + assert False + + #this is we don't have to rediscover settings_dir for test and teardown + return [settings_dir], {} + +def get_parent_path_teardown(settings_dir): + try: + shutil.rmtree(settings_dir, ignore_errors = True) + #restore previous settings dir if any + old_dir = settings_dir + ".tmp" + if os.path.exists(old_dir): + os.rename(old_dir, settings_dir) + except: + #cleanup is best effort + pass + +@with_setup_args.with_setup_args(get_parent_path_setup, get_parent_path_teardown) +def test_get_parent_path(settings_dir): + key = update_manager.get_platform_key() + got_settings_dir = update_manager.get_parent_path(key) + + assert settings_dir, "test_get_parent_path failed to obtain parent path" + + assert_equal(settings_dir, got_settings_dir) + + \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_platform_key.py b/indra/viewer_components/manager/tests/test_get_platform_key.py new file mode 100644 index 0000000000..37c570532c --- /dev/null +++ b/indra/viewer_components/manager/tests/test_get_platform_key.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_get_platform_key.py +@author coyot +@date 2016-06-01 +""" + +from nose.tools import assert_equal + +import platform +import update_manager + +def test_get_platform_key(): + key = update_manager.get_platform_key() + if key == 'mac': + assert_equal(platform.system(),'Darwin') + elif key == 'lnx': + assert_equal(platform.system(),'Linux') + elif key == 'win': + assert_equal(platform.system(),'Windows') + else: + assert_equal(key, None) + \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_settings.py b/indra/viewer_components/manager/tests/test_get_settings.py new file mode 100644 index 0000000000..46b779cbd5 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_get_settings.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_get_settings.py +@author coyot +@date 2016-06-03 +""" + +from nose.tools import * +from nose import with_setup + +import os +import shutil +import update_manager +import with_setup_args + +def get_settings_setup(): + try: + key = update_manager.get_platform_key() + settings_dir = os.path.join(update_manager.get_parent_path(key), "user_settings") + print settings_dir + + #preserve existing settings dir if any + if os.path.exists(settings_dir): + old_dir = settings_dir + ".tmp" + if os.path.exists(old_dir): + shutil.rmtree(old_dir, ignore_errors = True) + os.rename(settings_dir, old_dir) + os.makedirs(settings_dir) + + #the data subdir of the tests dir that this script is in + data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data") + #the test settings file + settings_file = os.path.join(data_dir, "settings.xml") + shutil.copyfile(settings_file, os.path.join(settings_dir, "settings.xml")) + + except Exception, e: + print "get_settings_setup failed due to: %s" % str(e) + assert False + + #this is we don't have to rediscover settings_dir for test and teardown + return [settings_dir], {} + +def get_settings_teardown(settings_dir): + try: + shutil.rmtree(settings_dir, ignore_errors = True) + #restore previous settings dir if any + old_dir = settings_dir + ".tmp" + if os.path.exists(old_dir): + os.rename(old_dir, settings_dir) + except: + #cleanup is best effort + pass + +@with_setup_args.with_setup_args(get_settings_setup, get_settings_teardown) +def test_get_settings(settings_dir): + key = update_manager.get_platform_key() + parent = update_manager.get_parent_path(key) + log_file = update_manager.get_log_file_handle(parent) + got_settings = update_manager.get_settings(log_file, parent) + + assert got_settings, "test_get_settings failed to find a settings.xml file" + + #test one key just to make sure it parsed + assert_equal(got_settings['CurrentGrid']['Value'], 'util.agni.lindenlab.com') + diff --git a/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py b/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py new file mode 100644 index 0000000000..513502a6ca --- /dev/null +++ b/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_make_VVM_UUID_hash.py +@author coyot +@date 2016-06-03 +""" + +from nose.tools import * + +import update_manager + +def test_make_VVM_UUID_hash(): + #because the method returns different results on different hosts + #it is not easy to unit test it reliably. + #About the best we can do is check for the exception from subprocess + key = update_manager.get_platform_key() + try: + UUID_hash = update_manager.make_VVM_UUID_hash(key) + except Exception, e: + print "Test failed due to: %s" % str(e) + assert False + + #make_UUID_hash returned None + assert UUID_hash, "make_UUID_hash failed to make a hash." + diff --git a/indra/viewer_components/manager/tests/test_make_download_dir.py b/indra/viewer_components/manager/tests/test_make_download_dir.py new file mode 100644 index 0000000000..5198a6de05 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_make_download_dir.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_make_download_dir.py +@author coyot +@date 2016-06-03 +""" + +from nose.tools import * + +import update_manager + +def test_make_download_dir(): + key = update_manager.get_platform_key() + path = update_manager.get_parent_path(key) + version = '1.2.3.456789' + try: + download_dir = update_manager.make_download_dir(path, version) + except OSError, e: + print "make_download_dir failed to eat OSError %s" % str(e) + assert False + except Exception, e: + print "make_download_dir raised an unexpected exception %s" % str(e) + assert False + + assert download_dir, "make_download_dir returned None for path %s and version %s" % (path, version) \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_query_vvm.py b/indra/viewer_components/manager/tests/test_query_vvm.py new file mode 100644 index 0000000000..40a0f7b215 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_query_vvm.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_query_vvm.py +@author coyot +@date 2016-06-08 +""" + +from nose.tools import * + +import os +import re +import shutil +import tempfile +import update_manager +import with_setup_args + +def query_vvm_setup(): + tmpdir1 = tempfile.mkdtemp(prefix = 'test1') + handle = update_manager.get_log_file_handle(tmpdir1) + + return [tmpdir1,handle], {} + +def query_vvm_teardown(tmpdir1, handle): + shutil.rmtree(tmpdir1, ignore_errors = True) + +@with_setup_args.with_setup_args(query_vvm_setup, query_vvm_teardown) +def test_query_vvm(tmpdir1, handle): + key = update_manager.get_platform_key() + parent = update_manager.get_parent_path(key) + settings = update_manager.get_settings(handle, parent) + launcher_path = os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))) + summary = update_manager.get_summary(key, launcher_path) + + #for unit testing purposes, just testing a value from results. If no update, then None and it falls through + #for formal QA see: + # https://docs.google.com/document/d/1WNjOPdKlq0j_7s7gdNe_3QlyGnQDa3bFNvtyVM6Hx8M/edit + # https://wiki.lindenlab.com/wiki/Login_Test#Test_Viewer_Updater + #for test plans on all cases, as it requires setting up a fake VVM service + + try: + results = update_manager.query_vvm(handle, key, settings, summary) + except Exception, e: + print "query_vvm threw unexpected exception %s" % str(e) + assert False + + if results: + pattern = re.compile('Second Life') + assert pattern.search(results['channel']), "Bad results returned %s" % str(results) + + assert True diff --git a/indra/viewer_components/manager/tests/test_silent_write.py b/indra/viewer_components/manager/tests/test_silent_write.py new file mode 100644 index 0000000000..a55665799f --- /dev/null +++ b/indra/viewer_components/manager/tests/test_silent_write.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_silent_write.py +@author coyot +@date 2016-06-02 +""" + +from nose.tools import * + +import tempfile +import update_manager + +def test_silent_write_to_file(): + test_log = tempfile.TemporaryFile() + try: + update_manager.silent_write(test_log, "This is a test.") + except Exception, e: + print "Test failed due to: %s" % str(e) + assert False + +def test_silent_write_to_null(): + try: + update_manager.silent_write(None, "This is a test.") + except Exception, e: + print "Test failed due to: %s" % str(e) + assert False \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_summary.py b/indra/viewer_components/manager/tests/test_summary.py new file mode 100644 index 0000000000..b318012b54 --- /dev/null +++ b/indra/viewer_components/manager/tests/test_summary.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + +""" +@file test_summary.py +@author coyot +@date 2016-06-02 +""" + +from nose.tools import * + +import os.path +import tempfile +import update_manager + +def test_get_summary(): + key = update_manager.get_platform_key() + #launcher is one dir above tests + launcher_path = os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))) + summary_json = update_manager.get_summary(key, launcher_path) + + #we aren't testing the JSON library, one key pair is enough + #so we will use the one pair that is actually a constant + assert_equal(summary_json['Type'],'viewer') \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/with_setup_args.py b/indra/viewer_components/manager/tests/with_setup_args.py new file mode 100644 index 0000000000..38350ab8c4 --- /dev/null +++ b/indra/viewer_components/manager/tests/with_setup_args.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python + +# $LicenseInfo:firstyear=2016&license=internal$ +# +# Copyright (c) 2016, Linden Research, Inc. +# +# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +# this source code is governed by the Linden Lab Source Code Disclosure +# Agreement ("Agreement") previously entered between you and Linden +# Lab. By accessing, using, copying, modifying or distributing this +# software, you acknowledge that you have been informed of your +# obligations under the Agreement and agree to abide by those obligations. +# +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ +# +# Taken from: https://gist.github.com/garyvdm/392ae20c673c7ee58d76 + +""" +@file with_setup_args.py +@author garyvdm +@date 2016-06-02 +""" + + +def with_setup_args(setup, teardown=None): + """Decorator to add setup and/or teardown methods to a test function:: + @with_setup_args(setup, teardown) + def test_something(): + " ... " + The setup function should return (args, kwargs) which will be passed to + test function, and teardown function. + Note that `with_setup_args` is useful *only* for test functions, not for test + methods or inside of TestCase subclasses. + """ + def decorate(func): + args = [] + kwargs = {} + + def test_wrapped(): + func(*args, **kwargs) + + test_wrapped.__name__ = func.__name__ + + def setup_wrapped(): + a, k = setup() + args.extend(a) + kwargs.update(k) + if hasattr(func, 'setup'): + func.setup() + test_wrapped.setup = setup_wrapped + + if teardown: + def teardown_wrapped(): + if hasattr(func, 'teardown'): + func.teardown() + teardown(*args, **kwargs) + + test_wrapped.teardown = teardown_wrapped + else: + if hasattr(func, 'teardown'): + test_wrapped.teardown = func.teardown() + return test_wrapped + return decorate \ No newline at end of file diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index ec6df17a6c..a7e0a19aef 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -204,11 +204,14 @@ def make_VVM_UUID_hash(platform_key): #fake it return hashlib.md5(str(uuid.uuid1())).hexdigest() -def query_vvm(log_file_handle, platform_key, settings, summary_dict): +def query_vvm(log_file_handle = None, platform_key = None, settings = None, summary_dict = None, UpdaterServiceURL = None, UpdaterWillingToTest = None): result_data = None #URI template /update/v1.1/channelname/version/platformkey/platformversion/willing-to-test/uniqueid #https://wiki.lindenlab.com/wiki/Viewer_Version_Manager_REST_API#Viewer_Update_Query - base_URI = 'https://update.secondlife.com/update/' + if UpdaterServiceURL: + baseURI = UpdaterServiceURL + else: + base_URI = 'https://update.secondlife.com/update/' channelname = summary_dict['Channel'] #this is kind of a mess because the settings value a) in a map and b) is both the cohort and the version version = summary_dict['Version'] @@ -229,11 +232,17 @@ def query_vvm(log_file_handle, platform_key, settings, summary_dict): """ - try: - test_ok = settings['test']['Value'] - except KeyError as ke: - #normal case, no testing key - test_ok = 'testok' + if UpdaterWillingToTest is not None: + if UpdaterWillingToTest: + test_ok = 'testok' + else: + test_ok = 'testno' + else: + try: + test_ok = settings['test']['Value'] + except KeyError: + #normal case, no testing key + test_ok = 'testok' UUID = make_VVM_UUID_hash(platform_key) #because urljoin can't be arsed to take multiple elements query_string = '/v1.0/' + channelname + '/' + version + '/' + platform_key + '/' + platform_version + '/' + test_ok + '/' + UUID @@ -245,7 +254,7 @@ def query_vvm(log_file_handle, platform_key, settings, summary_dict): return None return result_data -def download(url = None, version = None, download_dir = None, size = 0, background = False): +def download(url = None, version = None, download_dir = None, size = 0, background = False, chunk_size = 1024): download_tries = 0 download_success = False #for background execution @@ -259,7 +268,7 @@ def download(url = None, version = None, download_dir = None, size = 0, backgrou after_frame(message = "Trying again to download new version " + version + " Please wait.") if not background: try: - download_update.download_update(url = url, download_dir = download_dir, size = size, progressbar = True) + download_update.download_update(url = url, download_dir = download_dir, size = size, progressbar = True, chunk_size = chunk_size) download_success = True except: download_tries += 1 @@ -268,7 +277,7 @@ def download(url = None, version = None, download_dir = None, size = 0, backgrou try: #Python does not have a facility to multithread a method, so we make the method a standalone #and subprocess that - subprocess.call(path_to_downloader, "--url = %s --dir = %s --pb --size= %s" % (url, download_dir, size)) + subprocess.call(path_to_downloader, "--url = %s --dir = %s --pb --size = %s --chunk_size = %s" % (url, download_dir, size, chunk_size)) download_success = True except: download_tries += 1 @@ -294,11 +303,12 @@ def install(platform_key = None, download_dir = None, log_file_handle = None, in silent_write(log_file_handle, "Failed to update viewer to " + version) return False -def download_and_install(downloaded = None, url = None, version = None, download_dir = None, size = None, platform_key = None, log_file_handle = None, in_place = None): +def download_and_install(downloaded = None, url = None, version = None, download_dir = None, size = None, + platform_key = None, log_file_handle = None, in_place = None, chunk_size = 1024): #extracted to a method because we do it twice in update_manager() and this makes the logic clearer if not downloaded: #do the download, exit if we fail - if not download(url = url, version = version, download_dir = download_dir, size = size): + if not download(url = url, version = version, download_dir = download_dir, size = size, chunk_size = chunk_size): return (False, 'download', version) #do the install path_to_new_launcher = install(platform_key = platform_key, download_dir = download_dir, @@ -313,7 +323,8 @@ def download_and_install(downloaded = None, url = None, version = None, download #propagate failure return (False, 'apply', version) -def update_manager(): +def update_manager(cli_overrides = None): + #cli_overrides is a dict where the keys are specific parameters of interest and the values are the arguments to #comments that begin with '323:' are steps taken from the algorithm in the description of SL-323. # Note that in the interest of efficiency, such as determining download success once at the top # The code does follow precisely the same order as the algorithm. @@ -356,7 +367,11 @@ def update_manager(): print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) return (False, 'setup', None) - settings = get_settings(log_file_handle, parent_dir) + if cli_overrides['settings'] is not None: + settings = get_settings(log_file_handle, cli_overrides['settings']) + else: + settings = get_settings(log_file_handle, parent_dir) + if settings is None: silent_write(log_file_handle, "Failed to load viewer settings") print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) @@ -375,22 +390,34 @@ def update_manager(): 0 """ - try: - install_automatically = settings['UpdaterServiceSetting']['Value'] - #because, for some godforsaken reason, we delete the setting rather than changing the value - except KeyError: - install_automatically = 1 + if cli_overrides['set']['UpdaterServiceSetting'] is not None: + install_automatically = cli_overrides['set']['UpdaterServiceSetting'] + else: + try: + install_automatically = settings['UpdaterServiceSetting']['Value'] + #because, for some godforsaken reason, we delete the setting rather than changing the value + except KeyError: + install_automatically = 1 + + #use default chunk size if none is given + if cli_overrides['set']['UpdaterMaximumBandwidth ']: + chunk_size = cli_overrides['set']['UpdaterMaximumBandwidth '] + else: + chunk_size = 1024 #get channel and version try: summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) + if cli_overrides['channel']: + summary_dict['Channel'] = cli_overrides['channel'] except: silent_write(log_file_handle, "Could not obtain channel and version, exiting.") print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) return (False, 'setup', None) #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. - result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict) + UpdaterServiceURL = cli_overrides['update-service'] + result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict, UpdaterServiceURL) #nothing to do or error if not result_data: silent_write.write(og_file_handle, "No update found.") @@ -417,7 +444,7 @@ def update_manager(): #323: Check for a completed download of the required update; if found, display an alert, install the required update, and launch the newly installed viewer. #323: If [optional download and] Install Automatically: display an alert, install the update and launch updated viewer. return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, - size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place) + size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place, chunk_size = chunk_size) else: #323: If the update response indicates that there is an optional update: #323: Check to see if the optional update has already been downloaded. @@ -436,7 +463,7 @@ def update_manager(): choice = frame.choice.get() if choice == 1: return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, - size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place) + size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place, chunk_size = chunk_size) elif choice == 2: tempfile.mkstmp(suffix = ".next", dir = download_dir) return (True, None, None) From 49b8a1c82d1b12138fa1177db52efa9698c923f5 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 13 Jul 2016 08:19:49 -0700 Subject: [PATCH 027/183] include manager directory in CMake list --- indra/viewer_components/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt index 74c9b4568d..2030afacec 100644 --- a/indra/viewer_components/CMakeLists.txt +++ b/indra/viewer_components/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(login) add_subdirectory(updater) +add_subdirectory(manager) From adc67912d097aa032b7e7e76f6e87e8e6c54525e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 13 Jul 2016 09:37:53 -0700 Subject: [PATCH 028/183] include manager directory in viewer manifest, not CMake --- indra/newview/viewer_manifest.py | 1 + indra/viewer_components/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f476adda4f..9194a2161a 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -714,6 +714,7 @@ class Darwin_i386_Manifest(ViewerManifest): self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") #this copies over the python wrapper script, see SL-322 self.path2basename("../viewer_components/manager","SL_Launcher") + self.path2basename("../viewer_components/manager","*.py") self.end_prefix() # most everything goes in the Resources directory diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt index 2030afacec..74c9b4568d 100644 --- a/indra/viewer_components/CMakeLists.txt +++ b/indra/viewer_components/CMakeLists.txt @@ -2,4 +2,3 @@ add_subdirectory(login) add_subdirectory(updater) -add_subdirectory(manager) From 58d8b3a11edc9ad0edeaf11737e693f3dc5ad318 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 13 Jul 2016 17:31:14 -0700 Subject: [PATCH 029/183] SL-323: add llsd python module --- indra/viewer_components/manager/SL_Launcher | 3 + indra/viewer_components/manager/llsd.py | 1052 +++++++++++++++++++ 2 files changed, 1055 insertions(+) create mode 100755 indra/viewer_components/manager/llsd.py diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 1d4c19fa86..a96f2392a7 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -20,6 +20,9 @@ import argparse import collections import InstallerUserMessage +#NOTA BENE: +# For POSIX platforms, llsd.py will be imported from the same directory. +# For Windows, llsd.py will be compiled into the executable by pyinstaller import llsd import os import platform diff --git a/indra/viewer_components/manager/llsd.py b/indra/viewer_components/manager/llsd.py new file mode 100755 index 0000000000..4527b115f9 --- /dev/null +++ b/indra/viewer_components/manager/llsd.py @@ -0,0 +1,1052 @@ +"""\ +@file llsd.py +@brief Types as well as parsing and formatting functions for handling LLSD. + +$LicenseInfo:firstyear=2006&license=mit$ + +Copyright (c) 2006-2009, Linden Research, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +$/LicenseInfo$ +""" + +import datetime +import base64 +import string +import struct +import time +import types +import re + +from indra.util.fastest_elementtree import ElementTreeError, fromstring +from indra.base import lluuid + +# cllsd.c in server/server-1.25 has memory leaks, +# so disabling cllsd for now +#try: +# import cllsd +#except ImportError: +# cllsd = None +cllsd = None + +int_regex = re.compile(r"[-+]?\d+") +real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?") +alpha_regex = re.compile(r"[a-zA-Z]+") +date_regex = re.compile(r"(?P\d{4})-(?P\d{2})-(?P\d{2})T" + r"(?P\d{2}):(?P\d{2}):(?P\d{2})" + r"(?P(\.\d+)?)Z") +#date: d"YYYY-MM-DDTHH:MM:SS.FFFFFFZ" + +class LLSDParseError(Exception): + pass + +class LLSDSerializationError(TypeError): + pass + + +class binary(str): + pass + +class uri(str): + pass + + +BOOL_TRUE = ('1', '1.0', 'true') +BOOL_FALSE = ('0', '0.0', 'false', '') + + +def format_datestr(v): + """ Formats a datetime or date object into the string format shared by xml and notation serializations.""" + if hasattr(v, 'microsecond'): + return v.isoformat() + 'Z' + else: + return v.strftime('%Y-%m-%dT%H:%M:%SZ') + +def parse_datestr(datestr): + """Parses a datetime object from the string format shared by xml and notation serializations.""" + if datestr == "": + return datetime.datetime(1970, 1, 1) + + match = re.match(date_regex, datestr) + if not match: + raise LLSDParseError("invalid date string '%s'." % datestr) + + year = int(match.group('year')) + month = int(match.group('month')) + day = int(match.group('day')) + hour = int(match.group('hour')) + minute = int(match.group('minute')) + second = int(match.group('second')) + seconds_float = match.group('second_float') + microsecond = 0 + if seconds_float: + microsecond = int(float('0' + seconds_float) * 1e6) + return datetime.datetime(year, month, day, hour, minute, second, microsecond) + + +def bool_to_python(node): + val = node.text or '' + if val in BOOL_TRUE: + return True + else: + return False + +def int_to_python(node): + val = node.text or '' + if not val.strip(): + return 0 + return int(val) + +def real_to_python(node): + val = node.text or '' + if not val.strip(): + return 0.0 + return float(val) + +def uuid_to_python(node): + return lluuid.UUID(node.text) + +def str_to_python(node): + return node.text or '' + +def bin_to_python(node): + return binary(base64.decodestring(node.text or '')) + +def date_to_python(node): + val = node.text or '' + if not val: + val = "1970-01-01T00:00:00Z" + return parse_datestr(val) + + +def uri_to_python(node): + val = node.text or '' + if not val: + return None + return uri(val) + +def map_to_python(node): + result = {} + for index in range(len(node))[::2]: + result[node[index].text] = to_python(node[index+1]) + return result + +def array_to_python(node): + return [to_python(child) for child in node] + + +NODE_HANDLERS = dict( + undef=lambda x: None, + boolean=bool_to_python, + integer=int_to_python, + real=real_to_python, + uuid=uuid_to_python, + string=str_to_python, + binary=bin_to_python, + date=date_to_python, + uri=uri_to_python, + map=map_to_python, + array=array_to_python, + ) + +def to_python(node): + return NODE_HANDLERS[node.tag](node) + +class Nothing(object): + pass + + +class LLSDXMLFormatter(object): + def __init__(self): + self.type_map = { + type(None) : self.UNDEF, + bool : self.BOOLEAN, + int : self.INTEGER, + long : self.INTEGER, + float : self.REAL, + lluuid.UUID : self.UUID, + binary : self.BINARY, + str : self.STRING, + unicode : self.STRING, + uri : self.URI, + datetime.datetime : self.DATE, + datetime.date : self.DATE, + list : self.ARRAY, + tuple : self.ARRAY, + types.GeneratorType : self.ARRAY, + dict : self.MAP, + LLSD : self.LLSD + } + + def elt(self, name, contents=None): + if(contents is None or contents is ''): + return "<%s />" % (name,) + else: + if type(contents) is unicode: + contents = contents.encode('utf-8') + return "<%s>%s" % (name, contents, name) + + def xml_esc(self, v): + if type(v) is unicode: + v = v.encode('utf-8') + return v.replace('&', '&').replace('<', '<').replace('>', '>') + + def LLSD(self, v): + return self.generate(v.thing) + def UNDEF(self, v): + return self.elt('undef') + def BOOLEAN(self, v): + if v: + return self.elt('boolean', 'true') + else: + return self.elt('boolean', 'false') + def INTEGER(self, v): + return self.elt('integer', v) + def REAL(self, v): + return self.elt('real', v) + def UUID(self, v): + if(v.isNull()): + return self.elt('uuid') + else: + return self.elt('uuid', v) + def BINARY(self, v): + return self.elt('binary', base64.encodestring(v)) + def STRING(self, v): + return self.elt('string', self.xml_esc(v)) + def URI(self, v): + return self.elt('uri', self.xml_esc(str(v))) + def DATE(self, v): + return self.elt('date', format_datestr(v)) + def ARRAY(self, v): + return self.elt('array', ''.join([self.generate(item) for item in v])) + def MAP(self, v): + return self.elt( + 'map', + ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value)) + for key, value in v.items()])) + + typeof = type + def generate(self, something): + t = self.typeof(something) + if self.type_map.has_key(t): + return self.type_map[t](something) + else: + raise LLSDSerializationError("Cannot serialize unknown type: %s (%s)" % ( + t, something)) + + def _format(self, something): + return '' + self.elt("llsd", self.generate(something)) + + def format(self, something): + if cllsd: + return cllsd.llsd_to_xml(something) + return self._format(something) + +_g_xml_formatter = None +def format_xml(something): + global _g_xml_formatter + if _g_xml_formatter is None: + _g_xml_formatter = LLSDXMLFormatter() + return _g_xml_formatter.format(something) + +class LLSDXMLPrettyFormatter(LLSDXMLFormatter): + def __init__(self, indent_atom = None): + # Call the super class constructor so that we have the type map + super(LLSDXMLPrettyFormatter, self).__init__() + + # Override the type map to use our specialized formatters to + # emit the pretty output. + self.type_map[list] = self.PRETTY_ARRAY + self.type_map[tuple] = self.PRETTY_ARRAY + self.type_map[types.GeneratorType] = self.PRETTY_ARRAY, + self.type_map[dict] = self.PRETTY_MAP + + # Private data used for indentation. + self._indent_level = 1 + if indent_atom is None: + self._indent_atom = ' ' + else: + self._indent_atom = indent_atom + + def _indent(self): + "Return an indentation based on the atom and indentation level." + return self._indent_atom * self._indent_level + + def PRETTY_ARRAY(self, v): + rv = [] + rv.append('\n') + self._indent_level = self._indent_level + 1 + rv.extend(["%s%s\n" % + (self._indent(), + self.generate(item)) + for item in v]) + self._indent_level = self._indent_level - 1 + rv.append(self._indent()) + rv.append('') + return ''.join(rv) + + def PRETTY_MAP(self, v): + rv = [] + rv.append('\n') + self._indent_level = self._indent_level + 1 + keys = v.keys() + keys.sort() + rv.extend(["%s%s\n%s%s\n" % + (self._indent(), + self.elt('key', key), + self._indent(), + self.generate(v[key])) + for key in keys]) + self._indent_level = self._indent_level - 1 + rv.append(self._indent()) + rv.append('') + return ''.join(rv) + + def format(self, something): + data = [] + data.append('\n') + data.append(self.generate(something)) + data.append('\n') + return '\n'.join(data) + +def format_pretty_xml(something): + """@brief Serialize a python object as 'pretty' llsd xml. + + The output conforms to the LLSD DTD, unlike the output from the + standard python xml.dom DOM::toprettyxml() method which does not + preserve significant whitespace. + This function is not necessarily suited for serializing very large + objects. It is not optimized by the cllsd module, and sorts on + dict (llsd map) keys alphabetically to ease human reading. + """ + return LLSDXMLPrettyFormatter().format(something) + +class LLSDNotationFormatter(object): + def __init__(self): + self.type_map = { + type(None) : self.UNDEF, + bool : self.BOOLEAN, + int : self.INTEGER, + long : self.INTEGER, + float : self.REAL, + lluuid.UUID : self.UUID, + binary : self.BINARY, + str : self.STRING, + unicode : self.STRING, + uri : self.URI, + datetime.datetime : self.DATE, + datetime.date : self.DATE, + list : self.ARRAY, + tuple : self.ARRAY, + types.GeneratorType : self.ARRAY, + dict : self.MAP, + LLSD : self.LLSD + } + + def LLSD(self, v): + return self.generate(v.thing) + def UNDEF(self, v): + return '!' + def BOOLEAN(self, v): + if v: + return 'true' + else: + return 'false' + def INTEGER(self, v): + return "i%s" % v + def REAL(self, v): + return "r%s" % v + def UUID(self, v): + return "u%s" % v + def BINARY(self, v): + return 'b64"' + base64.encodestring(v) + '"' + def STRING(self, v): + if isinstance(v, unicode): + v = v.encode('utf-8') + return "'%s'" % v.replace("\\", "\\\\").replace("'", "\\'") + def URI(self, v): + return 'l"%s"' % str(v).replace("\\", "\\\\").replace('"', '\\"') + def DATE(self, v): + return 'd"%s"' % format_datestr(v) + def ARRAY(self, v): + return "[%s]" % ','.join([self.generate(item) for item in v]) + def MAP(self, v): + def fix(key): + if isinstance(key, unicode): + return key.encode('utf-8') + return key + return "{%s}" % ','.join(["'%s':%s" % (fix(key).replace("\\", "\\\\").replace("'", "\\'"), self.generate(value)) + for key, value in v.items()]) + + def generate(self, something): + t = type(something) + handler = self.type_map.get(t) + if handler: + return handler(something) + else: + try: + return self.ARRAY(iter(something)) + except TypeError: + raise LLSDSerializationError( + "Cannot serialize unknown type: %s (%s)" % (t, something)) + + def format(self, something): + return self.generate(something) + +def format_notation(something): + return LLSDNotationFormatter().format(something) + +def _hex_as_nybble(hex): + if (hex >= '0') and (hex <= '9'): + return ord(hex) - ord('0') + elif (hex >= 'a') and (hex <='f'): + return 10 + ord(hex) - ord('a') + elif (hex >= 'A') and (hex <='F'): + return 10 + ord(hex) - ord('A'); + +class LLSDBinaryParser(object): + def __init__(self): + pass + + def parse(self, buffer, ignore_binary = False): + """ + This is the basic public interface for parsing. + + @param buffer the binary data to parse in an indexable sequence. + @param ignore_binary parser throws away data in llsd binary nodes. + @return returns a python object. + """ + self._buffer = buffer + self._index = 0 + self._keep_binary = not ignore_binary + return self._parse() + + def _parse(self): + cc = self._buffer[self._index] + self._index += 1 + if cc == '{': + return self._parse_map() + elif cc == '[': + return self._parse_array() + elif cc == '!': + return None + elif cc == '0': + return False + elif cc == '1': + return True + elif cc == 'i': + # 'i' = integer + idx = self._index + self._index += 4 + return struct.unpack("!i", self._buffer[idx:idx+4])[0] + elif cc == ('r'): + # 'r' = real number + idx = self._index + self._index += 8 + return struct.unpack("!d", self._buffer[idx:idx+8])[0] + elif cc == 'u': + # 'u' = uuid + idx = self._index + self._index += 16 + return lluuid.uuid_bits_to_uuid(self._buffer[idx:idx+16]) + elif cc == 's': + # 's' = string + return self._parse_string() + elif cc in ("'", '"'): + # delimited/escaped string + return self._parse_string_delim(cc) + elif cc == 'l': + # 'l' = uri + return uri(self._parse_string()) + elif cc == ('d'): + # 'd' = date in seconds since epoch + idx = self._index + self._index += 8 + seconds = struct.unpack("!d", self._buffer[idx:idx+8])[0] + return datetime.datetime.fromtimestamp(seconds) + elif cc == 'b': + binary = self._parse_string() + if self._keep_binary: + return binary + # *NOTE: maybe have a binary placeholder which has the + # length. + return None + else: + raise LLSDParseError("invalid binary token at byte %d: %d" % ( + self._index - 1, ord(cc))) + + def _parse_map(self): + rv = {} + size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] + self._index += 4 + count = 0 + cc = self._buffer[self._index] + self._index += 1 + key = '' + while (cc != '}') and (count < size): + if cc == 'k': + key = self._parse_string() + elif cc in ("'", '"'): + key = self._parse_string_delim(cc) + else: + raise LLSDParseError("invalid map key at byte %d." % ( + self._index - 1,)) + value = self._parse() + rv[key] = value + count += 1 + cc = self._buffer[self._index] + self._index += 1 + if cc != '}': + raise LLSDParseError("invalid map close token at byte %d." % ( + self._index,)) + return rv + + def _parse_array(self): + rv = [] + size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] + self._index += 4 + count = 0 + cc = self._buffer[self._index] + while (cc != ']') and (count < size): + rv.append(self._parse()) + count += 1 + cc = self._buffer[self._index] + if cc != ']': + raise LLSDParseError("invalid array close token at byte %d." % ( + self._index,)) + self._index += 1 + return rv + + def _parse_string(self): + size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] + self._index += 4 + rv = self._buffer[self._index:self._index+size] + self._index += size + return rv + + def _parse_string_delim(self, delim): + list = [] + found_escape = False + found_hex = False + found_digit = False + byte = 0 + while True: + cc = self._buffer[self._index] + self._index += 1 + if found_escape: + if found_hex: + if found_digit: + found_escape = False + found_hex = False + found_digit = False + byte <<= 4 + byte |= _hex_as_nybble(cc) + list.append(chr(byte)) + byte = 0 + else: + found_digit = True + byte = _hex_as_nybble(cc) + elif cc == 'x': + found_hex = True + else: + if cc == 'a': + list.append('\a') + elif cc == 'b': + list.append('\b') + elif cc == 'f': + list.append('\f') + elif cc == 'n': + list.append('\n') + elif cc == 'r': + list.append('\r') + elif cc == 't': + list.append('\t') + elif cc == 'v': + list.append('\v') + else: + list.append(cc) + found_escape = False + elif cc == '\\': + found_escape = True + elif cc == delim: + break + else: + list.append(cc) + return ''.join(list) + +class LLSDNotationParser(object): + """ Parse LLSD notation: + map: { string:object, string:object } + array: [ object, object, object ] + undef: ! + boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE + integer: i#### + real: r#### + uuid: u#### + string: "g\'day" | 'have a "nice" day' | s(size)"raw data" + uri: l"escaped" + date: d"YYYY-MM-DDTHH:MM:SS.FFZ" + binary: b##"ff3120ab1" | b(size)"raw data" + """ + def __init__(self): + pass + + def parse(self, buffer, ignore_binary = False): + """ + This is the basic public interface for parsing. + + @param buffer the notation string to parse. + @param ignore_binary parser throws away data in llsd binary nodes. + @return returns a python object. + """ + if buffer == "": + return False + + self._buffer = buffer + self._index = 0 + return self._parse() + + def _parse(self): + cc = self._buffer[self._index] + self._index += 1 + if cc == '{': + return self._parse_map() + elif cc == '[': + return self._parse_array() + elif cc == '!': + return None + elif cc == '0': + return False + elif cc == '1': + return True + elif cc in ('F', 'f'): + self._skip_alpha() + return False + elif cc in ('T', 't'): + self._skip_alpha() + return True + elif cc == 'i': + # 'i' = integer + return self._parse_integer() + elif cc == ('r'): + # 'r' = real number + return self._parse_real() + elif cc == 'u': + # 'u' = uuid + return self._parse_uuid() + elif cc in ("'", '"', 's'): + return self._parse_string(cc) + elif cc == 'l': + # 'l' = uri + delim = self._buffer[self._index] + self._index += 1 + val = uri(self._parse_string(delim)) + if len(val) == 0: + return None + return val + elif cc == ('d'): + # 'd' = date in seconds since epoch + return self._parse_date() + elif cc == 'b': + return self._parse_binary() + else: + raise LLSDParseError("invalid token at index %d: %d" % ( + self._index - 1, ord(cc))) + + def _parse_binary(self): + i = self._index + if self._buffer[i:i+2] == '64': + q = self._buffer[i+2] + e = self._buffer.find(q, i+3) + try: + return base64.decodestring(self._buffer[i+3:e]) + finally: + self._index = e + 1 + else: + raise LLSDParseError('random horrible binary format not supported') + + def _parse_map(self): + """ map: { string:object, string:object } """ + rv = {} + cc = self._buffer[self._index] + self._index += 1 + key = '' + found_key = False + while (cc != '}'): + if not found_key: + if cc in ("'", '"', 's'): + key = self._parse_string(cc) + found_key = True + elif cc.isspace() or cc == ',': + cc = self._buffer[self._index] + self._index += 1 + else: + raise LLSDParseError("invalid map key at byte %d." % ( + self._index - 1,)) + elif cc.isspace() or cc == ':': + cc = self._buffer[self._index] + self._index += 1 + continue + else: + self._index += 1 + value = self._parse() + rv[key] = value + found_key = False + cc = self._buffer[self._index] + self._index += 1 + + return rv + + def _parse_array(self): + """ array: [ object, object, object ] """ + rv = [] + cc = self._buffer[self._index] + while (cc != ']'): + if cc.isspace() or cc == ',': + self._index += 1 + cc = self._buffer[self._index] + continue + rv.append(self._parse()) + cc = self._buffer[self._index] + + if cc != ']': + raise LLSDParseError("invalid array close token at index %d." % ( + self._index,)) + self._index += 1 + return rv + + def _parse_uuid(self): + match = re.match(lluuid.UUID.uuid_regex, self._buffer[self._index:]) + if not match: + raise LLSDParseError("invalid uuid token at index %d." % self._index) + + (start, end) = match.span() + start += self._index + end += self._index + self._index = end + return lluuid.UUID(self._buffer[start:end]) + + def _skip_alpha(self): + match = re.match(alpha_regex, self._buffer[self._index:]) + if match: + self._index += match.end() + + def _parse_date(self): + delim = self._buffer[self._index] + self._index += 1 + datestr = self._parse_string(delim) + return parse_datestr(datestr) + + def _parse_real(self): + match = re.match(real_regex, self._buffer[self._index:]) + if not match: + raise LLSDParseError("invalid real token at index %d." % self._index) + + (start, end) = match.span() + start += self._index + end += self._index + self._index = end + return float( self._buffer[start:end] ) + + def _parse_integer(self): + match = re.match(int_regex, self._buffer[self._index:]) + if not match: + raise LLSDParseError("invalid integer token at index %d." % self._index) + + (start, end) = match.span() + start += self._index + end += self._index + self._index = end + return int( self._buffer[start:end] ) + + def _parse_string(self, delim): + """ string: "g\'day" | 'have a "nice" day' | s(size)"raw data" """ + rv = "" + + if delim in ("'", '"'): + rv = self._parse_string_delim(delim) + elif delim == 's': + rv = self._parse_string_raw() + else: + raise LLSDParseError("invalid string token at index %d." % self._index) + + return rv + + + def _parse_string_delim(self, delim): + """ string: "g'day 'un" | 'have a "nice" day' """ + list = [] + found_escape = False + found_hex = False + found_digit = False + byte = 0 + while True: + cc = self._buffer[self._index] + self._index += 1 + if found_escape: + if found_hex: + if found_digit: + found_escape = False + found_hex = False + found_digit = False + byte <<= 4 + byte |= _hex_as_nybble(cc) + list.append(chr(byte)) + byte = 0 + else: + found_digit = True + byte = _hex_as_nybble(cc) + elif cc == 'x': + found_hex = True + else: + if cc == 'a': + list.append('\a') + elif cc == 'b': + list.append('\b') + elif cc == 'f': + list.append('\f') + elif cc == 'n': + list.append('\n') + elif cc == 'r': + list.append('\r') + elif cc == 't': + list.append('\t') + elif cc == 'v': + list.append('\v') + else: + list.append(cc) + found_escape = False + elif cc == '\\': + found_escape = True + elif cc == delim: + break + else: + list.append(cc) + return ''.join(list) + + def _parse_string_raw(self): + """ string: s(size)"raw data" """ + # Read the (size) portion. + cc = self._buffer[self._index] + self._index += 1 + if cc != '(': + raise LLSDParseError("invalid string token at index %d." % self._index) + + rparen = self._buffer.find(')', self._index) + if rparen == -1: + raise LLSDParseError("invalid string token at index %d." % self._index) + + size = int(self._buffer[self._index:rparen]) + + self._index = rparen + 1 + delim = self._buffer[self._index] + self._index += 1 + if delim not in ("'", '"'): + raise LLSDParseError("invalid string token at index %d." % self._index) + + rv = self._buffer[self._index:(self._index + size)] + self._index += size + cc = self._buffer[self._index] + self._index += 1 + if cc != delim: + raise LLSDParseError("invalid string token at index %d." % self._index) + + return rv + +def format_binary(something): + return '\n' + _format_binary_recurse(something) + +def _format_binary_recurse(something): + def _format_list(something): + array_builder = [] + array_builder.append('[' + struct.pack('!i', len(something))) + for item in something: + array_builder.append(_format_binary_recurse(item)) + array_builder.append(']') + return ''.join(array_builder) + + if something is None: + return '!' + elif isinstance(something, LLSD): + return _format_binary_recurse(something.thing) + elif isinstance(something, bool): + if something: + return '1' + else: + return '0' + elif isinstance(something, (int, long)): + return 'i' + struct.pack('!i', something) + elif isinstance(something, float): + return 'r' + struct.pack('!d', something) + elif isinstance(something, lluuid.UUID): + return 'u' + something._bits + elif isinstance(something, binary): + return 'b' + struct.pack('!i', len(something)) + something + elif isinstance(something, str): + return 's' + struct.pack('!i', len(something)) + something + elif isinstance(something, unicode): + something = something.encode('utf-8') + return 's' + struct.pack('!i', len(something)) + something + elif isinstance(something, uri): + return 'l' + struct.pack('!i', len(something)) + something + elif isinstance(something, datetime.datetime): + seconds_since_epoch = time.mktime(something.timetuple()) + return 'd' + struct.pack('!d', seconds_since_epoch) + elif isinstance(something, (list, tuple)): + return _format_list(something) + elif isinstance(something, dict): + map_builder = [] + map_builder.append('{' + struct.pack('!i', len(something))) + for key, value in something.items(): + if isinstance(key, unicode): + key = key.encode('utf-8') + map_builder.append('k' + struct.pack('!i', len(key)) + key) + map_builder.append(_format_binary_recurse(value)) + map_builder.append('}') + return ''.join(map_builder) + else: + try: + return _format_list(list(something)) + except TypeError: + raise LLSDSerializationError( + "Cannot serialize unknown type: %s (%s)" % + (type(something), something)) + + +def parse_binary(binary): + if binary.startswith(''): + just_binary = binary.split('\n', 1)[1] + else: + just_binary = binary + return LLSDBinaryParser().parse(just_binary) + +def parse_xml(something): + try: + return to_python(fromstring(something)[0]) + except ElementTreeError, err: + raise LLSDParseError(*err.args) + +def parse_notation(something): + return LLSDNotationParser().parse(something) + +def parse(something): + try: + something = string.lstrip(something) #remove any pre-trailing whitespace + if something.startswith(''): + return parse_binary(something) + # This should be better. + elif something.startswith('<'): + return parse_xml(something) + else: + return parse_notation(something) + except KeyError, e: + raise Exception('LLSD could not be parsed: %s' % (e,)) + +class LLSD(object): + def __init__(self, thing=None): + self.thing = thing + + def __str__(self): + return self.toXML(self.thing) + + parse = staticmethod(parse) + toXML = staticmethod(format_xml) + toPrettyXML = staticmethod(format_pretty_xml) + toBinary = staticmethod(format_binary) + toNotation = staticmethod(format_notation) + + +undef = LLSD(None) + +XML_MIME_TYPE = 'application/llsd+xml' +BINARY_MIME_TYPE = 'application/llsd+binary' + +# register converters for llsd in mulib, if it is available +try: + from mulib import stacked, mu + stacked.NoProducer() # just to exercise stacked + mu.safe_load(None) # just to exercise mu +except: + # mulib not available, don't print an error message since this is normal + pass +else: + mu.add_parser(parse, XML_MIME_TYPE) + mu.add_parser(parse, 'application/llsd+binary') + + def llsd_convert_xml(llsd_stuff, request): + request.write(format_xml(llsd_stuff)) + + def llsd_convert_binary(llsd_stuff, request): + request.write(format_binary(llsd_stuff)) + + for typ in [LLSD, dict, list, tuple, str, int, long, float, bool, unicode, type(None)]: + stacked.add_producer(typ, llsd_convert_xml, XML_MIME_TYPE) + stacked.add_producer(typ, llsd_convert_xml, 'application/xml') + stacked.add_producer(typ, llsd_convert_xml, 'text/xml') + + stacked.add_producer(typ, llsd_convert_binary, 'application/llsd+binary') + + stacked.add_producer(LLSD, llsd_convert_xml, '*/*') + + # in case someone is using the legacy mu.xml wrapper, we need to + # tell mu to produce application/xml or application/llsd+xml + # (based on the accept header) from raw xml. Phoenix 2008-07-21 + stacked.add_producer(mu.xml, mu.produce_raw, XML_MIME_TYPE) + stacked.add_producer(mu.xml, mu.produce_raw, 'application/xml') + + + +# mulib wsgi stuff +# try: +# from mulib import mu, adapters +# +# # try some known attributes from mulib to be ultra-sure we've imported it +# mu.get_current +# adapters.handlers +# except: +# # mulib not available, don't print an error message since this is normal +# pass +# else: +# def llsd_xml_handler(content_type): +# def handle_llsd_xml(env, start_response): +# llsd_stuff, _ = mu.get_current(env) +# result = format_xml(llsd_stuff) +# start_response("200 OK", [('Content-Type', content_type)]) +# env['mu.negotiated_type'] = content_type +# yield result +# return handle_llsd_xml +# +# def llsd_binary_handler(content_type): +# def handle_llsd_binary(env, start_response): +# llsd_stuff, _ = mu.get_current(env) +# result = format_binary(llsd_stuff) +# start_response("200 OK", [('Content-Type', content_type)]) +# env['mu.negotiated_type'] = content_type +# yield result +# return handle_llsd_binary +# +# adapters.DEFAULT_PARSERS[XML_MIME_TYPE] = parse + +# for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]: +# for content_type in (XML_MIME_TYPE, 'application/xml'): +# adapters.handlers.set_handler(typ, llsd_xml_handler(content_type), content_type) +# +# adapters.handlers.set_handler(typ, llsd_binary_handler(BINARY_MIME_TYPE), BINARY_MIME_TYPE) +# +# adapters.handlers.set_handler(LLSD, llsd_xml_handler(XML_MIME_TYPE), '*/*') From 68832f56ba09541f01a246574b141e3ab5fb62b8 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 14 Jul 2016 08:37:23 -0700 Subject: [PATCH 030/183] add dependent modules --- indra/newview/viewer_manifest.py | 4 +- .../manager/{ => base}/llsd.py | 0 .../viewer_components/manager/base/lluuid.py | 319 ++++++++++++++++++ .../manager/util/fastest_elementtree.py | 64 ++++ 4 files changed, 386 insertions(+), 1 deletion(-) rename indra/viewer_components/manager/{ => base}/llsd.py (100%) create mode 100755 indra/viewer_components/manager/base/lluuid.py create mode 100755 indra/viewer_components/manager/util/fastest_elementtree.py diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 9194a2161a..ac9b8d8ebe 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -712,9 +712,11 @@ class Darwin_i386_Manifest(ViewerManifest): if self.prefix(dst="MacOS"): self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") - #this copies over the python wrapper script, see SL-322 + #this copies over the python wrapper script and associated utilities, see SL-321, SL-322 and SL-323 self.path2basename("../viewer_components/manager","SL_Launcher") self.path2basename("../viewer_components/manager","*.py") + self.path2basename("../viewer_components/manager/base","*py") + self.path2basename("../viewer_components/manager/util","*py") self.end_prefix() # most everything goes in the Resources directory diff --git a/indra/viewer_components/manager/llsd.py b/indra/viewer_components/manager/base/llsd.py similarity index 100% rename from indra/viewer_components/manager/llsd.py rename to indra/viewer_components/manager/base/llsd.py diff --git a/indra/viewer_components/manager/base/lluuid.py b/indra/viewer_components/manager/base/lluuid.py new file mode 100755 index 0000000000..7413ffe10d --- /dev/null +++ b/indra/viewer_components/manager/base/lluuid.py @@ -0,0 +1,319 @@ +"""\ +@file lluuid.py +@brief UUID parser/generator. + +$LicenseInfo:firstyear=2004&license=mit$ + +Copyright (c) 2004-2009, Linden Research, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +$/LicenseInfo$ +""" + +import random, socket, string, time, re +import uuid +try: + # Python 2.6 + from hashlib import md5 +except ImportError: + # Python 2.5 and earlier + from md5 import new as md5 + +def _int2binstr(i,l): + s='' + for a in range(l): + s=chr(i&0xFF)+s + i>>=8 + return s + +def _binstr2int(s): + i = long(0) + for c in s: + i = (i<<8) + ord(c) + return i + +class UUID(object): + """ + A class which represents a 16 byte integer. Stored as a 16 byte 8 + bit character string. + + The string version is to be of the form: + AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) + where A=network address, B=timestamp, C=random. + """ + + NULL_STR = "00000000-0000-0000-0000-000000000000" + + # the UUIDREGEX_STRING is helpful for parsing UUID's in text + hex_wildcard = r"[0-9a-fA-F]" + word = hex_wildcard + r"{4,4}-" + long_word = hex_wildcard + r"{8,8}-" + very_long_word = hex_wildcard + r"{12,12}" + UUID_REGEX_STRING = long_word + word + word + word + very_long_word + uuid_regex = re.compile(UUID_REGEX_STRING) + + rand = random.Random() + ip = '' + try: + ip = socket.gethostbyname(socket.gethostname()) + except(socket.gaierror, socket.error): + # no ip address, so just default to somewhere in 10.x.x.x + ip = '10' + for i in range(3): + ip += '.' + str(rand.randrange(1,254)) + hexip = ''.join(["%04x" % long(i) for i in ip.split('.')]) + lastid = '' + + def __init__(self, possible_uuid=None): + """ + Initialize to first valid UUID in argument (if a string), + or to null UUID if none found or argument is not supplied. + + If the argument is a UUID, the constructed object will be a copy of it. + """ + self._bits = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + if possible_uuid is None: + return + + if isinstance(possible_uuid, type(self)): + self.set(possible_uuid) + return + + uuid_match = UUID.uuid_regex.search(possible_uuid) + if uuid_match: + uuid_string = uuid_match.group() + s = string.replace(uuid_string, '-', '') + self._bits = _int2binstr(string.atol(s[:8],16),4) + \ + _int2binstr(string.atol(s[8:16],16),4) + \ + _int2binstr(string.atol(s[16:24],16),4) + \ + _int2binstr(string.atol(s[24:],16),4) + + def __len__(self): + """ + Used by the len() builtin. + """ + return 36 + + def __nonzero__(self): + return self._bits != "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + + def __str__(self): + uuid_string = self.toString() + return uuid_string + + __repr__ = __str__ + + def __getitem__(self, index): + return str(self)[index] + + def __eq__(self, other): + if isinstance(other, (str, unicode)): + return other == str(self) + return self._bits == getattr(other, '_bits', '') + + def __ne__(self, other): + return not self.__eq__(other) + + def __le__(self, other): + return self._bits <= other._bits + + def __ge__(self, other): + return self._bits >= other._bits + + def __lt__(self, other): + return self._bits < other._bits + + def __gt__(self, other): + return self._bits > other._bits + + def __hash__(self): + return hash(self._bits) + + def set(self, uuid): + self._bits = uuid._bits + + def setFromString(self, uuid_string): + """ + Given a string version of a uuid, set self bits + appropriately. Returns self. + """ + s = string.replace(uuid_string, '-', '') + self._bits = _int2binstr(string.atol(s[:8],16),4) + \ + _int2binstr(string.atol(s[8:16],16),4) + \ + _int2binstr(string.atol(s[16:24],16),4) + \ + _int2binstr(string.atol(s[24:],16),4) + return self + + def setFromMemoryDump(self, gdb_string): + """ + We expect to get gdb_string as four hex units. eg: + 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 + Which will be translated to: + db547d14-1b3f4bc3-9b984f71-d22f890a + Returns self. + """ + s = string.replace(gdb_string, '0x', '') + s = string.replace(s, ' ', '') + t = '' + for i in range(8,40,8): + for j in range(0,8,2): + t = t + s[i-j-2:i-j] + self.setFromString(t) + + def toString(self): + """ + Return as a string matching the LL standard + AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) + where A=network address, B=timestamp, C=random. + """ + return uuid_bits_to_string(self._bits) + + def getAsString(self): + """ + Return a different string representation of the form + AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex) + where A=network address, B=timestamp, C=random. + """ + i1 = _binstr2int(self._bits[0:4]) + i2 = _binstr2int(self._bits[4:8]) + i3 = _binstr2int(self._bits[8:12]) + i4 = _binstr2int(self._bits[12:16]) + return '%08lx-%08lx-%08lx-%08lx' % (i1,i2,i3,i4) + + def generate(self): + """ + Generate a new uuid. This algorithm is slightly different + from c++ implementation for portability reasons. + Returns self. + """ + m = md5() + m.update(uuid.uuid1().bytes) + self._bits = m.digest() + return self + + def isNull(self): + """ + Returns 1 if the uuid is null - ie, equal to default uuid. + """ + return (self._bits == "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") + + def xor(self, rhs): + """ + xors self with rhs. + """ + v1 = _binstr2int(self._bits[0:4]) ^ _binstr2int(rhs._bits[0:4]) + v2 = _binstr2int(self._bits[4:8]) ^ _binstr2int(rhs._bits[4:8]) + v3 = _binstr2int(self._bits[8:12]) ^ _binstr2int(rhs._bits[8:12]) + v4 = _binstr2int(self._bits[12:16]) ^ _binstr2int(rhs._bits[12:16]) + self._bits = _int2binstr(v1,4) + \ + _int2binstr(v2,4) + \ + _int2binstr(v3,4) + \ + _int2binstr(v4,4) + + +# module-level null constant +NULL = UUID() + +def printTranslatedMemory(four_hex_uints): + """ + We expect to get the string as four hex units. eg: + 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 + Which will be translated to: + db547d14-1b3f4bc3-9b984f71-d22f890a + """ + uuid = UUID() + uuid.setFromMemoryDump(four_hex_uints) + print uuid.toString() + +def isUUID(id_str): + """ + This function returns: + - 1 if the string passed is a UUID + - 0 is the string passed is not a UUID + - None if it neither of the if's below is satisfied + """ + if not id_str or len(id_str) < 5 or len(id_str) > 36: + return 0 + + if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str): + return 1 + + return None + +def isPossiblyID(id_str): + """ + This function returns 1 if the string passed has some uuid-like + characteristics. Otherwise returns 0. + """ + + is_uuid = isUUID(id_str) + if is_uuid is not None: + return is_uuid + + # build a string which matches every character. + hex_wildcard = r"[0-9a-fA-F]" + chars = len(id_str) + next = min(chars, 8) + matcher = hex_wildcard+"{"+str(next)+","+str(next)+"}" + chars = chars - next + if chars > 0: + matcher = matcher + "-" + chars = chars - 1 + for block in range(3): + next = max(min(chars, 4), 0) + if next: + matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" + chars = chars - next + if chars > 0: + matcher = matcher + "-" + chars = chars - 1 + if chars > 0: + next = min(chars, 12) + matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" + #print matcher + uuid_matcher = re.compile(matcher) + if uuid_matcher.match(id_str): + return 1 + return 0 + +def uuid_bits_to_string(bits): + i1 = _binstr2int(bits[0:4]) + i2 = _binstr2int(bits[4:6]) + i3 = _binstr2int(bits[6:8]) + i4 = _binstr2int(bits[8:10]) + i5 = _binstr2int(bits[10:12]) + i6 = _binstr2int(bits[12:16]) + return '%08lx-%04lx-%04lx-%04lx-%04lx%08lx' % (i1,i2,i3,i4,i5,i6) + +def uuid_bits_to_uuid(bits): + return UUID(uuid_bits_to_string(bits)) + + +try: + from mulib import stacked + stacked.NoProducer() # just to exercise stacked +except: + #print "Couldn't import mulib.stacked, not registering UUID converter" + pass +else: + def convertUUID(uuid, req): + req.write(str(uuid)) + + stacked.add_producer(UUID, convertUUID, "*/*") + stacked.add_producer(UUID, convertUUID, "text/html") diff --git a/indra/viewer_components/manager/util/fastest_elementtree.py b/indra/viewer_components/manager/util/fastest_elementtree.py new file mode 100755 index 0000000000..4fcf662dd9 --- /dev/null +++ b/indra/viewer_components/manager/util/fastest_elementtree.py @@ -0,0 +1,64 @@ +"""\ +@file fastest_elementtree.py +@brief Concealing some gnarly import logic in here. This should export the interface of elementtree. + +$LicenseInfo:firstyear=2008&license=mit$ + +Copyright (c) 2008-2009, Linden Research, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +$/LicenseInfo$ +""" + +# The parsing exception raised by the underlying library depends +# on the ElementTree implementation we're using, so we provide an +# alias here. +# +# Use ElementTreeError as the exception type for catching parsing +# errors. + + +# Using cElementTree might cause some unforeseen problems, so here's a +# convenient off switch. +use_celementree = True + +try: + if not use_celementree: + raise ImportError() + # Python 2.3 and 2.4. + from cElementTree import * + ElementTreeError = SyntaxError +except ImportError: + try: + if not use_celementree: + raise ImportError() + # Python 2.5 and above. + from xml.etree.cElementTree import * + ElementTreeError = SyntaxError + except ImportError: + # Pure Python code. + try: + # Python 2.3 and 2.4. + from elementtree.ElementTree import * + except ImportError: + # Python 2.5 and above. + from xml.etree.ElementTree import * + + # The pure Python ElementTree module uses Expat for parsing. + from xml.parsers.expat import ExpatError as ElementTreeError From 4428ee77c29fb2e0af50bf6d650abfeb33329b3f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 21 Jul 2016 10:18:58 -0700 Subject: [PATCH 031/183] SL-323: make changes to include llbase as an autobuild pkg, undelete files that will be deleted with MAINT-6585 and no need to copy local files in viewer-manifest. --- autobuild.xml | 52 + indra/cmake/LLBase.cmake | 4 + indra/newview/CMakeLists.txt | 1 + indra/newview/viewer_manifest.py | 2 - indra/viewer_components/manager/base/llsd.py | 1052 ----------------- .../viewer_components/manager/base/lluuid.py | 319 ----- .../manager/util/fastest_elementtree.py | 64 - 7 files changed, 57 insertions(+), 1437 deletions(-) create mode 100644 indra/cmake/LLBase.cmake delete mode 100755 indra/viewer_components/manager/base/llsd.py delete mode 100755 indra/viewer_components/manager/base/lluuid.py delete mode 100755 indra/viewer_components/manager/util/fastest_elementtree.py diff --git a/autobuild.xml b/autobuild.xml index 072dfa678a..1c04fb85fe 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1465,6 +1465,58 @@ version 0.0.1 + llbase + + copyright + Copyright (c) 2010, Linden Research, Inc. + license + mit + license_file + LICENSES/llbase-license.txt + name + llbase + platforms + + darwin + + archive + + hash + 313f5c8edd328e05c59cbe980512f84c + url + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/Darwin/installer/llbase-0.8.6.317790-darwin-317790.tar.bz2 + + name + darwin + + linux + + archive + + hash + e85171c70b57dd086b956ba36e6f2306 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/Linux/installer/llbase-0.8.6.317790-linux-317790.tar.bz2 + + name + linux + + windows + + archive + + hash + 07b0d64d812cfaf3025b799cea5fe446 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/CYGWIN/installer/llbase-0.8.6.0-windows-317790.tar.bz2 + + name + windows + + + version + 0.8.6.317790 + llceflib copyright diff --git a/indra/cmake/LLBase.cmake b/indra/cmake/LLBase.cmake new file mode 100644 index 0000000000..76e3c688a3 --- /dev/null +++ b/indra/cmake/LLBase.cmake @@ -0,0 +1,4 @@ +# -*- cmake -*- +include(Prebuilt) + +use_prebuilt_binary(llbase) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 132b57eb44..31e3711569 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -17,6 +17,7 @@ include(GooglePerfTools) include(Hunspell) include(JsonCpp) include(LLAppearance) +include(LLBase) include(LLAudio) include(LLCharacter) include(LLCommon) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ac9b8d8ebe..d3ab05b9bd 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -715,8 +715,6 @@ class Darwin_i386_Manifest(ViewerManifest): #this copies over the python wrapper script and associated utilities, see SL-321, SL-322 and SL-323 self.path2basename("../viewer_components/manager","SL_Launcher") self.path2basename("../viewer_components/manager","*.py") - self.path2basename("../viewer_components/manager/base","*py") - self.path2basename("../viewer_components/manager/util","*py") self.end_prefix() # most everything goes in the Resources directory diff --git a/indra/viewer_components/manager/base/llsd.py b/indra/viewer_components/manager/base/llsd.py deleted file mode 100755 index 4527b115f9..0000000000 --- a/indra/viewer_components/manager/base/llsd.py +++ /dev/null @@ -1,1052 +0,0 @@ -"""\ -@file llsd.py -@brief Types as well as parsing and formatting functions for handling LLSD. - -$LicenseInfo:firstyear=2006&license=mit$ - -Copyright (c) 2006-2009, Linden Research, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -$/LicenseInfo$ -""" - -import datetime -import base64 -import string -import struct -import time -import types -import re - -from indra.util.fastest_elementtree import ElementTreeError, fromstring -from indra.base import lluuid - -# cllsd.c in server/server-1.25 has memory leaks, -# so disabling cllsd for now -#try: -# import cllsd -#except ImportError: -# cllsd = None -cllsd = None - -int_regex = re.compile(r"[-+]?\d+") -real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?") -alpha_regex = re.compile(r"[a-zA-Z]+") -date_regex = re.compile(r"(?P\d{4})-(?P\d{2})-(?P\d{2})T" - r"(?P\d{2}):(?P\d{2}):(?P\d{2})" - r"(?P(\.\d+)?)Z") -#date: d"YYYY-MM-DDTHH:MM:SS.FFFFFFZ" - -class LLSDParseError(Exception): - pass - -class LLSDSerializationError(TypeError): - pass - - -class binary(str): - pass - -class uri(str): - pass - - -BOOL_TRUE = ('1', '1.0', 'true') -BOOL_FALSE = ('0', '0.0', 'false', '') - - -def format_datestr(v): - """ Formats a datetime or date object into the string format shared by xml and notation serializations.""" - if hasattr(v, 'microsecond'): - return v.isoformat() + 'Z' - else: - return v.strftime('%Y-%m-%dT%H:%M:%SZ') - -def parse_datestr(datestr): - """Parses a datetime object from the string format shared by xml and notation serializations.""" - if datestr == "": - return datetime.datetime(1970, 1, 1) - - match = re.match(date_regex, datestr) - if not match: - raise LLSDParseError("invalid date string '%s'." % datestr) - - year = int(match.group('year')) - month = int(match.group('month')) - day = int(match.group('day')) - hour = int(match.group('hour')) - minute = int(match.group('minute')) - second = int(match.group('second')) - seconds_float = match.group('second_float') - microsecond = 0 - if seconds_float: - microsecond = int(float('0' + seconds_float) * 1e6) - return datetime.datetime(year, month, day, hour, minute, second, microsecond) - - -def bool_to_python(node): - val = node.text or '' - if val in BOOL_TRUE: - return True - else: - return False - -def int_to_python(node): - val = node.text or '' - if not val.strip(): - return 0 - return int(val) - -def real_to_python(node): - val = node.text or '' - if not val.strip(): - return 0.0 - return float(val) - -def uuid_to_python(node): - return lluuid.UUID(node.text) - -def str_to_python(node): - return node.text or '' - -def bin_to_python(node): - return binary(base64.decodestring(node.text or '')) - -def date_to_python(node): - val = node.text or '' - if not val: - val = "1970-01-01T00:00:00Z" - return parse_datestr(val) - - -def uri_to_python(node): - val = node.text or '' - if not val: - return None - return uri(val) - -def map_to_python(node): - result = {} - for index in range(len(node))[::2]: - result[node[index].text] = to_python(node[index+1]) - return result - -def array_to_python(node): - return [to_python(child) for child in node] - - -NODE_HANDLERS = dict( - undef=lambda x: None, - boolean=bool_to_python, - integer=int_to_python, - real=real_to_python, - uuid=uuid_to_python, - string=str_to_python, - binary=bin_to_python, - date=date_to_python, - uri=uri_to_python, - map=map_to_python, - array=array_to_python, - ) - -def to_python(node): - return NODE_HANDLERS[node.tag](node) - -class Nothing(object): - pass - - -class LLSDXMLFormatter(object): - def __init__(self): - self.type_map = { - type(None) : self.UNDEF, - bool : self.BOOLEAN, - int : self.INTEGER, - long : self.INTEGER, - float : self.REAL, - lluuid.UUID : self.UUID, - binary : self.BINARY, - str : self.STRING, - unicode : self.STRING, - uri : self.URI, - datetime.datetime : self.DATE, - datetime.date : self.DATE, - list : self.ARRAY, - tuple : self.ARRAY, - types.GeneratorType : self.ARRAY, - dict : self.MAP, - LLSD : self.LLSD - } - - def elt(self, name, contents=None): - if(contents is None or contents is ''): - return "<%s />" % (name,) - else: - if type(contents) is unicode: - contents = contents.encode('utf-8') - return "<%s>%s" % (name, contents, name) - - def xml_esc(self, v): - if type(v) is unicode: - v = v.encode('utf-8') - return v.replace('&', '&').replace('<', '<').replace('>', '>') - - def LLSD(self, v): - return self.generate(v.thing) - def UNDEF(self, v): - return self.elt('undef') - def BOOLEAN(self, v): - if v: - return self.elt('boolean', 'true') - else: - return self.elt('boolean', 'false') - def INTEGER(self, v): - return self.elt('integer', v) - def REAL(self, v): - return self.elt('real', v) - def UUID(self, v): - if(v.isNull()): - return self.elt('uuid') - else: - return self.elt('uuid', v) - def BINARY(self, v): - return self.elt('binary', base64.encodestring(v)) - def STRING(self, v): - return self.elt('string', self.xml_esc(v)) - def URI(self, v): - return self.elt('uri', self.xml_esc(str(v))) - def DATE(self, v): - return self.elt('date', format_datestr(v)) - def ARRAY(self, v): - return self.elt('array', ''.join([self.generate(item) for item in v])) - def MAP(self, v): - return self.elt( - 'map', - ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value)) - for key, value in v.items()])) - - typeof = type - def generate(self, something): - t = self.typeof(something) - if self.type_map.has_key(t): - return self.type_map[t](something) - else: - raise LLSDSerializationError("Cannot serialize unknown type: %s (%s)" % ( - t, something)) - - def _format(self, something): - return '' + self.elt("llsd", self.generate(something)) - - def format(self, something): - if cllsd: - return cllsd.llsd_to_xml(something) - return self._format(something) - -_g_xml_formatter = None -def format_xml(something): - global _g_xml_formatter - if _g_xml_formatter is None: - _g_xml_formatter = LLSDXMLFormatter() - return _g_xml_formatter.format(something) - -class LLSDXMLPrettyFormatter(LLSDXMLFormatter): - def __init__(self, indent_atom = None): - # Call the super class constructor so that we have the type map - super(LLSDXMLPrettyFormatter, self).__init__() - - # Override the type map to use our specialized formatters to - # emit the pretty output. - self.type_map[list] = self.PRETTY_ARRAY - self.type_map[tuple] = self.PRETTY_ARRAY - self.type_map[types.GeneratorType] = self.PRETTY_ARRAY, - self.type_map[dict] = self.PRETTY_MAP - - # Private data used for indentation. - self._indent_level = 1 - if indent_atom is None: - self._indent_atom = ' ' - else: - self._indent_atom = indent_atom - - def _indent(self): - "Return an indentation based on the atom and indentation level." - return self._indent_atom * self._indent_level - - def PRETTY_ARRAY(self, v): - rv = [] - rv.append('\n') - self._indent_level = self._indent_level + 1 - rv.extend(["%s%s\n" % - (self._indent(), - self.generate(item)) - for item in v]) - self._indent_level = self._indent_level - 1 - rv.append(self._indent()) - rv.append('') - return ''.join(rv) - - def PRETTY_MAP(self, v): - rv = [] - rv.append('\n') - self._indent_level = self._indent_level + 1 - keys = v.keys() - keys.sort() - rv.extend(["%s%s\n%s%s\n" % - (self._indent(), - self.elt('key', key), - self._indent(), - self.generate(v[key])) - for key in keys]) - self._indent_level = self._indent_level - 1 - rv.append(self._indent()) - rv.append('') - return ''.join(rv) - - def format(self, something): - data = [] - data.append('\n') - data.append(self.generate(something)) - data.append('\n') - return '\n'.join(data) - -def format_pretty_xml(something): - """@brief Serialize a python object as 'pretty' llsd xml. - - The output conforms to the LLSD DTD, unlike the output from the - standard python xml.dom DOM::toprettyxml() method which does not - preserve significant whitespace. - This function is not necessarily suited for serializing very large - objects. It is not optimized by the cllsd module, and sorts on - dict (llsd map) keys alphabetically to ease human reading. - """ - return LLSDXMLPrettyFormatter().format(something) - -class LLSDNotationFormatter(object): - def __init__(self): - self.type_map = { - type(None) : self.UNDEF, - bool : self.BOOLEAN, - int : self.INTEGER, - long : self.INTEGER, - float : self.REAL, - lluuid.UUID : self.UUID, - binary : self.BINARY, - str : self.STRING, - unicode : self.STRING, - uri : self.URI, - datetime.datetime : self.DATE, - datetime.date : self.DATE, - list : self.ARRAY, - tuple : self.ARRAY, - types.GeneratorType : self.ARRAY, - dict : self.MAP, - LLSD : self.LLSD - } - - def LLSD(self, v): - return self.generate(v.thing) - def UNDEF(self, v): - return '!' - def BOOLEAN(self, v): - if v: - return 'true' - else: - return 'false' - def INTEGER(self, v): - return "i%s" % v - def REAL(self, v): - return "r%s" % v - def UUID(self, v): - return "u%s" % v - def BINARY(self, v): - return 'b64"' + base64.encodestring(v) + '"' - def STRING(self, v): - if isinstance(v, unicode): - v = v.encode('utf-8') - return "'%s'" % v.replace("\\", "\\\\").replace("'", "\\'") - def URI(self, v): - return 'l"%s"' % str(v).replace("\\", "\\\\").replace('"', '\\"') - def DATE(self, v): - return 'd"%s"' % format_datestr(v) - def ARRAY(self, v): - return "[%s]" % ','.join([self.generate(item) for item in v]) - def MAP(self, v): - def fix(key): - if isinstance(key, unicode): - return key.encode('utf-8') - return key - return "{%s}" % ','.join(["'%s':%s" % (fix(key).replace("\\", "\\\\").replace("'", "\\'"), self.generate(value)) - for key, value in v.items()]) - - def generate(self, something): - t = type(something) - handler = self.type_map.get(t) - if handler: - return handler(something) - else: - try: - return self.ARRAY(iter(something)) - except TypeError: - raise LLSDSerializationError( - "Cannot serialize unknown type: %s (%s)" % (t, something)) - - def format(self, something): - return self.generate(something) - -def format_notation(something): - return LLSDNotationFormatter().format(something) - -def _hex_as_nybble(hex): - if (hex >= '0') and (hex <= '9'): - return ord(hex) - ord('0') - elif (hex >= 'a') and (hex <='f'): - return 10 + ord(hex) - ord('a') - elif (hex >= 'A') and (hex <='F'): - return 10 + ord(hex) - ord('A'); - -class LLSDBinaryParser(object): - def __init__(self): - pass - - def parse(self, buffer, ignore_binary = False): - """ - This is the basic public interface for parsing. - - @param buffer the binary data to parse in an indexable sequence. - @param ignore_binary parser throws away data in llsd binary nodes. - @return returns a python object. - """ - self._buffer = buffer - self._index = 0 - self._keep_binary = not ignore_binary - return self._parse() - - def _parse(self): - cc = self._buffer[self._index] - self._index += 1 - if cc == '{': - return self._parse_map() - elif cc == '[': - return self._parse_array() - elif cc == '!': - return None - elif cc == '0': - return False - elif cc == '1': - return True - elif cc == 'i': - # 'i' = integer - idx = self._index - self._index += 4 - return struct.unpack("!i", self._buffer[idx:idx+4])[0] - elif cc == ('r'): - # 'r' = real number - idx = self._index - self._index += 8 - return struct.unpack("!d", self._buffer[idx:idx+8])[0] - elif cc == 'u': - # 'u' = uuid - idx = self._index - self._index += 16 - return lluuid.uuid_bits_to_uuid(self._buffer[idx:idx+16]) - elif cc == 's': - # 's' = string - return self._parse_string() - elif cc in ("'", '"'): - # delimited/escaped string - return self._parse_string_delim(cc) - elif cc == 'l': - # 'l' = uri - return uri(self._parse_string()) - elif cc == ('d'): - # 'd' = date in seconds since epoch - idx = self._index - self._index += 8 - seconds = struct.unpack("!d", self._buffer[idx:idx+8])[0] - return datetime.datetime.fromtimestamp(seconds) - elif cc == 'b': - binary = self._parse_string() - if self._keep_binary: - return binary - # *NOTE: maybe have a binary placeholder which has the - # length. - return None - else: - raise LLSDParseError("invalid binary token at byte %d: %d" % ( - self._index - 1, ord(cc))) - - def _parse_map(self): - rv = {} - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - count = 0 - cc = self._buffer[self._index] - self._index += 1 - key = '' - while (cc != '}') and (count < size): - if cc == 'k': - key = self._parse_string() - elif cc in ("'", '"'): - key = self._parse_string_delim(cc) - else: - raise LLSDParseError("invalid map key at byte %d." % ( - self._index - 1,)) - value = self._parse() - rv[key] = value - count += 1 - cc = self._buffer[self._index] - self._index += 1 - if cc != '}': - raise LLSDParseError("invalid map close token at byte %d." % ( - self._index,)) - return rv - - def _parse_array(self): - rv = [] - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - count = 0 - cc = self._buffer[self._index] - while (cc != ']') and (count < size): - rv.append(self._parse()) - count += 1 - cc = self._buffer[self._index] - if cc != ']': - raise LLSDParseError("invalid array close token at byte %d." % ( - self._index,)) - self._index += 1 - return rv - - def _parse_string(self): - size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0] - self._index += 4 - rv = self._buffer[self._index:self._index+size] - self._index += size - return rv - - def _parse_string_delim(self, delim): - list = [] - found_escape = False - found_hex = False - found_digit = False - byte = 0 - while True: - cc = self._buffer[self._index] - self._index += 1 - if found_escape: - if found_hex: - if found_digit: - found_escape = False - found_hex = False - found_digit = False - byte <<= 4 - byte |= _hex_as_nybble(cc) - list.append(chr(byte)) - byte = 0 - else: - found_digit = True - byte = _hex_as_nybble(cc) - elif cc == 'x': - found_hex = True - else: - if cc == 'a': - list.append('\a') - elif cc == 'b': - list.append('\b') - elif cc == 'f': - list.append('\f') - elif cc == 'n': - list.append('\n') - elif cc == 'r': - list.append('\r') - elif cc == 't': - list.append('\t') - elif cc == 'v': - list.append('\v') - else: - list.append(cc) - found_escape = False - elif cc == '\\': - found_escape = True - elif cc == delim: - break - else: - list.append(cc) - return ''.join(list) - -class LLSDNotationParser(object): - """ Parse LLSD notation: - map: { string:object, string:object } - array: [ object, object, object ] - undef: ! - boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE - integer: i#### - real: r#### - uuid: u#### - string: "g\'day" | 'have a "nice" day' | s(size)"raw data" - uri: l"escaped" - date: d"YYYY-MM-DDTHH:MM:SS.FFZ" - binary: b##"ff3120ab1" | b(size)"raw data" - """ - def __init__(self): - pass - - def parse(self, buffer, ignore_binary = False): - """ - This is the basic public interface for parsing. - - @param buffer the notation string to parse. - @param ignore_binary parser throws away data in llsd binary nodes. - @return returns a python object. - """ - if buffer == "": - return False - - self._buffer = buffer - self._index = 0 - return self._parse() - - def _parse(self): - cc = self._buffer[self._index] - self._index += 1 - if cc == '{': - return self._parse_map() - elif cc == '[': - return self._parse_array() - elif cc == '!': - return None - elif cc == '0': - return False - elif cc == '1': - return True - elif cc in ('F', 'f'): - self._skip_alpha() - return False - elif cc in ('T', 't'): - self._skip_alpha() - return True - elif cc == 'i': - # 'i' = integer - return self._parse_integer() - elif cc == ('r'): - # 'r' = real number - return self._parse_real() - elif cc == 'u': - # 'u' = uuid - return self._parse_uuid() - elif cc in ("'", '"', 's'): - return self._parse_string(cc) - elif cc == 'l': - # 'l' = uri - delim = self._buffer[self._index] - self._index += 1 - val = uri(self._parse_string(delim)) - if len(val) == 0: - return None - return val - elif cc == ('d'): - # 'd' = date in seconds since epoch - return self._parse_date() - elif cc == 'b': - return self._parse_binary() - else: - raise LLSDParseError("invalid token at index %d: %d" % ( - self._index - 1, ord(cc))) - - def _parse_binary(self): - i = self._index - if self._buffer[i:i+2] == '64': - q = self._buffer[i+2] - e = self._buffer.find(q, i+3) - try: - return base64.decodestring(self._buffer[i+3:e]) - finally: - self._index = e + 1 - else: - raise LLSDParseError('random horrible binary format not supported') - - def _parse_map(self): - """ map: { string:object, string:object } """ - rv = {} - cc = self._buffer[self._index] - self._index += 1 - key = '' - found_key = False - while (cc != '}'): - if not found_key: - if cc in ("'", '"', 's'): - key = self._parse_string(cc) - found_key = True - elif cc.isspace() or cc == ',': - cc = self._buffer[self._index] - self._index += 1 - else: - raise LLSDParseError("invalid map key at byte %d." % ( - self._index - 1,)) - elif cc.isspace() or cc == ':': - cc = self._buffer[self._index] - self._index += 1 - continue - else: - self._index += 1 - value = self._parse() - rv[key] = value - found_key = False - cc = self._buffer[self._index] - self._index += 1 - - return rv - - def _parse_array(self): - """ array: [ object, object, object ] """ - rv = [] - cc = self._buffer[self._index] - while (cc != ']'): - if cc.isspace() or cc == ',': - self._index += 1 - cc = self._buffer[self._index] - continue - rv.append(self._parse()) - cc = self._buffer[self._index] - - if cc != ']': - raise LLSDParseError("invalid array close token at index %d." % ( - self._index,)) - self._index += 1 - return rv - - def _parse_uuid(self): - match = re.match(lluuid.UUID.uuid_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid uuid token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return lluuid.UUID(self._buffer[start:end]) - - def _skip_alpha(self): - match = re.match(alpha_regex, self._buffer[self._index:]) - if match: - self._index += match.end() - - def _parse_date(self): - delim = self._buffer[self._index] - self._index += 1 - datestr = self._parse_string(delim) - return parse_datestr(datestr) - - def _parse_real(self): - match = re.match(real_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid real token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return float( self._buffer[start:end] ) - - def _parse_integer(self): - match = re.match(int_regex, self._buffer[self._index:]) - if not match: - raise LLSDParseError("invalid integer token at index %d." % self._index) - - (start, end) = match.span() - start += self._index - end += self._index - self._index = end - return int( self._buffer[start:end] ) - - def _parse_string(self, delim): - """ string: "g\'day" | 'have a "nice" day' | s(size)"raw data" """ - rv = "" - - if delim in ("'", '"'): - rv = self._parse_string_delim(delim) - elif delim == 's': - rv = self._parse_string_raw() - else: - raise LLSDParseError("invalid string token at index %d." % self._index) - - return rv - - - def _parse_string_delim(self, delim): - """ string: "g'day 'un" | 'have a "nice" day' """ - list = [] - found_escape = False - found_hex = False - found_digit = False - byte = 0 - while True: - cc = self._buffer[self._index] - self._index += 1 - if found_escape: - if found_hex: - if found_digit: - found_escape = False - found_hex = False - found_digit = False - byte <<= 4 - byte |= _hex_as_nybble(cc) - list.append(chr(byte)) - byte = 0 - else: - found_digit = True - byte = _hex_as_nybble(cc) - elif cc == 'x': - found_hex = True - else: - if cc == 'a': - list.append('\a') - elif cc == 'b': - list.append('\b') - elif cc == 'f': - list.append('\f') - elif cc == 'n': - list.append('\n') - elif cc == 'r': - list.append('\r') - elif cc == 't': - list.append('\t') - elif cc == 'v': - list.append('\v') - else: - list.append(cc) - found_escape = False - elif cc == '\\': - found_escape = True - elif cc == delim: - break - else: - list.append(cc) - return ''.join(list) - - def _parse_string_raw(self): - """ string: s(size)"raw data" """ - # Read the (size) portion. - cc = self._buffer[self._index] - self._index += 1 - if cc != '(': - raise LLSDParseError("invalid string token at index %d." % self._index) - - rparen = self._buffer.find(')', self._index) - if rparen == -1: - raise LLSDParseError("invalid string token at index %d." % self._index) - - size = int(self._buffer[self._index:rparen]) - - self._index = rparen + 1 - delim = self._buffer[self._index] - self._index += 1 - if delim not in ("'", '"'): - raise LLSDParseError("invalid string token at index %d." % self._index) - - rv = self._buffer[self._index:(self._index + size)] - self._index += size - cc = self._buffer[self._index] - self._index += 1 - if cc != delim: - raise LLSDParseError("invalid string token at index %d." % self._index) - - return rv - -def format_binary(something): - return '\n' + _format_binary_recurse(something) - -def _format_binary_recurse(something): - def _format_list(something): - array_builder = [] - array_builder.append('[' + struct.pack('!i', len(something))) - for item in something: - array_builder.append(_format_binary_recurse(item)) - array_builder.append(']') - return ''.join(array_builder) - - if something is None: - return '!' - elif isinstance(something, LLSD): - return _format_binary_recurse(something.thing) - elif isinstance(something, bool): - if something: - return '1' - else: - return '0' - elif isinstance(something, (int, long)): - return 'i' + struct.pack('!i', something) - elif isinstance(something, float): - return 'r' + struct.pack('!d', something) - elif isinstance(something, lluuid.UUID): - return 'u' + something._bits - elif isinstance(something, binary): - return 'b' + struct.pack('!i', len(something)) + something - elif isinstance(something, str): - return 's' + struct.pack('!i', len(something)) + something - elif isinstance(something, unicode): - something = something.encode('utf-8') - return 's' + struct.pack('!i', len(something)) + something - elif isinstance(something, uri): - return 'l' + struct.pack('!i', len(something)) + something - elif isinstance(something, datetime.datetime): - seconds_since_epoch = time.mktime(something.timetuple()) - return 'd' + struct.pack('!d', seconds_since_epoch) - elif isinstance(something, (list, tuple)): - return _format_list(something) - elif isinstance(something, dict): - map_builder = [] - map_builder.append('{' + struct.pack('!i', len(something))) - for key, value in something.items(): - if isinstance(key, unicode): - key = key.encode('utf-8') - map_builder.append('k' + struct.pack('!i', len(key)) + key) - map_builder.append(_format_binary_recurse(value)) - map_builder.append('}') - return ''.join(map_builder) - else: - try: - return _format_list(list(something)) - except TypeError: - raise LLSDSerializationError( - "Cannot serialize unknown type: %s (%s)" % - (type(something), something)) - - -def parse_binary(binary): - if binary.startswith(''): - just_binary = binary.split('\n', 1)[1] - else: - just_binary = binary - return LLSDBinaryParser().parse(just_binary) - -def parse_xml(something): - try: - return to_python(fromstring(something)[0]) - except ElementTreeError, err: - raise LLSDParseError(*err.args) - -def parse_notation(something): - return LLSDNotationParser().parse(something) - -def parse(something): - try: - something = string.lstrip(something) #remove any pre-trailing whitespace - if something.startswith(''): - return parse_binary(something) - # This should be better. - elif something.startswith('<'): - return parse_xml(something) - else: - return parse_notation(something) - except KeyError, e: - raise Exception('LLSD could not be parsed: %s' % (e,)) - -class LLSD(object): - def __init__(self, thing=None): - self.thing = thing - - def __str__(self): - return self.toXML(self.thing) - - parse = staticmethod(parse) - toXML = staticmethod(format_xml) - toPrettyXML = staticmethod(format_pretty_xml) - toBinary = staticmethod(format_binary) - toNotation = staticmethod(format_notation) - - -undef = LLSD(None) - -XML_MIME_TYPE = 'application/llsd+xml' -BINARY_MIME_TYPE = 'application/llsd+binary' - -# register converters for llsd in mulib, if it is available -try: - from mulib import stacked, mu - stacked.NoProducer() # just to exercise stacked - mu.safe_load(None) # just to exercise mu -except: - # mulib not available, don't print an error message since this is normal - pass -else: - mu.add_parser(parse, XML_MIME_TYPE) - mu.add_parser(parse, 'application/llsd+binary') - - def llsd_convert_xml(llsd_stuff, request): - request.write(format_xml(llsd_stuff)) - - def llsd_convert_binary(llsd_stuff, request): - request.write(format_binary(llsd_stuff)) - - for typ in [LLSD, dict, list, tuple, str, int, long, float, bool, unicode, type(None)]: - stacked.add_producer(typ, llsd_convert_xml, XML_MIME_TYPE) - stacked.add_producer(typ, llsd_convert_xml, 'application/xml') - stacked.add_producer(typ, llsd_convert_xml, 'text/xml') - - stacked.add_producer(typ, llsd_convert_binary, 'application/llsd+binary') - - stacked.add_producer(LLSD, llsd_convert_xml, '*/*') - - # in case someone is using the legacy mu.xml wrapper, we need to - # tell mu to produce application/xml or application/llsd+xml - # (based on the accept header) from raw xml. Phoenix 2008-07-21 - stacked.add_producer(mu.xml, mu.produce_raw, XML_MIME_TYPE) - stacked.add_producer(mu.xml, mu.produce_raw, 'application/xml') - - - -# mulib wsgi stuff -# try: -# from mulib import mu, adapters -# -# # try some known attributes from mulib to be ultra-sure we've imported it -# mu.get_current -# adapters.handlers -# except: -# # mulib not available, don't print an error message since this is normal -# pass -# else: -# def llsd_xml_handler(content_type): -# def handle_llsd_xml(env, start_response): -# llsd_stuff, _ = mu.get_current(env) -# result = format_xml(llsd_stuff) -# start_response("200 OK", [('Content-Type', content_type)]) -# env['mu.negotiated_type'] = content_type -# yield result -# return handle_llsd_xml -# -# def llsd_binary_handler(content_type): -# def handle_llsd_binary(env, start_response): -# llsd_stuff, _ = mu.get_current(env) -# result = format_binary(llsd_stuff) -# start_response("200 OK", [('Content-Type', content_type)]) -# env['mu.negotiated_type'] = content_type -# yield result -# return handle_llsd_binary -# -# adapters.DEFAULT_PARSERS[XML_MIME_TYPE] = parse - -# for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]: -# for content_type in (XML_MIME_TYPE, 'application/xml'): -# adapters.handlers.set_handler(typ, llsd_xml_handler(content_type), content_type) -# -# adapters.handlers.set_handler(typ, llsd_binary_handler(BINARY_MIME_TYPE), BINARY_MIME_TYPE) -# -# adapters.handlers.set_handler(LLSD, llsd_xml_handler(XML_MIME_TYPE), '*/*') diff --git a/indra/viewer_components/manager/base/lluuid.py b/indra/viewer_components/manager/base/lluuid.py deleted file mode 100755 index 7413ffe10d..0000000000 --- a/indra/viewer_components/manager/base/lluuid.py +++ /dev/null @@ -1,319 +0,0 @@ -"""\ -@file lluuid.py -@brief UUID parser/generator. - -$LicenseInfo:firstyear=2004&license=mit$ - -Copyright (c) 2004-2009, Linden Research, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -$/LicenseInfo$ -""" - -import random, socket, string, time, re -import uuid -try: - # Python 2.6 - from hashlib import md5 -except ImportError: - # Python 2.5 and earlier - from md5 import new as md5 - -def _int2binstr(i,l): - s='' - for a in range(l): - s=chr(i&0xFF)+s - i>>=8 - return s - -def _binstr2int(s): - i = long(0) - for c in s: - i = (i<<8) + ord(c) - return i - -class UUID(object): - """ - A class which represents a 16 byte integer. Stored as a 16 byte 8 - bit character string. - - The string version is to be of the form: - AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - - NULL_STR = "00000000-0000-0000-0000-000000000000" - - # the UUIDREGEX_STRING is helpful for parsing UUID's in text - hex_wildcard = r"[0-9a-fA-F]" - word = hex_wildcard + r"{4,4}-" - long_word = hex_wildcard + r"{8,8}-" - very_long_word = hex_wildcard + r"{12,12}" - UUID_REGEX_STRING = long_word + word + word + word + very_long_word - uuid_regex = re.compile(UUID_REGEX_STRING) - - rand = random.Random() - ip = '' - try: - ip = socket.gethostbyname(socket.gethostname()) - except(socket.gaierror, socket.error): - # no ip address, so just default to somewhere in 10.x.x.x - ip = '10' - for i in range(3): - ip += '.' + str(rand.randrange(1,254)) - hexip = ''.join(["%04x" % long(i) for i in ip.split('.')]) - lastid = '' - - def __init__(self, possible_uuid=None): - """ - Initialize to first valid UUID in argument (if a string), - or to null UUID if none found or argument is not supplied. - - If the argument is a UUID, the constructed object will be a copy of it. - """ - self._bits = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - if possible_uuid is None: - return - - if isinstance(possible_uuid, type(self)): - self.set(possible_uuid) - return - - uuid_match = UUID.uuid_regex.search(possible_uuid) - if uuid_match: - uuid_string = uuid_match.group() - s = string.replace(uuid_string, '-', '') - self._bits = _int2binstr(string.atol(s[:8],16),4) + \ - _int2binstr(string.atol(s[8:16],16),4) + \ - _int2binstr(string.atol(s[16:24],16),4) + \ - _int2binstr(string.atol(s[24:],16),4) - - def __len__(self): - """ - Used by the len() builtin. - """ - return 36 - - def __nonzero__(self): - return self._bits != "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - - def __str__(self): - uuid_string = self.toString() - return uuid_string - - __repr__ = __str__ - - def __getitem__(self, index): - return str(self)[index] - - def __eq__(self, other): - if isinstance(other, (str, unicode)): - return other == str(self) - return self._bits == getattr(other, '_bits', '') - - def __ne__(self, other): - return not self.__eq__(other) - - def __le__(self, other): - return self._bits <= other._bits - - def __ge__(self, other): - return self._bits >= other._bits - - def __lt__(self, other): - return self._bits < other._bits - - def __gt__(self, other): - return self._bits > other._bits - - def __hash__(self): - return hash(self._bits) - - def set(self, uuid): - self._bits = uuid._bits - - def setFromString(self, uuid_string): - """ - Given a string version of a uuid, set self bits - appropriately. Returns self. - """ - s = string.replace(uuid_string, '-', '') - self._bits = _int2binstr(string.atol(s[:8],16),4) + \ - _int2binstr(string.atol(s[8:16],16),4) + \ - _int2binstr(string.atol(s[16:24],16),4) + \ - _int2binstr(string.atol(s[24:],16),4) - return self - - def setFromMemoryDump(self, gdb_string): - """ - We expect to get gdb_string as four hex units. eg: - 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 - Which will be translated to: - db547d14-1b3f4bc3-9b984f71-d22f890a - Returns self. - """ - s = string.replace(gdb_string, '0x', '') - s = string.replace(s, ' ', '') - t = '' - for i in range(8,40,8): - for j in range(0,8,2): - t = t + s[i-j-2:i-j] - self.setFromString(t) - - def toString(self): - """ - Return as a string matching the LL standard - AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - return uuid_bits_to_string(self._bits) - - def getAsString(self): - """ - Return a different string representation of the form - AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex) - where A=network address, B=timestamp, C=random. - """ - i1 = _binstr2int(self._bits[0:4]) - i2 = _binstr2int(self._bits[4:8]) - i3 = _binstr2int(self._bits[8:12]) - i4 = _binstr2int(self._bits[12:16]) - return '%08lx-%08lx-%08lx-%08lx' % (i1,i2,i3,i4) - - def generate(self): - """ - Generate a new uuid. This algorithm is slightly different - from c++ implementation for portability reasons. - Returns self. - """ - m = md5() - m.update(uuid.uuid1().bytes) - self._bits = m.digest() - return self - - def isNull(self): - """ - Returns 1 if the uuid is null - ie, equal to default uuid. - """ - return (self._bits == "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") - - def xor(self, rhs): - """ - xors self with rhs. - """ - v1 = _binstr2int(self._bits[0:4]) ^ _binstr2int(rhs._bits[0:4]) - v2 = _binstr2int(self._bits[4:8]) ^ _binstr2int(rhs._bits[4:8]) - v3 = _binstr2int(self._bits[8:12]) ^ _binstr2int(rhs._bits[8:12]) - v4 = _binstr2int(self._bits[12:16]) ^ _binstr2int(rhs._bits[12:16]) - self._bits = _int2binstr(v1,4) + \ - _int2binstr(v2,4) + \ - _int2binstr(v3,4) + \ - _int2binstr(v4,4) - - -# module-level null constant -NULL = UUID() - -def printTranslatedMemory(four_hex_uints): - """ - We expect to get the string as four hex units. eg: - 0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2 - Which will be translated to: - db547d14-1b3f4bc3-9b984f71-d22f890a - """ - uuid = UUID() - uuid.setFromMemoryDump(four_hex_uints) - print uuid.toString() - -def isUUID(id_str): - """ - This function returns: - - 1 if the string passed is a UUID - - 0 is the string passed is not a UUID - - None if it neither of the if's below is satisfied - """ - if not id_str or len(id_str) < 5 or len(id_str) > 36: - return 0 - - if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str): - return 1 - - return None - -def isPossiblyID(id_str): - """ - This function returns 1 if the string passed has some uuid-like - characteristics. Otherwise returns 0. - """ - - is_uuid = isUUID(id_str) - if is_uuid is not None: - return is_uuid - - # build a string which matches every character. - hex_wildcard = r"[0-9a-fA-F]" - chars = len(id_str) - next = min(chars, 8) - matcher = hex_wildcard+"{"+str(next)+","+str(next)+"}" - chars = chars - next - if chars > 0: - matcher = matcher + "-" - chars = chars - 1 - for block in range(3): - next = max(min(chars, 4), 0) - if next: - matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" - chars = chars - next - if chars > 0: - matcher = matcher + "-" - chars = chars - 1 - if chars > 0: - next = min(chars, 12) - matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}" - #print matcher - uuid_matcher = re.compile(matcher) - if uuid_matcher.match(id_str): - return 1 - return 0 - -def uuid_bits_to_string(bits): - i1 = _binstr2int(bits[0:4]) - i2 = _binstr2int(bits[4:6]) - i3 = _binstr2int(bits[6:8]) - i4 = _binstr2int(bits[8:10]) - i5 = _binstr2int(bits[10:12]) - i6 = _binstr2int(bits[12:16]) - return '%08lx-%04lx-%04lx-%04lx-%04lx%08lx' % (i1,i2,i3,i4,i5,i6) - -def uuid_bits_to_uuid(bits): - return UUID(uuid_bits_to_string(bits)) - - -try: - from mulib import stacked - stacked.NoProducer() # just to exercise stacked -except: - #print "Couldn't import mulib.stacked, not registering UUID converter" - pass -else: - def convertUUID(uuid, req): - req.write(str(uuid)) - - stacked.add_producer(UUID, convertUUID, "*/*") - stacked.add_producer(UUID, convertUUID, "text/html") diff --git a/indra/viewer_components/manager/util/fastest_elementtree.py b/indra/viewer_components/manager/util/fastest_elementtree.py deleted file mode 100755 index 4fcf662dd9..0000000000 --- a/indra/viewer_components/manager/util/fastest_elementtree.py +++ /dev/null @@ -1,64 +0,0 @@ -"""\ -@file fastest_elementtree.py -@brief Concealing some gnarly import logic in here. This should export the interface of elementtree. - -$LicenseInfo:firstyear=2008&license=mit$ - -Copyright (c) 2008-2009, Linden Research, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -$/LicenseInfo$ -""" - -# The parsing exception raised by the underlying library depends -# on the ElementTree implementation we're using, so we provide an -# alias here. -# -# Use ElementTreeError as the exception type for catching parsing -# errors. - - -# Using cElementTree might cause some unforeseen problems, so here's a -# convenient off switch. -use_celementree = True - -try: - if not use_celementree: - raise ImportError() - # Python 2.3 and 2.4. - from cElementTree import * - ElementTreeError = SyntaxError -except ImportError: - try: - if not use_celementree: - raise ImportError() - # Python 2.5 and above. - from xml.etree.cElementTree import * - ElementTreeError = SyntaxError - except ImportError: - # Pure Python code. - try: - # Python 2.3 and 2.4. - from elementtree.ElementTree import * - except ImportError: - # Python 2.5 and above. - from xml.etree.ElementTree import * - - # The pure Python ElementTree module uses Expat for parsing. - from xml.parsers.expat import ExpatError as ElementTreeError From 1224697a40a469bebd794c5816d6cc9c34e1000a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 22 Jul 2016 13:23:59 -0700 Subject: [PATCH 032/183] SL-323: Changes to viewer manifest to move llbase to where Launcher can find them --- indra/newview/viewer_manifest.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index d3ab05b9bd..aaad79387f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -355,7 +355,7 @@ class Windows_i686_Manifest(ViewerManifest): 'llplugin', 'slplugin', self.args['configuration']), "slplugin.exe") - self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat") + #note, launcher and friends do not need viewer_manifest in Windows as the scripts are compiled into executables # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): @@ -712,9 +712,10 @@ class Darwin_i386_Manifest(ViewerManifest): if self.prefix(dst="MacOS"): self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") - #this copies over the python wrapper script and associated utilities, see SL-321, SL-322 and SL-323 + #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 self.path2basename("../viewer_components/manager","SL_Launcher") self.path2basename("../viewer_components/manager","*.py") + self.path2basename("../../../../../packages/llbase","*") self.end_prefix() # most everything goes in the Resources directory @@ -1067,7 +1068,10 @@ class LinuxManifest(ViewerManifest): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") self.path2basename("../llplugin/slplugin", "SLPlugin") - self.path2basename("../viewer_components/updater/scripts/linux", "update_install") + #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 + self.path2basename("../viewer_components/manager","SL_Launcher") + self.path2basename("../viewer_components/manager","*.py") + self.path2basename("../packages/llbase","*") self.end_prefix("bin") if self.prefix("res-sdl"): From f44829f2aefe8c5fae9fba6bb838500719e1067e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 27 Jul 2016 15:44:56 -0700 Subject: [PATCH 033/183] SL-321: basic launcher/updater integration test fixes --- autobuild.xml | 14 +-- indra/newview/viewer_manifest.py | 20 +++- indra/viewer_components/manager/SL_Launcher | 59 +++++----- .../manager/update_manager.py | 101 +++++++++++------- 4 files changed, 119 insertions(+), 75 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1c04fb85fe..469f1c32f5 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1482,9 +1482,9 @@ archive hash - 313f5c8edd328e05c59cbe980512f84c + 13998879705aa1af36c6ea8f480901e3 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/Darwin/installer/llbase-0.8.6.317790-darwin-317790.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Darwin/installer/llbase-0.8.6.318106-darwin-318106.tar.bz2 name darwin @@ -1494,9 +1494,9 @@ archive hash - e85171c70b57dd086b956ba36e6f2306 + 80ef3f9f6bde28787b02837ace2ad84c url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/Linux/installer/llbase-0.8.6.317790-linux-317790.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Linux/installer/llbase-0.8.6.318106-linux-318106.tar.bz2 name linux @@ -1506,16 +1506,16 @@ archive hash - 07b0d64d812cfaf3025b799cea5fe446 + 57837daafa60f98a4d9fa4dfe53d995e url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/317790/arch/CYGWIN/installer/llbase-0.8.6.0-windows-317790.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/CYGWIN/installer/llbase-0.8.6.0-windows-318106.tar.bz2 name windows version - 0.8.6.317790 + 0.8.6.318106 llceflib diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index aaad79387f..3572b7dba8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -27,6 +27,7 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA $/LicenseInfo$ """ import sys +import os import os.path import shutil import errno @@ -702,6 +703,7 @@ class Darwin_i386_Manifest(ViewerManifest): pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") + llbasedir = os.path.join(pkgdir, os.pardir) if self.prefix(src="", dst="Contents"): # everything goes in Contents self.path("Info.plist", dst="Info.plist") @@ -715,8 +717,14 @@ class Darwin_i386_Manifest(ViewerManifest): #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 self.path2basename("../viewer_components/manager","SL_Launcher") self.path2basename("../viewer_components/manager","*.py") - self.path2basename("../../../../../packages/llbase","*") - self.end_prefix() + llbase_path = os.path.join(self.get_dst_prefix(),'llbase') + if not os.path.exists(llbase_path): + os.makedirs(llbase_path) + if self.prefix(dst="llbase"): + self.path2basename("../packages/llbase","*.py") + self.path2basename("../packages/llbase","_cllsd.so") + self.end_prefix() + self.end_prefix() # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): @@ -1071,7 +1079,13 @@ class LinuxManifest(ViewerManifest): #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 self.path2basename("../viewer_components/manager","SL_Launcher") self.path2basename("../viewer_components/manager","*.py") - self.path2basename("../packages/llbase","*") + llbase_path = os.path.join(self.get_dst_prefix(),'llbase') + if not os.path.exists(llbase_path): + os.makedirs(llbase_path) + if self.prefix(dst="llbase"): + self.path2basename("../packages/llbase","*.py") + self.path2basename("../packages/llbase","_cllsd.so") + self.end_prefix() self.end_prefix("bin") if self.prefix("res-sdl"): diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index a96f2392a7..dde7cd9c2e 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -17,43 +17,51 @@ # $/LicenseInfo$ # Copyright (c) 2013, Linden Research, Inc. +import os +import sys + +#module globals +log_file_handle = None +cwd = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(cwd, 'llbase')) + import argparse import collections import InstallerUserMessage #NOTA BENE: # For POSIX platforms, llsd.py will be imported from the same directory. # For Windows, llsd.py will be compiled into the executable by pyinstaller -import llsd -import os +from llbase import llsd import platform -import sys import subprocess import update_manager -def after_frame(my_message, timeout = 10000): - #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds - #note that this blocks the caller for the duration of timeout - frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") - #this is done before basic_message so that we aren't blocked by mainloop() - frame.after(timout, lambda: frame._delete_window) - frame.basic_message(message = my_message) - + +def silent_write(log_file_handle, text): + #if we have a log file, write. If not, do nothing. + #this is so we don't have to keep trapping for an exception with a None handle + #oh and because it is best effort, it is also a holey_write ;) + if (log_file_handle): + #prepend text for easy grepping + log_file_handle.write("SL LAUNCHER: " + text + "\n") + def get_cmd_line(): platform_name = platform.system() #find the parent of the logs and user_settings directories - if (platform_name == 'mac'): + if (platform_name == 'Darwin'): settings_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'Resources/app_settings/cmd_line.xml') - elif (platform_name == 'lnx'): + elif (platform_name == 'Linux'): settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') #using list format of join is important here because the Windows pathsep in a string escapes the next char - elif (platform_name == 'win'): + elif (platform_name == 'Windows'): settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') else: - settings_dir = None + settings_file = None try: cmd_line = llsd.parse((open(settings_file)).read()) except: + silent_write(log_file_handle, "Could not parse settings file %s" % settings_file) cmd_line = None return cmd_line @@ -68,7 +76,6 @@ def get_settings(): return None return settings - def capture_vmp_args(arg_list = None, cmd_line = None): #expected input format: arg_list = ['--set', 'foo', 'bar', '-X', '-Y', 'qux'] #take a copy of the viewer parameters that are of interest to VMP. @@ -96,7 +103,8 @@ def capture_vmp_args(arg_list = None, cmd_line = None): cli_overrides[vmp_params[param]] = (setting_name, setting_value) else: #find out how many args this parameter has - count = cmd_line[param]['count'] + no_dashes = vmp_params[param] + count = cmd_line[no_dashes]['count'] param_args = [] if count: for argh in range(1,count): @@ -112,6 +120,7 @@ def capture_vmp_args(arg_list = None, cmd_line = None): except KeyError: cli_overrides[key] = None else: + cli_overrides["--set"] = {} for arg in vmp_setters: try: cli_overrides[key][arg] @@ -119,7 +128,10 @@ def capture_vmp_args(arg_list = None, cmd_line = None): cli_overrides[key][arg] = None return cli_overrides -cwd = os.path.dirname(os.path.realpath(__file__)) +#main entry point +#this and a few other update manager methods really should be refactored into a util lib +parent_dir = update_manager.get_parent_path(update_manager.get_platform_key()) +log_file_handle = update_manager.get_log_file_handle(parent_dir) executable_name = "" if sys.platform.startswith('darwin'): @@ -137,23 +149,18 @@ else: #SL doesn't run on VMS or punch cards sys.exit("Unsupported platform") -#check for an update -#TODO - #find the viewer to be lauched viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name) parser = argparse.ArgumentParser() args = parser.parse_known_args(sys.argv) -print args[1] -sys.exit() #args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname args_list_to_pass = args[1][1:] vmp_args = capture_vmp_args(args_list_to_pass) #make a copy by value, not by reference command = list(args_list_to_pass) -(success, state, condition) = update_manager.update_manager(cli_overrides) +(success, state, condition) = update_manager.update_manager(vmp_args) # From update_manager: # (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) # (False, 'download', version): we failed to download the new version @@ -167,8 +174,8 @@ command = list(args_list_to_pass) # No update, update succeeded in place in foreground, or background update started: silently launch the current viewer channel # Updated succeed to a different channel, launch that viewer and exit if not success: - msg = 'Update failed in the %s process. Please check logs. Viewer will launch starting momentarily.' - after_frame(msg) + msg = 'Update failed in the %s process. Please check logs. Viewer will launch starting momentarily.' % state + update_manager.after_frame(msg) command.insert(0,viewer_binary) viewer_process = subprocess.Popen(command) #at the moment, we just exit here. Later, the crash monitor will be launched at this point diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index a7e0a19aef..398c8bb55d 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -1,29 +1,35 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ -# Copyright (c) 2013, Linden Research, Inc. - -""" -@file update_manager.py +"""\ +@file update_manager.py @author coyot -@date 2016-05-16 +@date 2016-05-16 +@brief executes viewer update checking and manages downloading and applying of updates + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from llbase import llrest +from llbase.llrest import RESTError from llbase import llsd from urlparse import urljoin @@ -55,9 +61,9 @@ def silent_write(log_file_handle, text): def after_frame(my_message, timeout = 10000): #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds #note that this blocks the caller for the duration of timeout - frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") + frame = InstallerUserMessage.InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") #this is done before basic_message so that we aren't blocked by mainloop() - frame.after(timout, lambda: frame._delete_window) + frame.after(timeout, lambda: frame._delete_window) frame.basic_message(message = my_message) def convert_version_file_style(version): @@ -146,8 +152,10 @@ def check_for_completed_download(download_dir): def get_settings(log_file_handle, parent_dir): #return the settings file parsed into a dict + print str(parent_dir) try: settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) + print "Settings file: " + str(settings_file) settings = llsd.parse((open(settings_file)).read()) except llsd.LLSDParseError as lpe: silent_write(log_file_handle, "Could not parse settings file %s" % lpe) @@ -213,7 +221,7 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ else: base_URI = 'https://update.secondlife.com/update/' channelname = summary_dict['Channel'] - #this is kind of a mess because the settings value a) in a map and b) is both the cohort and the version + #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version version = summary_dict['Version'] platform_version = platform.release() #this will always return something usable, error handling in method @@ -250,7 +258,7 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ try: result_data = VVMService.get(query_string) except RESTError as re: - silent_write.write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string, re))) + silent_write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string), re)) return None return result_data @@ -342,6 +350,8 @@ def update_manager(cli_overrides = None): platform_key = get_platform_key() parent_dir = get_parent_path(platform_key) log_file_handle = get_log_file_handle(parent_dir) + settings = None + print "parent dir: " + str(parent_dir) #check to see if user has install rights #get the owner of the install and the current user @@ -367,10 +377,12 @@ def update_manager(cli_overrides = None): print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) return (False, 'setup', None) - if cli_overrides['settings'] is not None: - settings = get_settings(log_file_handle, cli_overrides['settings']) - else: - settings = get_settings(log_file_handle, parent_dir) + if cli_overrides is not None: + if '--settings' in cli_overrides.keys(): + if cli_overrides['--settings'] is not None: + settings = get_settings(log_file_handle, cli_overrides['--settings']) + else: + settings = get_settings(log_file_handle, parent_dir) if settings is None: silent_write(log_file_handle, "Failed to load viewer settings") @@ -379,7 +391,7 @@ def update_manager(cli_overrides = None): #323: If a complete download of that update is found, check the update preference: #settings['UpdaterServiceSetting'] = 0 is manual install - """ + """ssh://hg@bitbucket.org/lindenlab/viewer-release-maint-6585 UpdaterServiceSetting Comment @@ -390,8 +402,10 @@ def update_manager(cli_overrides = None): 0 """ - if cli_overrides['set']['UpdaterServiceSetting'] is not None: - install_automatically = cli_overrides['set']['UpdaterServiceSetting'] + if cli_overrides is not None: + if '--set' in cli_overrides.keys(): + if 'UpdaterServiceSetting' in cli_overrides['--set'].keys(): + install_automatically = cli_overrides['--set']['UpdaterServiceSetting'] else: try: install_automatically = settings['UpdaterServiceSetting']['Value'] @@ -399,28 +413,37 @@ def update_manager(cli_overrides = None): except KeyError: install_automatically = 1 - #use default chunk size if none is given - if cli_overrides['set']['UpdaterMaximumBandwidth ']: - chunk_size = cli_overrides['set']['UpdaterMaximumBandwidth '] + #use default chunk size if none is given + if cli_overrides is not None: + if '--set' in cli_overrides.keys(): + if 'UpdaterMaximumBandwidth' in cli_overrides['--set'].keys(): + chunk_size = cli_overrides['--set']['UpdaterMaximumBandwidth'] else: chunk_size = 1024 #get channel and version try: summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) - if cli_overrides['channel']: - summary_dict['Channel'] = cli_overrides['channel'] - except: + if cli_overrides is not None: + if 'channel' in cli_overrides.keys(): + summary_dict['Channel'] = cli_overrides['channel'] + except Exception, e: silent_write(log_file_handle, "Could not obtain channel and version, exiting.") + silent_write(log_file_handle, e.message) print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) return (False, 'setup', None) #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. - UpdaterServiceURL = cli_overrides['update-service'] + if cli_overrides is not None: + if '--update-service' in cli_overrides.keys(): + UpdaterServiceURL = cli_overrides['--update-service'] + else: + #tells query_vvm to use the default + UpdaterServiceURL = None result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict, UpdaterServiceURL) #nothing to do or error if not result_data: - silent_write.write(og_file_handle, "No update found.") + silent_write(log_file_handle, "No update found.") print "Update manager exited with (%s, %s, %s)" % (True, None, None) return (True, None, None) From 2bb4214866ddd17578ff094b83f3bcf5a46053c0 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 28 Jul 2016 07:57:34 -0700 Subject: [PATCH 034/183] trivial change to bump build --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad040fb077..6eddb9aa9e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Second Life Viewer ==================== - + This project manages the source code for the [Second Life](https://www.secondlife.com) Viewer. From fc7c0645fa9c9d47c1462387a3de82a2a4474467 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 28 Jul 2016 08:50:52 -0700 Subject: [PATCH 035/183] SL-321: add in resource files, more CLI handling fixes --- indra/viewer_components/Resources/README | 9 ++++ .../viewer_components/Resources/summary.json | 1 + .../manager/InstallerError.py | 49 ++++++++++++++++++ indra/viewer_components/manager/SL_Launcher | 5 +- .../manager/icons/SL_Logo.gif | Bin 0 -> 1322 bytes .../manager/icons/SL_Logo.png | Bin 0 -> 1484 bytes .../manager/icons/head-sl-logo.gif | Bin 0 -> 960 bytes .../manager/icons/head-sl-logo.png | Bin 0 -> 2316 bytes .../manager/update_manager.py | 11 +++- 9 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 indra/viewer_components/Resources/README create mode 100644 indra/viewer_components/Resources/summary.json create mode 100644 indra/viewer_components/manager/InstallerError.py create mode 100644 indra/viewer_components/manager/icons/SL_Logo.gif create mode 100644 indra/viewer_components/manager/icons/SL_Logo.png create mode 100644 indra/viewer_components/manager/icons/head-sl-logo.gif create mode 100644 indra/viewer_components/manager/icons/head-sl-logo.png diff --git a/indra/viewer_components/Resources/README b/indra/viewer_components/Resources/README new file mode 100644 index 0000000000..e1b35730d4 --- /dev/null +++ b/indra/viewer_components/Resources/README @@ -0,0 +1,9 @@ +This directory only exists as a place for the summary.json file to exist when the unit tests are run on a Mac, where the file goes to a sibling directory of the scripts dir. In Linux and Windows, the JSON file goes into the same directory as the script. + +See: + +test_get_summary.py +update_manager.get_summary() + +for more details +- coyot 201606.02 diff --git a/indra/viewer_components/Resources/summary.json b/indra/viewer_components/Resources/summary.json new file mode 100644 index 0000000000..b78859d427 --- /dev/null +++ b/indra/viewer_components/Resources/summary.json @@ -0,0 +1 @@ +{"Type":"viewer","Version":"4.0.5.315117","Channel":"Second Life Release"} diff --git a/indra/viewer_components/manager/InstallerError.py b/indra/viewer_components/manager/InstallerError.py new file mode 100644 index 0000000000..3b199ea231 --- /dev/null +++ b/indra/viewer_components/manager/InstallerError.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +"""\ +@file InstallerError.py +@author coyot +@date 2016-05-16 +@brief custom exception class for VMP + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" + +""" +usage: + +>>> import InstallerError +>>> import os +>>> try: +... os.mkdir('/tmp') +... except OSError, oe: +... ie = InstallerError.InstallerError(oe, "foo") +... raise ie + +Traceback (most recent call last): + File "", line 5, in +InstallerError.InstallerError: [Errno [Errno 17] File exists: '/tmp'] foo +""" + +class InstallerError(OSError): + def __init___(self, message): + Exception.__init__(self, message) diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index dde7cd9c2e..0403e01cec 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -106,11 +106,12 @@ def capture_vmp_args(arg_list = None, cmd_line = None): no_dashes = vmp_params[param] count = cmd_line[no_dashes]['count'] param_args = [] - if count: - for argh in range(1,count): + if count > 0: + for argh in range(0,count): param_args.append(vmp_queue.popleft()) #the parameter name is the key, the (possibly empty) list of args is the value cli_overrides[vmp_params[param]] = param_args + print "cli override param %s vmp_param %s args %s count %s" % (param, vmp_params[param], param_args, count) #to prevent KeyErrors on missing keys, set the remainder to None for key in vmp_params: diff --git a/indra/viewer_components/manager/icons/SL_Logo.gif b/indra/viewer_components/manager/icons/SL_Logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..c24d6b08cbda0d7d597932733eb04b9f805b858a GIT binary patch literal 1322 zcmb``X;YF3003ZAP*N%o?(WoFyAP$4Y1>%CRhX~jpJPtz&!V`lC zL_Cp1Acq8FsKJC#a!6aV;PE^Ol5AC z>O{6W??_Vq(X`@xjp1a5;gqhdAo+A*=INp%6~!5qCC9%k&8jZTsVX~OQ*y#so?lyW z%yjl--Pz;ymAQ>og$>mwnyT}gYfiP+6||WO&)1i=HR#Qa`PQaVOYIr+xf1KS3QM!0 zqq)@9Qr6k3cb-4vY_IIGmJYO+_jelm?G=NLszFQ5faC0tvt-OxH`H}*u&ZUbr*70< z=yEn(>@|%!PER@;M=!Kpyih&a)jrl=H#yKcIn?GFwz)>?=lZJ`20EuM+NVbyGh^2I z@#ZTdZI>tNmq%N#jW)Q)%-5#cmd7kh)92me_T@|F>k|(5WcTu{Wp&cI;%f1@dfane z*QYvH=Q}*p-K*1WYtzFki?$mx4$orW>gCS0S^N5&`PRJi=0fkrQrE4;q4lM{TW;6J z%GAy4gLhWPZm(Xt>zVlKhHG$u19x2|9^l_!K&I)y{XhdYdm8r zr)iVZGilXTG(9a{UjhR@!oB=qpJ80szy2EoLw^xkJxH0 zdVF#T)xZ4y1KR!bpf{>0o0dBVS>T19j~vA=X*Te#c?!&athD&UCG^~uV!VXWJ)+xGmNz5#?swxj zWTkcchrQbxFXm!<^*t}s>ed}U;ZQ-D=#^)CowxHMl-m^_I9aZ81^+_IvpLm4E2P_S zUVe`tCq(rb_q?tmI5MX0-2hDabhjHn+eg{6=<-10FPnq!?#Ehe>6F+j+sE42KnEwc?j>3p6-mm$N_h^e|ggre9mh(NhQcDjSW{Q+MB z_+;)08w4YKhYL*4Y}j!wwvRW$eeL9azi3Uuo@)BQ@K(+OcH*($UfIJIaKkA6#M>Gl oT;n{T)*#;&X~@0SZQEhNCTs_tv$B1S6lc(G%uq;BQV;+DAtM~tlEafn z0`YNrSG|`e2QscWOH%;2BL@KY?gPNiA%_eA2u1?HqB8(sasWWgH{FS9z}e+9V_0|5XmawIMwH&6V?4Dr(;aro~oV1ml90RWypBdiWVqdz~>*vo!M zs{8Ij@M^xqC;M@Kc8-xtf@~KSE($v#9DLq_H%72RFuG6<8>?SxRgMj*RD=g7Xe-&) za+hpO0LqG`<_XjF@ZY)B1fr3(SGGpO9Ji84^KE8giKfqDg-DSsP5RCO{W3-2$Cwe* zr4i5qvw0NO-dhQ12x{G^9x?9R-p}t)?eX7zEc=caKI8+JEAP=OwV$y{_;ajH$>C{BO`?2T#}{SH;Q4BtxZ5&d2su1rBIu#AYw__ZjqZcJ)ni~X8Lag3 zt9keI{2lSbFCTGNTC8a#0(?GQjjaE`uWO@BC42M)^p1b+$ zx3`cF9=OYY4P@JTzv*3_dY8XFWqPMDG@q+*q=UF*e7&XyY5jcHJ8tSADj>2|?NmRm zW8J>QDyKjcOqK8wW%j;vs*7YBm{BnLErX8yPQ^BeI3e9El`PQAgEZZOVZ2BhC}}o* zGY|x~srs5~Kx_BRIgARCJcYGJWLYZ?6I};SV+Fu8IoQ)w=}Fy6qMq}YDtI=t)+}^yoyH-Ce?)so|I%55{`n+KcK7cJPokk}B@GvGdyVnh+wirAWId?H;2ogp4 zwBGkfwO0God -0w}F!!fWQWT^QmKbqA&CE4k21yDK|OGJ=6^W;Et!8mn`5{nE*# zfmwmzCtaJf=k&3k8L+Nj^z`0qu}7;t##0#q0`emZ?|vgu^Ye6op4xI8W9@YA^OhUoo2%eaxfhj1r*@fzm*AeGgx~UQKwrR6t=; zW)BUj3~*gdC#-u+6)~0S!^EU7dF%xXw;UN5xjqKlG3wnsR_}ejTU;ei^IB_bXKyda z>fut4DI%^+D3C^zO`O|GZ1xySJw3a@XitF?9o)o4f-v?!>9$$77W%{lV=b_*jnNjn zdz2uv+XGSl@#~QdC=_w}^W$r4^A**!s*6AO`hAf|EnL}Tk?o6G?+E#D`4zV|HN)j` z!8jB8jniQI_R`+gGILg=n`m6zjJLCm+UnqXvobnRL+@d;l0tJsYcypeBmQ=YC+eNQW1MURMcaKyecMGdbw8--^|)=()N}%t>z8 zHPonH)x|t5dR5=mckTJl>E-q`9U5ieSw^S0Ua4h~RYmLB2s)kDBqcd{6AFR2sPIcU zH`d{cCrhOGf;xfQ%0xx2+0@O!g$vn?HK-D8V-B?+ z+3I*yQ5r#5gRpJbTY?k{y7gdmZqrnH{P6=&}?#An6zY(?(Btv zzRNlIxRqtTSNe&E-FnYILwEh}t>x9xvQ74l^&OEy70pe_t+9~|lNq9>mI_woW%dQn z7LxR4WLe_Ez{JJF!{x-lymT!i8=Lbw4(7Exmak=6!s094IxqilbfGtkz^ScF{7wQ} zc{~_+PunxF+FxVf5n$z5`{0_lc#lM1VP1Ew%gM(K92YL%-S2dA8Mi$v-`cx;oDb_{ zP8?5RTI}3=Pr>Jr-@FMGTzX%n%ijxa&%R`!Rb0j^!`Q!RlFN@rY>CT!gJ+ni6gfmT zv$Cr-ZDxOX%_Zw^T?jXOBg4M~j4LgKJk^gpP;+ky(JJmpiQe9GzU5!XasB5E?H{Fh zA{_)y?p&O3zb4R%?_?vpkFaK^L!wild)2*N3lH#}JQcQ1!!dNX3ez21!AVlLO4gmc zo6V)5<1j%&e`)3vCGT~rJBwKOn@m#lcD|Ijx#iX~-MM1htW5d;XNh&@hZ9G;Wz-ly_ka2R-q?vvzS8{Zea-1WZwhX9PqdF& za8ho;p9y{0CY%-z>hImXHd%kemZVus5(ob&xhm!_IDSyciG}$g|83tJ@eR9X9-3ow z^h4u)ez%R!TdKG1eX*$6K7!$q*vpd-uXk#8u`Os__4dXi{*u2Li%Ol>Bqs}7Tr0ZW z`>At@r>IK^J7?1$&y18-R=>%qLi1W4IEsk$e2w&<>T7gyVyaeTaH?|!=OI=hmrrei zVmp2=W8x6W%2-%DNi$7%nPGv(BIgMuv1}3?>5gnyGruS0hJMFR8grSf2ENS+i6gEatM+{p6) literal 0 HcmV?d00001 diff --git a/indra/viewer_components/manager/icons/head-sl-logo.png b/indra/viewer_components/manager/icons/head-sl-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5c214e96d1cc22698384815cd696cb780fd0e16a GIT binary patch literal 2316 zcmV+n3G?=eP)34P@5 zhYzcJkXkSntdjx}**Ie9Cq!UZYV{_2O_L#cgMQBDJwz>lH5;U3;z_+$<3CmNWbpF4 zCtoh_LAq9){0A((4vnnhC)ZHL1iEI?Uu@F_CKIcNs2|2Hwt9H~GXt`DqNvaKKMJ~V zkHS0>{yy}M7jaL8U020bMAvbxDvZxpUePqJ%B~gpSmJnSE3;=S^jmnBCN8{vODSkH zR?5PXS6=()W&Xl5wZ$dN0R+a1jL+Hajx^+C{P;)jC~YQIwcG6_kEctlstMFdhr^ka z!x3$NG)9$vPyX!16MWpP%jFjPi<4c#_&J}?Pj%|2&!uEGE&)1;e(B)85RH`;`WWLq zojghRB=PK$aLqX9&%!;WZ2^liv2IBiVtPuWpPi)=l5@TUpmLNVR{a#cH-#f3Xo&#KJM=(5}GNpyL=%2O{K z*H>2R#BlxUm3(m%u+YQmz=bz;0k|e3mzON1KoL9vE(Mya%gx)09ohh{iOJNNVO76% zlO|~bH81KVD;dW2O%wUz$+PO*>`a37Gp=K@jB5Z+_WJ{t;5i%)6|2MY#bC@sYh!qI zr_-5TU2P~`U0(IspPx~#{Ppsv-J(OevCd9aT;^85I$bWwbk8wCcPBaoHV+9hCI=s= zMq}NHa3q@b2ZBw#6up?+bF)-6)B8}QSYmp*;l0kh_SO`Aqs?x&B0#DJPl!)|sgNcQ z*=#ob(uH>`ct;uR*71(TkQ_eRDx?*4)-YhiWWlIyD9~ZA%C3zpFE3>X z{8)Ey9^pTDm&MMAvuo;rtzg(ZTXtbW|sl5y0o}(k=kr9HpEJu zz+=Wo35MmV(7`AlEKdF@+NU0P>=7>1@o&GnUd04Z8`sh!Y^=%NM<1eKp@_ErcEFK= zA?s=~SaCs54fjWMhn_$2ixLcu1}0@Jv~yP_VJ2Z|r=YDluCoib=f$P3SVUiD8EEP& z#^MoJr!qjG(mRnmG>+dRbUuH3PGiB!t`0_M9amyU9weqEf0_Gm;-l27dAxWLAP%u* z&Vj9@tfa3A$U&lBuSqZ{5+-kyvl?KROo2)n43Aq(5>I_@ zw`52%g#MP)eDc|3OJH?!{#{)jaLzFiVN&)wge(EF*FO8-ZX0>I3J*s;R z*kY${7SqDvfm4H|SsJ-DWPxdHfVyF91PuiCmgAA}f{bkU@tamePv3*v?(1BOxEdSs z1C+>4efah;fR#D(cpD}_K3m9Y|GR!ef)w<_gU~NLb&5-Y?Cvr?uyD7QRN>=`1Y-VP zFJ)2ZcTgsrt?~f5SKl2y^{4k0o5MZ`Ky&b8Rq|zLzMhuQ)(m9{U|cWb+BGsfa9!m4 zAQ{u?`x}fk@&IC%iiM@=xm)@W8K^)wB!zu3LoQkr4IYBFI5)3Pe|0^x+YO7rN?Qlr z4X>o_){K}382ap@yq3IhP|{oKe)zDFqiq9fGZ_OHO^zPw%Yy0Iy|m%xk_4#gfkV9n zCh1$ol(rLHtT;~(QeuOWFXU&7>VMdVc_3Hk58r_!_2H`5dhEX>U}jSN^m@B<*0 zIc3RfavObA<6*` zWs3T~SD^$=t0axxl%SS>^~J~A-f5-OVDC?kG$SvH+Q43O0_R7ovDMnr@;cHEd&0tR zr1N&mqrklhVQ);o&#|kv$@)o7=J;0yj6pNO`KVQ&BqyF`D9L7rYQR$cgsBy+t0zK_t-+j3Dqj$Fe z+{o#%^G|Ri1UVpgi~iX%+-R&63E02=`nSYj%QPK8CHcr9UYCQ>2$zAKhM@ybCr@fi zON(3O5&qvP!((u_M%pD|i~^&R@&^1R$_3Cl9T6PlX1 Date: Thu, 28 Jul 2016 11:04:35 -0700 Subject: [PATCH 036/183] SL-321: fix viewer_manifest to not run strip on python files in the Linux build --- indra/newview/viewer_manifest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 3572b7dba8..502c054730 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1155,7 +1155,8 @@ class LinuxManifest(ViewerManifest): def strip_binaries(self): if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" - self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + # makes some small assumptions about our packaged dir structure + self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name \*.py \! -name SL_Launcher \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) class Linux_i686_Manifest(LinuxManifest): def construct(self): From 398fabf10c47c984c179e599af14fd27be4816cf Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 28 Jul 2016 11:38:13 -0700 Subject: [PATCH 037/183] SL-321: fix commithook issues in test files --- .../manager/tests/test_InstallerError.py | 40 ++++++++++-------- .../test_check_for_completed_download.py | 38 ++++++++++------- .../tests/test_convert_version_file_style.py | 42 +++++++++++-------- .../manager/tests/test_get_filename.py | 38 ++++++++++------- .../manager/tests/test_get_log_file_handle.py | 39 +++++++++-------- .../manager/tests/test_get_parent_path.py | 38 +++++++++-------- .../manager/tests/test_get_platform_key.py | 38 +++++++++-------- .../manager/tests/test_get_settings.py | 37 +++++++++------- .../manager/tests/test_make_VVM_UUID_hash.py | 37 +++++++++------- .../manager/tests/test_make_download_dir.py | 39 +++++++++-------- .../manager/tests/test_query_vvm.py | 36 +++++++++------- .../manager/tests/test_summary.py | 38 ++++++++++------- .../manager/tests/with_setup_args.py | 42 ++++++++++--------- 13 files changed, 284 insertions(+), 218 deletions(-) diff --git a/indra/viewer_components/manager/tests/test_InstallerError.py b/indra/viewer_components/manager/tests/test_InstallerError.py index d722208b7f..9139447932 100644 --- a/indra/viewer_components/manager/tests/test_InstallerError.py +++ b/indra/viewer_components/manager/tests/test_InstallerError.py @@ -1,27 +1,33 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - -""" +"""\ @file test_InstallerError.py @author coyot @date 2016-06-01 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ + from nose.tools import assert_equal import InstallerError diff --git a/indra/viewer_components/manager/tests/test_check_for_completed_download.py b/indra/viewer_components/manager/tests/test_check_for_completed_download.py index 388bc900e9..bcaaef4c3f 100644 --- a/indra/viewer_components/manager/tests/test_check_for_completed_download.py +++ b/indra/viewer_components/manager/tests/test_check_for_completed_download.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_check_for_completed_download.py @author coyot @date 2016-06-03 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -50,4 +56,4 @@ def test_completed_check_for_completed_download(tmpdir1,tmpdir2): def test_incomplete_check_for_completed_download(tmpdir1,tmpdir2): #should return False incomplete = not update_manager.check_for_completed_download(tmpdir2) - assert incomplete, "False positive, should not mark complete without a marker" \ No newline at end of file + assert incomplete, "False positive, should not mark complete without a marker" diff --git a/indra/viewer_components/manager/tests/test_convert_version_file_style.py b/indra/viewer_components/manager/tests/test_convert_version_file_style.py index d700f91b84..244c22c458 100644 --- a/indra/viewer_components/manager/tests/test_convert_version_file_style.py +++ b/indra/viewer_components/manager/tests/test_convert_version_file_style.py @@ -1,27 +1,33 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - -""" +"""\ @file test_convert_version_file_style.py @author coyot @date 2016-06-01 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ + from nose.tools import assert_equal import update_manager @@ -52,4 +58,4 @@ def test_none(): golden = None converted = update_manager.convert_version_file_style(version) - assert_equal(golden, converted) \ No newline at end of file + assert_equal(golden, converted) diff --git a/indra/viewer_components/manager/tests/test_get_filename.py b/indra/viewer_components/manager/tests/test_get_filename.py index 95771d75dc..efb6349374 100644 --- a/indra/viewer_components/manager/tests/test_get_filename.py +++ b/indra/viewer_components/manager/tests/test_get_filename.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_get_filename.py @author coyot @date 2016-06-30 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -57,4 +63,4 @@ def test_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): @with_setup_args.with_setup_args(get_filename_setup, get_filename_teardown) def test_missing_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): not_found = not apply_update.get_filename(tmpdir4) - assert not_found, "False positive, should not find an installable in an empty dir" \ No newline at end of file + assert not_found, "False positive, should not find an installable in an empty dir" diff --git a/indra/viewer_components/manager/tests/test_get_log_file_handle.py b/indra/viewer_components/manager/tests/test_get_log_file_handle.py index c5b3c89550..5ea821acf7 100644 --- a/indra/viewer_components/manager/tests/test_get_log_file_handle.py +++ b/indra/viewer_components/manager/tests/test_get_log_file_handle.py @@ -1,25 +1,30 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - """ @file test_get_log_file_handle.py @author coyot @date 2016-06-08 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -60,4 +65,4 @@ def test_missing_get_log_file_handle(tmpdir1,tmpdir2,log_file_path): if not os.path.exists(log_file_path): print "Failed to touch new log file" assert False - assert True \ No newline at end of file + assert True diff --git a/indra/viewer_components/manager/tests/test_get_parent_path.py b/indra/viewer_components/manager/tests/test_get_parent_path.py index 3cfd72310e..6e4b9dfaff 100644 --- a/indra/viewer_components/manager/tests/test_get_parent_path.py +++ b/indra/viewer_components/manager/tests/test_get_parent_path.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_get_parent_path.py @author coyot @date 2016-06-02 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -75,5 +81,3 @@ def test_get_parent_path(settings_dir): assert settings_dir, "test_get_parent_path failed to obtain parent path" assert_equal(settings_dir, got_settings_dir) - - \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_platform_key.py b/indra/viewer_components/manager/tests/test_get_platform_key.py index 37c570532c..eeaca1dff7 100644 --- a/indra/viewer_components/manager/tests/test_get_platform_key.py +++ b/indra/viewer_components/manager/tests/test_get_platform_key.py @@ -1,25 +1,30 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - """ @file test_get_platform_key.py @author coyot @date 2016-06-01 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import assert_equal @@ -37,4 +42,3 @@ def test_get_platform_key(): assert_equal(platform.system(),'Windows') else: assert_equal(key, None) - \ No newline at end of file diff --git a/indra/viewer_components/manager/tests/test_get_settings.py b/indra/viewer_components/manager/tests/test_get_settings.py index 46b779cbd5..7efcf62673 100644 --- a/indra/viewer_components/manager/tests/test_get_settings.py +++ b/indra/viewer_components/manager/tests/test_get_settings.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_get_settings.py @author coyot @date 2016-06-03 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -79,4 +85,3 @@ def test_get_settings(settings_dir): #test one key just to make sure it parsed assert_equal(got_settings['CurrentGrid']['Value'], 'util.agni.lindenlab.com') - diff --git a/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py b/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py index 513502a6ca..5939e5806a 100644 --- a/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py +++ b/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_make_VVM_UUID_hash.py @author coyot @date 2016-06-03 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -39,4 +45,3 @@ def test_make_VVM_UUID_hash(): #make_UUID_hash returned None assert UUID_hash, "make_UUID_hash failed to make a hash." - diff --git a/indra/viewer_components/manager/tests/test_make_download_dir.py b/indra/viewer_components/manager/tests/test_make_download_dir.py index 5198a6de05..e3f9cb83fe 100644 --- a/indra/viewer_components/manager/tests/test_make_download_dir.py +++ b/indra/viewer_components/manager/tests/test_make_download_dir.py @@ -1,25 +1,30 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ - """ @file test_make_download_dir.py @author coyot @date 2016-06-03 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -39,4 +44,4 @@ def test_make_download_dir(): print "make_download_dir raised an unexpected exception %s" % str(e) assert False - assert download_dir, "make_download_dir returned None for path %s and version %s" % (path, version) \ No newline at end of file + assert download_dir, "make_download_dir returned None for path %s and version %s" % (path, version) diff --git a/indra/viewer_components/manager/tests/test_query_vvm.py b/indra/viewer_components/manager/tests/test_query_vvm.py index 40a0f7b215..79c8ede480 100644 --- a/indra/viewer_components/manager/tests/test_query_vvm.py +++ b/indra/viewer_components/manager/tests/test_query_vvm.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_query_vvm.py @author coyot @date 2016-06-08 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * diff --git a/indra/viewer_components/manager/tests/test_summary.py b/indra/viewer_components/manager/tests/test_summary.py index b318012b54..f2f2af7347 100644 --- a/indra/viewer_components/manager/tests/test_summary.py +++ b/indra/viewer_components/manager/tests/test_summary.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_summary.py @author coyot @date 2016-06-02 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -36,4 +42,4 @@ def test_get_summary(): #we aren't testing the JSON library, one key pair is enough #so we will use the one pair that is actually a constant - assert_equal(summary_json['Type'],'viewer') \ No newline at end of file + assert_equal(summary_json['Type'],'viewer') diff --git a/indra/viewer_components/manager/tests/with_setup_args.py b/indra/viewer_components/manager/tests/with_setup_args.py index 38350ab8c4..94d33aa5fe 100644 --- a/indra/viewer_components/manager/tests/with_setup_args.py +++ b/indra/viewer_components/manager/tests/with_setup_args.py @@ -1,29 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ -# -# Taken from: https://gist.github.com/garyvdm/392ae20c673c7ee58d76 - """ @file with_setup_args.py @author garyvdm @date 2016-06-02 -""" +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ +""" def with_setup_args(setup, teardown=None): """Decorator to add setup and/or teardown methods to a test function:: @@ -63,4 +65,4 @@ def with_setup_args(setup, teardown=None): if hasattr(func, 'teardown'): test_wrapped.teardown = func.teardown() return test_wrapped - return decorate \ No newline at end of file + return decorate From 2afcff5b013c778f55af77f27932e10792986a05 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 28 Jul 2016 11:44:01 -0700 Subject: [PATCH 038/183] SL-321: one more commithook issue in test file --- .../manager/tests/test_silent_write.py | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/indra/viewer_components/manager/tests/test_silent_write.py b/indra/viewer_components/manager/tests/test_silent_write.py index a55665799f..ad286787e2 100644 --- a/indra/viewer_components/manager/tests/test_silent_write.py +++ b/indra/viewer_components/manager/tests/test_silent_write.py @@ -1,25 +1,31 @@ #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ """ @file test_silent_write.py @author coyot @date 2016-06-02 + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +$/LicenseInfo$ """ from nose.tools import * @@ -40,4 +46,4 @@ def test_silent_write_to_null(): update_manager.silent_write(None, "This is a test.") except Exception, e: print "Test failed due to: %s" % str(e) - assert False \ No newline at end of file + assert False From 7ed9c85a1a28e494adbd2cef85b186e45dba2dc2 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 15 Aug 2016 14:48:09 -0700 Subject: [PATCH 039/183] SL-323: fixes to Tkinter race condition, post --channel and --settings testing, contains debugging statements to be removed after all testing complete --- .../manager/InstallerUserMessage.py | 13 ++- indra/viewer_components/manager/SL_Launcher | 8 +- .../manager/download_update.py | 2 + .../manager/update_manager.py | 87 ++++++++++++------- 4 files changed, 77 insertions(+), 33 deletions(-) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py index f66af81d06..4f81aa9cd1 100644 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ b/indra/viewer_components/manager/InstallerUserMessage.py @@ -78,11 +78,17 @@ class InstallerUserMessage(tk.Tk): #defines what to do when window is closed self.protocol("WM_DELETE_WINDOW", self._delete_window) + + #callback id + self.id = -1 def _delete_window(self): #capture and discard all destroy events before the choice is set if not ((self.choice == None) or (self.choice == "")): try: + #initialized value. If we have an outstanding callback, kill it before killing ourselves + if self.id != -1: + self.after_cancel(self.id) self.destroy() except: #tk may try to destroy the same object twice @@ -217,8 +223,11 @@ class InstallerUserMessage(tk.Tk): def check_scheduler(self): if self.value < self.progress["maximum"]: - self.check_queue() - self.after(100, self.check_scheduler) + self.check_queue() + self.id = self.after(100, self.check_scheduler) + else: + #prevent a race condition between polling and the widget destruction + self.after_cancel(self.id) def check_queue(self): while self.queue.qsize(): diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 0403e01cec..8da8dc236b 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -31,7 +31,12 @@ import InstallerUserMessage #NOTA BENE: # For POSIX platforms, llsd.py will be imported from the same directory. # For Windows, llsd.py will be compiled into the executable by pyinstaller -from llbase import llsd +try: + from llbase import llsd +except: + #if Windows, this is expected, if not, we're dead + if os.name == 'nt': + pass import platform import subprocess import update_manager @@ -158,6 +163,7 @@ args = parser.parse_known_args(sys.argv) #args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname args_list_to_pass = args[1][1:] vmp_args = capture_vmp_args(args_list_to_pass) +print "vmp args: " + repr(vmp_args) #make a copy by value, not by reference command = list(args_list_to_pass) diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py index 23f784c6c1..a5e365fa37 100755 --- a/indra/viewer_components/manager/download_update.py +++ b/indra/viewer_components/manager/download_update.py @@ -45,6 +45,8 @@ def download_update(url = None, download_dir = None, size = None, progressbar = #chunk_size is in bytes, amount to download at once queue = Queue.Queue() + if not os.path.exists(download_dir): + os.makedirs(download_dir) #the url split provides the basename of the filename filename = os.path.join(download_dir, url.split('/')[-1]) req = requests.get(url, stream=True) diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index ff0f69a1b1..6e79e83605 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -28,9 +28,21 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA $/LicenseInfo$ """ -from llbase import llrest -from llbase.llrest import RESTError -from llbase import llsd +import os + +#NOTA BENE: +# For POSIX platforms, llbase will be imported from the same directory. +# For Windows, llbase will be compiled into the executable by pyinstaller +try: + from llbase import llrest + from llbase.llrest import RESTError + from llbase import llsd +except: + #if Windows, this is expected, if not, we're dead + if os.name == 'nt': + pass + +from copy import deepcopy from urlparse import urljoin import apply_update @@ -40,7 +52,6 @@ import fnmatch import hashlib import InstallerUserMessage import json -import os import platform import re import shutil @@ -58,13 +69,14 @@ def silent_write(log_file_handle, text): #prepend text for easy grepping log_file_handle.write("UPDATE MANAGER: " + text + "\n") -def after_frame(my_message, timeout = 10000): +def after_frame(message, timeout = 10000): #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds #note that this blocks the caller for the duration of timeout frame = InstallerUserMessage.InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") #this is done before basic_message so that we aren't blocked by mainloop() - frame.after(timeout, lambda: frame._delete_window) - frame.basic_message(message = my_message) + #frame.after(timeout, lambda: frame._delete_window) + frame.after(timeout, lambda: frame.destroy()) + frame.basic_message(message = message) def convert_version_file_style(version): #converts a version string a.b.c.d to a_b_c_d as used in downloaded filenames @@ -155,6 +167,10 @@ def get_settings(log_file_handle, parent_dir): print str(parent_dir) try: settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) + #this happens when the path to settings file happens on the command line + #we get a full path and don't need to munge it + if not os.path.exists(settings_file): + settings_file = parent_dir print "Settings file: " + str(settings_file) settings = llsd.parse((open(settings_file)).read()) except llsd.LLSDParseError as lpe: @@ -223,9 +239,15 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ channelname = summary_dict['Channel'] #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version version = summary_dict['Version'] - platform_version = platform.release() + #we need to use the dotted versions of the platform versions in order to be compatible with VVM rules and arithmetic + if platform_key == 'win': + platform_version = platform.win32_ver()[1] + elif platform_key == 'mac': + platform_version = platform.mac_ver()[0] + else: + platform_version = platform.release() #this will always return something usable, error handling in method - hashed_UUID = make_VVM_UUID_hash(platform_key) + UUID = str(make_VVM_UUID_hash(platform_key)) #note that this will not normally be in a settings.xml file and is only here for test builds. #for test builds, add this key to the ../user_settings/settings.xml """ @@ -251,16 +273,10 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ except KeyError: #normal case, no testing key test_ok = 'testok' - UUID = make_VVM_UUID_hash(platform_key) - print repr(channelname) - print repr(version) - print repr(platform_key) - print repr(platform_version) - print repr(test_ok) - print repr(UUID) #because urljoin can't be arsed to take multiple elements - #channelname is a list because although it can only be one word, it is a kind of argument and viewer args can take multiple keywords. - query_string = '/v1.0/' + channelname[0] + '/' + version + '/' + platform_key + '/' + platform_version + '/' + test_ok + '/' + UUID + #channelname is a list because although it is only one string, it is a kind of argument and viewer args can take multiple keywords. + query_string = urllib.quote('v1.0/' + channelname[0] + '/' + version + '/' + platform_key + '/' + platform_version + '/' + test_ok + '/' + UUID) + silent_write(log_file_handle, "About to query VVM: %s" % base_URI + query_string) VVMService = llrest.SimpleRESTService(name='VVM', baseurl=base_URI) try: result_data = VVMService.get(query_string) @@ -269,25 +285,28 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ return None return result_data -def download(url = None, version = None, download_dir = None, size = 0, background = False, chunk_size = 1024): +def download(url = None, version = None, download_dir = None, size = 0, background = False, chunk_size = None, log_file_handle = None): download_tries = 0 download_success = False + if not chunk_size: + chunk_size = 1024 #for background execution path_to_downloader = os.path.join(os.path.dirname(os.path.realpath(__file__)), "download_update.py") #three strikes and you're out while download_tries < 3 and not download_success: #323: Check for a partial update of the required update; in either event, display an alert that a download is required, initiate the download, and then install and launch if download_tries == 0: - after_frame(message = "Downloading new version " + version + " Please wait.") + after_frame(message = "Downloading new version " + version + " Please wait.", timeout = 5000) else: - after_frame(message = "Trying again to download new version " + version + " Please wait.") + after_frame(message = "Trying again to download new version " + version + " Please wait.", timeout = 5000) if not background: try: download_update.download_update(url = url, download_dir = download_dir, size = size, progressbar = True, chunk_size = chunk_size) download_success = True - except: + except Exception, e: download_tries += 1 silent_write(log_file_handle, "Failed to download new version " + version + ". Trying again.") + silent_write(log_file_handle, "Logging download exception: %s" % e.message) else: try: #Python does not have a facility to multithread a method, so we make the method a standalone @@ -308,6 +327,9 @@ def install(platform_key = None, download_dir = None, log_file_handle = None, in if downloaded != 'skip': after_frame(message = "New version downloaded. Installing now, please wait.") success = apply_update.apply_update(download_dir, platform_key, log_file_handle, in_place) + print download_dir + print success + version = download_dir.split('/')[-1] if success: silent_write(log_file_handle, "successfully updated to " + version) shutil.rmtree(download_dir) @@ -323,7 +345,7 @@ def download_and_install(downloaded = None, url = None, version = None, download #extracted to a method because we do it twice in update_manager() and this makes the logic clearer if not downloaded: #do the download, exit if we fail - if not download(url = url, version = version, download_dir = download_dir, size = size, chunk_size = chunk_size): + if not download(url = url, version = version, download_dir = download_dir, size = size, chunk_size = chunk_size, log_file_handle = log_file_handle): return (False, 'download', version) #do the install path_to_new_launcher = install(platform_key = platform_key, download_dir = download_dir, @@ -385,9 +407,10 @@ def update_manager(cli_overrides = None): return (False, 'setup', None) if cli_overrides is not None: - if '--settings' in cli_overrides.keys(): - if cli_overrides['--settings'] is not None: - settings = get_settings(log_file_handle, cli_overrides['--settings']) + print "update manager settings file: " + str(cli_overrides['settings']) + if 'settings' in cli_overrides.keys(): + if cli_overrides['settings'] is not None: + settings = get_settings(log_file_handle, cli_overrides['settings'][0]) else: settings = get_settings(log_file_handle, parent_dir) @@ -398,7 +421,7 @@ def update_manager(cli_overrides = None): #323: If a complete download of that update is found, check the update preference: #settings['UpdaterServiceSetting'] = 0 is manual install - """ssh://hg@bitbucket.org/lindenlab/viewer-release-maint-6585 + """ UpdaterServiceSetting Comment @@ -431,9 +454,11 @@ def update_manager(cli_overrides = None): #get channel and version try: summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) + #we send the override to the VVM, but retain the summary.json version for in_place computations + channel_override_summary = deepcopy(summary_dict) if cli_overrides is not None: if 'channel' in cli_overrides.keys(): - summary_dict['Channel'] = cli_overrides['channel'] + channel_override_summary['Channel'] = cli_overrides['channel'] except Exception, e: silent_write(log_file_handle, "Could not obtain channel and version, exiting.") silent_write(log_file_handle, e.message) @@ -447,7 +472,8 @@ def update_manager(cli_overrides = None): else: #tells query_vvm to use the default UpdaterServiceURL = None - result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict, UpdaterServiceURL) + result_data = query_vvm(log_file_handle, platform_key, settings, channel_override_summary, UpdaterServiceURL) + #nothing to do or error if not result_data: silent_write(log_file_handle, "No update found.") @@ -465,6 +491,7 @@ def update_manager(cli_overrides = None): #and launcher will launch the viewer in this install location. Otherwise, it will launch the Launcher from #the new location and kill itself. in_place = (summary_dict['Channel'] == result_data['channel']) + print "summary %s, result %s, in_place %s" % (summary_dict['Channel'], result_data['channel'], in_place) #determine if we've tried this download before downloaded = check_for_completed_download(download_dir) @@ -502,7 +529,7 @@ def update_manager(cli_overrides = None): return (True, None, None) else: #multithread a download - download(url = result_data['url'], version = result_data['version'], download_dir = download_dir, size = result_data['size'], background = True) + download(url = result_data['url'], version = result_data['version'], download_dir = download_dir, size = result_data['size'], background = True, log_file_handle = log_file_handle) print "Update manager exited with (%s, %s, %s)" % (True, 'background', True) return (True, 'background', True) From 5811b4721f8b2d848efeb37f2dff14f00bb7fc67 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 16 Aug 2016 08:40:39 -0700 Subject: [PATCH 040/183] SL-323: fixed update service redirect handling --- indra/viewer_components/manager/SL_Launcher | 2 -- .../manager/update_manager.py | 33 +++++++++---------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 8da8dc236b..1184a4c794 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -116,7 +116,6 @@ def capture_vmp_args(arg_list = None, cmd_line = None): param_args.append(vmp_queue.popleft()) #the parameter name is the key, the (possibly empty) list of args is the value cli_overrides[vmp_params[param]] = param_args - print "cli override param %s vmp_param %s args %s count %s" % (param, vmp_params[param], param_args, count) #to prevent KeyErrors on missing keys, set the remainder to None for key in vmp_params: @@ -163,7 +162,6 @@ args = parser.parse_known_args(sys.argv) #args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname args_list_to_pass = args[1][1:] vmp_args = capture_vmp_args(args_list_to_pass) -print "vmp args: " + repr(vmp_args) #make a copy by value, not by reference command = list(args_list_to_pass) diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index 6e79e83605..80b0f087ab 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -164,14 +164,12 @@ def check_for_completed_download(download_dir): def get_settings(log_file_handle, parent_dir): #return the settings file parsed into a dict - print str(parent_dir) try: settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) #this happens when the path to settings file happens on the command line #we get a full path and don't need to munge it if not os.path.exists(settings_file): settings_file = parent_dir - print "Settings file: " + str(settings_file) settings = llsd.parse((open(settings_file)).read()) except llsd.LLSDParseError as lpe: silent_write(log_file_handle, "Could not parse settings file %s" % lpe) @@ -230,14 +228,19 @@ def make_VVM_UUID_hash(platform_key): def query_vvm(log_file_handle = None, platform_key = None, settings = None, summary_dict = None, UpdaterServiceURL = None, UpdaterWillingToTest = None): result_data = None + baseURI = None #URI template /update/v1.1/channelname/version/platformkey/platformversion/willing-to-test/uniqueid #https://wiki.lindenlab.com/wiki/Viewer_Version_Manager_REST_API#Viewer_Update_Query + #note that the only two valid options are: + # # version-phx0.damballah.lindenlab.com + # # version-qa.secondlife-staging.com if UpdaterServiceURL: - baseURI = UpdaterServiceURL + #we can't really expect the users to put the protocol or base dir on, they will give us a host + base_URI = urljoin('https://' + UpdaterServiceURL[0], '/update/') else: base_URI = 'https://update.secondlife.com/update/' channelname = summary_dict['Channel'] - #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version + #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version in one string version = summary_dict['Version'] #we need to use the dotted versions of the platform versions in order to be compatible with VVM rules and arithmetic if platform_key == 'win': @@ -327,8 +330,6 @@ def install(platform_key = None, download_dir = None, log_file_handle = None, in if downloaded != 'skip': after_frame(message = "New version downloaded. Installing now, please wait.") success = apply_update.apply_update(download_dir, platform_key, log_file_handle, in_place) - print download_dir - print success version = download_dir.split('/')[-1] if success: silent_write(log_file_handle, "successfully updated to " + version) @@ -380,7 +381,6 @@ def update_manager(cli_overrides = None): parent_dir = get_parent_path(platform_key) log_file_handle = get_log_file_handle(parent_dir) settings = None - print "cli_overrides: " + str(cli_overrides) #check to see if user has install rights #get the owner of the install and the current user @@ -407,12 +407,11 @@ def update_manager(cli_overrides = None): return (False, 'setup', None) if cli_overrides is not None: - print "update manager settings file: " + str(cli_overrides['settings']) if 'settings' in cli_overrides.keys(): if cli_overrides['settings'] is not None: settings = get_settings(log_file_handle, cli_overrides['settings'][0]) - else: - settings = get_settings(log_file_handle, parent_dir) + else: + settings = get_settings(log_file_handle, parent_dir) if settings is None: silent_write(log_file_handle, "Failed to load viewer settings") @@ -433,9 +432,9 @@ def update_manager(cli_overrides = None): """ if cli_overrides is not None: - if '--set' in cli_overrides.keys(): - if 'UpdaterServiceSetting' in cli_overrides['--set'].keys(): - install_automatically = cli_overrides['--set']['UpdaterServiceSetting'] + if 'set' in cli_overrides.keys(): + if 'UpdaterServiceSetting' in cli_overrides['set'].keys(): + install_automatically = cli_overrides['set']['UpdaterServiceSetting'] else: try: install_automatically = settings['UpdaterServiceSetting']['Value'] @@ -445,9 +444,9 @@ def update_manager(cli_overrides = None): #use default chunk size if none is given if cli_overrides is not None: - if '--set' in cli_overrides.keys(): - if 'UpdaterMaximumBandwidth' in cli_overrides['--set'].keys(): - chunk_size = cli_overrides['--set']['UpdaterMaximumBandwidth'] + if 'set' in cli_overrides.keys(): + if 'UpdaterMaximumBandwidth' in cli_overrides['set'].keys(): + chunk_size = cli_overrides['set']['UpdaterMaximumBandwidth'] else: chunk_size = 1024 @@ -468,7 +467,7 @@ def update_manager(cli_overrides = None): #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. if cli_overrides is not None: if '--update-service' in cli_overrides.keys(): - UpdaterServiceURL = cli_overrides['--update-service'] + UpdaterServiceURL = cli_overrides['update-service'] else: #tells query_vvm to use the default UpdaterServiceURL = None From 4a124b8b9d709c3ae1856666bb29f28e90ab5d05 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 16 Aug 2016 09:17:07 -0700 Subject: [PATCH 041/183] SL-323: logging improvements --- indra/viewer_components/manager/SL_Launcher | 5 +++-- .../manager/update_manager.py | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index 1184a4c794..257543187c 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -48,7 +48,8 @@ def silent_write(log_file_handle, text): #oh and because it is best effort, it is also a holey_write ;) if (log_file_handle): #prepend text for easy grepping - log_file_handle.write("SL LAUNCHER: " + text + "\n") + timestamp = datetime.utcnow().strftime("%Y-%m-%D %H:%M:%S") + log_file_handle.write(timestamp + " LAUNCHER: " + text + "\n") def get_cmd_line(): platform_name = platform.system() @@ -136,7 +137,7 @@ def capture_vmp_args(arg_list = None, cmd_line = None): #main entry point #this and a few other update manager methods really should be refactored into a util lib parent_dir = update_manager.get_parent_path(update_manager.get_platform_key()) -log_file_handle = update_manager.get_log_file_handle(parent_dir) +log_file_handle = update_manager.get_log_file_handle(parent_dir, 'launcher.log') executable_name = "" if sys.platform.startswith('darwin'): diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index 80b0f087ab..647e7a77e6 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -43,6 +43,7 @@ except: pass from copy import deepcopy +from datetime import datetime from urlparse import urljoin import apply_update @@ -67,7 +68,8 @@ def silent_write(log_file_handle, text): #oh and because it is best effort, it is also a holey_write ;) if (log_file_handle): #prepend text for easy grepping - log_file_handle.write("UPDATE MANAGER: " + text + "\n") + timestamp = datetime.utcnow().strftime("%Y-%m-%D %H:%M:%S") + log_file_handle.write(timestamp + " UPDATE MANAGER: " + text + "\n") def after_frame(message, timeout = 10000): #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds @@ -176,10 +178,12 @@ def get_settings(log_file_handle, parent_dir): return None return settings -def get_log_file_handle(parent_dir): +def get_log_file_handle(parent_dir, filename = None): #return a write handle on the log file #plus log rotation and not dying on failure - log_file = os.path.join(parent_dir, 'update_manager.log') + if not filename: + return None + log_file = os.path.join(parent_dir, filename) old_file = log_file + '.old' #if someone's log files are present but not writable, they've screwed up their install. if os.access(log_file, os.W_OK): @@ -234,6 +238,7 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ #note that the only two valid options are: # # version-phx0.damballah.lindenlab.com # # version-qa.secondlife-staging.com + print "updater service host: " + repr(UpdaterServiceURL) if UpdaterServiceURL: #we can't really expect the users to put the protocol or base dir on, they will give us a host base_URI = urljoin('https://' + UpdaterServiceURL[0], '/update/') @@ -379,7 +384,7 @@ def update_manager(cli_overrides = None): #setup and getting initial parameters platform_key = get_platform_key() parent_dir = get_parent_path(platform_key) - log_file_handle = get_log_file_handle(parent_dir) + log_file_handle = get_log_file_handle(parent_dir, 'update_manager.log') settings = None #check to see if user has install rights @@ -466,10 +471,12 @@ def update_manager(cli_overrides = None): #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. if cli_overrides is not None: - if '--update-service' in cli_overrides.keys(): + if 'update-service' in cli_overrides.keys(): UpdaterServiceURL = cli_overrides['update-service'] + else: + #tells query_vvm to use the default + UpdaterServiceURL = None else: - #tells query_vvm to use the default UpdaterServiceURL = None result_data = query_vvm(log_file_handle, platform_key, settings, channel_override_summary, UpdaterServiceURL) From 3e55d8c77a21977f4023a82ebef3fed9879247bc Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 Aug 2016 08:20:12 -0700 Subject: [PATCH 042/183] SL-323: add icon support for macs, text flow in Tkinter windows --- indra/newview/viewer_manifest.py | 6 ++++ indra/newview/vmp_icons/SL_Logo.gif | Bin 0 -> 1322 bytes indra/newview/vmp_icons/SL_Logo.png | Bin 0 -> 1484 bytes indra/newview/vmp_icons/head-sl-logo.gif | Bin 0 -> 960 bytes indra/newview/vmp_icons/head-sl-logo.png | Bin 0 -> 2316 bytes .../manager/InstallerUserMessage.py | 26 ++++++++++++------ .../manager/update_manager.py | 2 ++ 7 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 indra/newview/vmp_icons/SL_Logo.gif create mode 100644 indra/newview/vmp_icons/SL_Logo.png create mode 100644 indra/newview/vmp_icons/head-sl-logo.gif create mode 100644 indra/newview/vmp_icons/head-sl-logo.png diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 502c054730..03a727468e 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -767,6 +767,12 @@ class Darwin_i386_Manifest(ViewerManifest): self.path("uk.lproj") self.path("zh-Hans.lproj") + #VMP icons + if self.prefix("vmp_icons"): + self.path("*.png") + self.path("*.gif") + self.end_prefix("vmp_icons") + def path_optional(src, dst): """ For a number of our self.path() calls, not only do we want diff --git a/indra/newview/vmp_icons/SL_Logo.gif b/indra/newview/vmp_icons/SL_Logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..c24d6b08cbda0d7d597932733eb04b9f805b858a GIT binary patch literal 1322 zcmb``X;YF3003ZAP*N%o?(WoFyAP$4Y1>%CRhX~jpJPtz&!V`lC zL_Cp1Acq8FsKJC#a!6aV;PE^Ol5AC z>O{6W??_Vq(X`@xjp1a5;gqhdAo+A*=INp%6~!5qCC9%k&8jZTsVX~OQ*y#so?lyW z%yjl--Pz;ymAQ>og$>mwnyT}gYfiP+6||WO&)1i=HR#Qa`PQaVOYIr+xf1KS3QM!0 zqq)@9Qr6k3cb-4vY_IIGmJYO+_jelm?G=NLszFQ5faC0tvt-OxH`H}*u&ZUbr*70< z=yEn(>@|%!PER@;M=!Kpyih&a)jrl=H#yKcIn?GFwz)>?=lZJ`20EuM+NVbyGh^2I z@#ZTdZI>tNmq%N#jW)Q)%-5#cmd7kh)92me_T@|F>k|(5WcTu{Wp&cI;%f1@dfane z*QYvH=Q}*p-K*1WYtzFki?$mx4$orW>gCS0S^N5&`PRJi=0fkrQrE4;q4lM{TW;6J z%GAy4gLhWPZm(Xt>zVlKhHG$u19x2|9^l_!K&I)y{XhdYdm8r zr)iVZGilXTG(9a{UjhR@!oB=qpJ80szy2EoLw^xkJxH0 zdVF#T)xZ4y1KR!bpf{>0o0dBVS>T19j~vA=X*Te#c?!&athD&UCG^~uV!VXWJ)+xGmNz5#?swxj zWTkcchrQbxFXm!<^*t}s>ed}U;ZQ-D=#^)CowxHMl-m^_I9aZ81^+_IvpLm4E2P_S zUVe`tCq(rb_q?tmI5MX0-2hDabhjHn+eg{6=<-10FPnq!?#Ehe>6F+j+sE42KnEwc?j>3p6-mm$N_h^e|ggre9mh(NhQcDjSW{Q+MB z_+;)08w4YKhYL*4Y}j!wwvRW$eeL9azi3Uuo@)BQ@K(+OcH*($UfIJIaKkA6#M>Gl oT;n{T)*#;&X~@0SZQEhNCTs_tv$B1S6lc(G%uq;BQV;+DAtM~tlEafn z0`YNrSG|`e2QscWOH%;2BL@KY?gPNiA%_eA2u1?HqB8(sasWWgH{FS9z}e+9V_0|5XmawIMwH&6V?4Dr(;aro~oV1ml90RWypBdiWVqdz~>*vo!M zs{8Ij@M^xqC;M@Kc8-xtf@~KSE($v#9DLq_H%72RFuG6<8>?SxRgMj*RD=g7Xe-&) za+hpO0LqG`<_XjF@ZY)B1fr3(SGGpO9Ji84^KE8giKfqDg-DSsP5RCO{W3-2$Cwe* zr4i5qvw0NO-dhQ12x{G^9x?9R-p}t)?eX7zEc=caKI8+JEAP=OwV$y{_;ajH$>C{BO`?2T#}{SH;Q4BtxZ5&d2su1rBIu#AYw__ZjqZcJ)ni~X8Lag3 zt9keI{2lSbFCTGNTC8a#0(?GQjjaE`uWO@BC42M)^p1b+$ zx3`cF9=OYY4P@JTzv*3_dY8XFWqPMDG@q+*q=UF*e7&XyY5jcHJ8tSADj>2|?NmRm zW8J>QDyKjcOqK8wW%j;vs*7YBm{BnLErX8yPQ^BeI3e9El`PQAgEZZOVZ2BhC}}o* zGY|x~srs5~Kx_BRIgARCJcYGJWLYZ?6I};SV+Fu8IoQ)w=}Fy6qMq}YDtI=t)+}^yoyH-Ce?)so|I%55{`n+KcK7cJPokk}B@GvGdyVnh+wirAWId?H;2ogp4 zwBGkfwO0God -0w}F!!fWQWT^QmKbqA&CE4k21yDK|OGJ=6^W;Et!8mn`5{nE*# zfmwmzCtaJf=k&3k8L+Nj^z`0qu}7;t##0#q0`emZ?|vgu^Ye6op4xI8W9@YA^OhUoo2%eaxfhj1r*@fzm*AeGgx~UQKwrR6t=; zW)BUj3~*gdC#-u+6)~0S!^EU7dF%xXw;UN5xjqKlG3wnsR_}ejTU;ei^IB_bXKyda z>fut4DI%^+D3C^zO`O|GZ1xySJw3a@XitF?9o)o4f-v?!>9$$77W%{lV=b_*jnNjn zdz2uv+XGSl@#~QdC=_w}^W$r4^A**!s*6AO`hAf|EnL}Tk?o6G?+E#D`4zV|HN)j` z!8jB8jniQI_R`+gGILg=n`m6zjJLCm+UnqXvobnRL+@d;l0tJsYcypeBmQ=YC+eNQW1MURMcaKyecMGdbw8--^|)=()N}%t>z8 zHPonH)x|t5dR5=mckTJl>E-q`9U5ieSw^S0Ua4h~RYmLB2s)kDBqcd{6AFR2sPIcU zH`d{cCrhOGf;xfQ%0xx2+0@O!g$vn?HK-D8V-B?+ z+3I*yQ5r#5gRpJbTY?k{y7gdmZqrnH{P6=&}?#An6zY(?(Btv zzRNlIxRqtTSNe&E-FnYILwEh}t>x9xvQ74l^&OEy70pe_t+9~|lNq9>mI_woW%dQn z7LxR4WLe_Ez{JJF!{x-lymT!i8=Lbw4(7Exmak=6!s094IxqilbfGtkz^ScF{7wQ} zc{~_+PunxF+FxVf5n$z5`{0_lc#lM1VP1Ew%gM(K92YL%-S2dA8Mi$v-`cx;oDb_{ zP8?5RTI}3=Pr>Jr-@FMGTzX%n%ijxa&%R`!Rb0j^!`Q!RlFN@rY>CT!gJ+ni6gfmT zv$Cr-ZDxOX%_Zw^T?jXOBg4M~j4LgKJk^gpP;+ky(JJmpiQe9GzU5!XasB5E?H{Fh zA{_)y?p&O3zb4R%?_?vpkFaK^L!wild)2*N3lH#}JQcQ1!!dNX3ez21!AVlLO4gmc zo6V)5<1j%&e`)3vCGT~rJBwKOn@m#lcD|Ijx#iX~-MM1htW5d;XNh&@hZ9G;Wz-ly_ka2R-q?vvzS8{Zea-1WZwhX9PqdF& za8ho;p9y{0CY%-z>hImXHd%kemZVus5(ob&xhm!_IDSyciG}$g|83tJ@eR9X9-3ow z^h4u)ez%R!TdKG1eX*$6K7!$q*vpd-uXk#8u`Os__4dXi{*u2Li%Ol>Bqs}7Tr0ZW z`>At@r>IK^J7?1$&y18-R=>%qLi1W4IEsk$e2w&<>T7gyVyaeTaH?|!=OI=hmrrei zVmp2=W8x6W%2-%DNi$7%nPGv(BIgMuv1}3?>5gnyGruS0hJMFR8grSf2ENS+i6gEatM+{p6) literal 0 HcmV?d00001 diff --git a/indra/newview/vmp_icons/head-sl-logo.png b/indra/newview/vmp_icons/head-sl-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5c214e96d1cc22698384815cd696cb780fd0e16a GIT binary patch literal 2316 zcmV+n3G?=eP)34P@5 zhYzcJkXkSntdjx}**Ie9Cq!UZYV{_2O_L#cgMQBDJwz>lH5;U3;z_+$<3CmNWbpF4 zCtoh_LAq9){0A((4vnnhC)ZHL1iEI?Uu@F_CKIcNs2|2Hwt9H~GXt`DqNvaKKMJ~V zkHS0>{yy}M7jaL8U020bMAvbxDvZxpUePqJ%B~gpSmJnSE3;=S^jmnBCN8{vODSkH zR?5PXS6=()W&Xl5wZ$dN0R+a1jL+Hajx^+C{P;)jC~YQIwcG6_kEctlstMFdhr^ka z!x3$NG)9$vPyX!16MWpP%jFjPi<4c#_&J}?Pj%|2&!uEGE&)1;e(B)85RH`;`WWLq zojghRB=PK$aLqX9&%!;WZ2^liv2IBiVtPuWpPi)=l5@TUpmLNVR{a#cH-#f3Xo&#KJM=(5}GNpyL=%2O{K z*H>2R#BlxUm3(m%u+YQmz=bz;0k|e3mzON1KoL9vE(Mya%gx)09ohh{iOJNNVO76% zlO|~bH81KVD;dW2O%wUz$+PO*>`a37Gp=K@jB5Z+_WJ{t;5i%)6|2MY#bC@sYh!qI zr_-5TU2P~`U0(IspPx~#{Ppsv-J(OevCd9aT;^85I$bWwbk8wCcPBaoHV+9hCI=s= zMq}NHa3q@b2ZBw#6up?+bF)-6)B8}QSYmp*;l0kh_SO`Aqs?x&B0#DJPl!)|sgNcQ z*=#ob(uH>`ct;uR*71(TkQ_eRDx?*4)-YhiWWlIyD9~ZA%C3zpFE3>X z{8)Ey9^pTDm&MMAvuo;rtzg(ZTXtbW|sl5y0o}(k=kr9HpEJu zz+=Wo35MmV(7`AlEKdF@+NU0P>=7>1@o&GnUd04Z8`sh!Y^=%NM<1eKp@_ErcEFK= zA?s=~SaCs54fjWMhn_$2ixLcu1}0@Jv~yP_VJ2Z|r=YDluCoib=f$P3SVUiD8EEP& z#^MoJr!qjG(mRnmG>+dRbUuH3PGiB!t`0_M9amyU9weqEf0_Gm;-l27dAxWLAP%u* z&Vj9@tfa3A$U&lBuSqZ{5+-kyvl?KROo2)n43Aq(5>I_@ zw`52%g#MP)eDc|3OJH?!{#{)jaLzFiVN&)wge(EF*FO8-ZX0>I3J*s;R z*kY${7SqDvfm4H|SsJ-DWPxdHfVyF91PuiCmgAA}f{bkU@tamePv3*v?(1BOxEdSs z1C+>4efah;fR#D(cpD}_K3m9Y|GR!ef)w<_gU~NLb&5-Y?Cvr?uyD7QRN>=`1Y-VP zFJ)2ZcTgsrt?~f5SKl2y^{4k0o5MZ`Ky&b8Rq|zLzMhuQ)(m9{U|cWb+BGsfa9!m4 zAQ{u?`x}fk@&IC%iiM@=xm)@W8K^)wB!zu3LoQkr4IYBFI5)3Pe|0^x+YO7rN?Qlr z4X>o_){K}382ap@yq3IhP|{oKe)zDFqiq9fGZ_OHO^zPw%Yy0Iy|m%xk_4#gfkV9n zCh1$ol(rLHtT;~(QeuOWFXU&7>VMdVc_3Hk58r_!_2H`5dhEX>U}jSN^m@B<*0 zIc3RfavObA<6*` zWs3T~SD^$=t0axxl%SS>^~J~A-f5-OVDC?kG$SvH+Q43O0_R7ovDMnr@;cHEd&0tR zr1N&mqrklhVQ);o&#|kv$@)o7=J;0yj6pNO`KVQ&BqyF`D9L7rYQR$cgsBy+t0zK_t-+j3Dqj$Fe z+{o#%^G|Ri1UVpgi~iX%+-R&63E02=`nSYj%QPK8CHcr9UYCQ>2$zAKhM@ybCr@fi zON(3O5&qvP!((u_M%pD|i~^&R@&^1R$_3Cl9T6PlX1 Date: Wed, 17 Aug 2016 08:50:43 -0700 Subject: [PATCH 043/183] SL-323: remove vmp icons from viewer_components subtree --- .../viewer_components/manager/icons/SL_Logo.gif | Bin 1322 -> 0 bytes .../viewer_components/manager/icons/SL_Logo.png | Bin 1484 -> 0 bytes .../manager/icons/head-sl-logo.gif | Bin 960 -> 0 bytes .../manager/icons/head-sl-logo.png | Bin 2316 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 indra/viewer_components/manager/icons/SL_Logo.gif delete mode 100644 indra/viewer_components/manager/icons/SL_Logo.png delete mode 100644 indra/viewer_components/manager/icons/head-sl-logo.gif delete mode 100644 indra/viewer_components/manager/icons/head-sl-logo.png diff --git a/indra/viewer_components/manager/icons/SL_Logo.gif b/indra/viewer_components/manager/icons/SL_Logo.gif deleted file mode 100644 index c24d6b08cbda0d7d597932733eb04b9f805b858a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1322 zcmb``X;YF3003ZAP*N%o?(WoFyAP$4Y1>%CRhX~jpJPtz&!V`lC zL_Cp1Acq8FsKJC#a!6aV;PE^Ol5AC z>O{6W??_Vq(X`@xjp1a5;gqhdAo+A*=INp%6~!5qCC9%k&8jZTsVX~OQ*y#so?lyW z%yjl--Pz;ymAQ>og$>mwnyT}gYfiP+6||WO&)1i=HR#Qa`PQaVOYIr+xf1KS3QM!0 zqq)@9Qr6k3cb-4vY_IIGmJYO+_jelm?G=NLszFQ5faC0tvt-OxH`H}*u&ZUbr*70< z=yEn(>@|%!PER@;M=!Kpyih&a)jrl=H#yKcIn?GFwz)>?=lZJ`20EuM+NVbyGh^2I z@#ZTdZI>tNmq%N#jW)Q)%-5#cmd7kh)92me_T@|F>k|(5WcTu{Wp&cI;%f1@dfane z*QYvH=Q}*p-K*1WYtzFki?$mx4$orW>gCS0S^N5&`PRJi=0fkrQrE4;q4lM{TW;6J z%GAy4gLhWPZm(Xt>zVlKhHG$u19x2|9^l_!K&I)y{XhdYdm8r zr)iVZGilXTG(9a{UjhR@!oB=qpJ80szy2EoLw^xkJxH0 zdVF#T)xZ4y1KR!bpf{>0o0dBVS>T19j~vA=X*Te#c?!&athD&UCG^~uV!VXWJ)+xGmNz5#?swxj zWTkcchrQbxFXm!<^*t}s>ed}U;ZQ-D=#^)CowxHMl-m^_I9aZ81^+_IvpLm4E2P_S zUVe`tCq(rb_q?tmI5MX0-2hDabhjHn+eg{6=<-10FPnq!?#Ehe>6F+j+sE42KnEwc?j>3p6-mm$N_h^e|ggre9mh(NhQcDjSW{Q+MB z_+;)08w4YKhYL*4Y}j!wwvRW$eeL9azi3Uuo@)BQ@K(+OcH*($UfIJIaKkA6#M>Gl oT;n{T)*#;&X~@0SZQEhNCTs_tv$B1S6lc(G%uq;BQV;+DAtM~tlEafn z0`YNrSG|`e2QscWOH%;2BL@KY?gPNiA%_eA2u1?HqB8(sasWWgH{FS9z}e+9V_0|5XmawIMwH&6V?4Dr(;aro~oV1ml90RWypBdiWVqdz~>*vo!M zs{8Ij@M^xqC;M@Kc8-xtf@~KSE($v#9DLq_H%72RFuG6<8>?SxRgMj*RD=g7Xe-&) za+hpO0LqG`<_XjF@ZY)B1fr3(SGGpO9Ji84^KE8giKfqDg-DSsP5RCO{W3-2$Cwe* zr4i5qvw0NO-dhQ12x{G^9x?9R-p}t)?eX7zEc=caKI8+JEAP=OwV$y{_;ajH$>C{BO`?2T#}{SH;Q4BtxZ5&d2su1rBIu#AYw__ZjqZcJ)ni~X8Lag3 zt9keI{2lSbFCTGNTC8a#0(?GQjjaE`uWO@BC42M)^p1b+$ zx3`cF9=OYY4P@JTzv*3_dY8XFWqPMDG@q+*q=UF*e7&XyY5jcHJ8tSADj>2|?NmRm zW8J>QDyKjcOqK8wW%j;vs*7YBm{BnLErX8yPQ^BeI3e9El`PQAgEZZOVZ2BhC}}o* zGY|x~srs5~Kx_BRIgARCJcYGJWLYZ?6I};SV+Fu8IoQ)w=}Fy6qMq}YDtI=t)+}^yoyH-Ce?)so|I%55{`n+KcK7cJPokk}B@GvGdyVnh+wirAWId?H;2ogp4 zwBGkfwO0God -0w}F!!fWQWT^QmKbqA&CE4k21yDK|OGJ=6^W;Et!8mn`5{nE*# zfmwmzCtaJf=k&3k8L+Nj^z`0qu}7;t##0#q0`emZ?|vgu^Ye6op4xI8W9@YA^OhUoo2%eaxfhj1r*@fzm*AeGgx~UQKwrR6t=; zW)BUj3~*gdC#-u+6)~0S!^EU7dF%xXw;UN5xjqKlG3wnsR_}ejTU;ei^IB_bXKyda z>fut4DI%^+D3C^zO`O|GZ1xySJw3a@XitF?9o)o4f-v?!>9$$77W%{lV=b_*jnNjn zdz2uv+XGSl@#~QdC=_w}^W$r4^A**!s*6AO`hAf|EnL}Tk?o6G?+E#D`4zV|HN)j` z!8jB8jniQI_R`+gGILg=n`m6zjJLCm+UnqXvobnRL+@d;l0tJsYcypeBmQ=YC+eNQW1MURMcaKyecMGdbw8--^|)=()N}%t>z8 zHPonH)x|t5dR5=mckTJl>E-q`9U5ieSw^S0Ua4h~RYmLB2s)kDBqcd{6AFR2sPIcU zH`d{cCrhOGf;xfQ%0xx2+0@O!g$vn?HK-D8V-B?+ z+3I*yQ5r#5gRpJbTY?k{y7gdmZqrnH{P6=&}?#An6zY(?(Btv zzRNlIxRqtTSNe&E-FnYILwEh}t>x9xvQ74l^&OEy70pe_t+9~|lNq9>mI_woW%dQn z7LxR4WLe_Ez{JJF!{x-lymT!i8=Lbw4(7Exmak=6!s094IxqilbfGtkz^ScF{7wQ} zc{~_+PunxF+FxVf5n$z5`{0_lc#lM1VP1Ew%gM(K92YL%-S2dA8Mi$v-`cx;oDb_{ zP8?5RTI}3=Pr>Jr-@FMGTzX%n%ijxa&%R`!Rb0j^!`Q!RlFN@rY>CT!gJ+ni6gfmT zv$Cr-ZDxOX%_Zw^T?jXOBg4M~j4LgKJk^gpP;+ky(JJmpiQe9GzU5!XasB5E?H{Fh zA{_)y?p&O3zb4R%?_?vpkFaK^L!wild)2*N3lH#}JQcQ1!!dNX3ez21!AVlLO4gmc zo6V)5<1j%&e`)3vCGT~rJBwKOn@m#lcD|Ijx#iX~-MM1htW5d;XNh&@hZ9G;Wz-ly_ka2R-q?vvzS8{Zea-1WZwhX9PqdF& za8ho;p9y{0CY%-z>hImXHd%kemZVus5(ob&xhm!_IDSyciG}$g|83tJ@eR9X9-3ow z^h4u)ez%R!TdKG1eX*$6K7!$q*vpd-uXk#8u`Os__4dXi{*u2Li%Ol>Bqs}7Tr0ZW z`>At@r>IK^J7?1$&y18-R=>%qLi1W4IEsk$e2w&<>T7gyVyaeTaH?|!=OI=hmrrei zVmp2=W8x6W%2-%DNi$7%nPGv(BIgMuv1}3?>5gnyGruS0hJMFR8grSf2ENS+i6gEatM+{p6) diff --git a/indra/viewer_components/manager/icons/head-sl-logo.png b/indra/viewer_components/manager/icons/head-sl-logo.png deleted file mode 100644 index 5c214e96d1cc22698384815cd696cb780fd0e16a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2316 zcmV+n3G?=eP)34P@5 zhYzcJkXkSntdjx}**Ie9Cq!UZYV{_2O_L#cgMQBDJwz>lH5;U3;z_+$<3CmNWbpF4 zCtoh_LAq9){0A((4vnnhC)ZHL1iEI?Uu@F_CKIcNs2|2Hwt9H~GXt`DqNvaKKMJ~V zkHS0>{yy}M7jaL8U020bMAvbxDvZxpUePqJ%B~gpSmJnSE3;=S^jmnBCN8{vODSkH zR?5PXS6=()W&Xl5wZ$dN0R+a1jL+Hajx^+C{P;)jC~YQIwcG6_kEctlstMFdhr^ka z!x3$NG)9$vPyX!16MWpP%jFjPi<4c#_&J}?Pj%|2&!uEGE&)1;e(B)85RH`;`WWLq zojghRB=PK$aLqX9&%!;WZ2^liv2IBiVtPuWpPi)=l5@TUpmLNVR{a#cH-#f3Xo&#KJM=(5}GNpyL=%2O{K z*H>2R#BlxUm3(m%u+YQmz=bz;0k|e3mzON1KoL9vE(Mya%gx)09ohh{iOJNNVO76% zlO|~bH81KVD;dW2O%wUz$+PO*>`a37Gp=K@jB5Z+_WJ{t;5i%)6|2MY#bC@sYh!qI zr_-5TU2P~`U0(IspPx~#{Ppsv-J(OevCd9aT;^85I$bWwbk8wCcPBaoHV+9hCI=s= zMq}NHa3q@b2ZBw#6up?+bF)-6)B8}QSYmp*;l0kh_SO`Aqs?x&B0#DJPl!)|sgNcQ z*=#ob(uH>`ct;uR*71(TkQ_eRDx?*4)-YhiWWlIyD9~ZA%C3zpFE3>X z{8)Ey9^pTDm&MMAvuo;rtzg(ZTXtbW|sl5y0o}(k=kr9HpEJu zz+=Wo35MmV(7`AlEKdF@+NU0P>=7>1@o&GnUd04Z8`sh!Y^=%NM<1eKp@_ErcEFK= zA?s=~SaCs54fjWMhn_$2ixLcu1}0@Jv~yP_VJ2Z|r=YDluCoib=f$P3SVUiD8EEP& z#^MoJr!qjG(mRnmG>+dRbUuH3PGiB!t`0_M9amyU9weqEf0_Gm;-l27dAxWLAP%u* z&Vj9@tfa3A$U&lBuSqZ{5+-kyvl?KROo2)n43Aq(5>I_@ zw`52%g#MP)eDc|3OJH?!{#{)jaLzFiVN&)wge(EF*FO8-ZX0>I3J*s;R z*kY${7SqDvfm4H|SsJ-DWPxdHfVyF91PuiCmgAA}f{bkU@tamePv3*v?(1BOxEdSs z1C+>4efah;fR#D(cpD}_K3m9Y|GR!ef)w<_gU~NLb&5-Y?Cvr?uyD7QRN>=`1Y-VP zFJ)2ZcTgsrt?~f5SKl2y^{4k0o5MZ`Ky&b8Rq|zLzMhuQ)(m9{U|cWb+BGsfa9!m4 zAQ{u?`x}fk@&IC%iiM@=xm)@W8K^)wB!zu3LoQkr4IYBFI5)3Pe|0^x+YO7rN?Qlr z4X>o_){K}382ap@yq3IhP|{oKe)zDFqiq9fGZ_OHO^zPw%Yy0Iy|m%xk_4#gfkV9n zCh1$ol(rLHtT;~(QeuOWFXU&7>VMdVc_3Hk58r_!_2H`5dhEX>U}jSN^m@B<*0 zIc3RfavObA<6*` zWs3T~SD^$=t0axxl%SS>^~J~A-f5-OVDC?kG$SvH+Q43O0_R7ovDMnr@;cHEd&0tR zr1N&mqrklhVQ);o&#|kv$@)o7=J;0yj6pNO`KVQ&BqyF`D9L7rYQR$cgsBy+t0zK_t-+j3Dqj$Fe z+{o#%^G|Ri1UVpgi~iX%+-R&63E02=`nSYj%QPK8CHcr9UYCQ>2$zAKhM@ybCr@fi zON(3O5&qvP!((u_M%pD|i~^&R@&^1R$_3Cl9T6PlX1 Date: Thu, 18 Aug 2016 13:05:30 -0700 Subject: [PATCH 044/183] SL-323: first pass at ripping out old updater --- indra/CMakeLists.txt | 2 +- indra/newview/CMakeLists.txt | 2 - indra/newview/llappviewer.cpp | 373 --------- indra/newview/llappviewer.h | 19 - indra/newview/llappviewerwin32.cpp | 11 - indra/newview/llfloaterabout.cpp | 83 -- indra/newview/lllogininstance.cpp | 568 +------------ indra/newview/lllogininstance.h | 13 - indra/newview/llstartup.cpp | 1 - indra/newview/llviewercontrol.cpp | 15 - indra/newview/llviewermenu.cpp | 17 - indra/newview/tests/lllogininstance_test.cpp | 137 ---- indra/viewer_components/CMakeLists.txt | 1 - .../viewer_components/updater/CMakeLists.txt | 106 --- .../updater/llupdatechecker.cpp | 187 ----- .../updater/llupdatechecker.h | 119 --- .../updater/llupdatedownloader.cpp | 604 -------------- .../updater/llupdatedownloader.h | 96 --- .../updater/llupdateinstaller.cpp | 98 --- .../updater/llupdateinstaller.h | 58 -- .../updater/llupdaterservice.cpp | 760 ------------------ .../updater/llupdaterservice.h | 112 --- .../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 ----- .../scripts/windows/update_install.bat | 3 - .../updater/tests/llupdaterservice_test.cpp | 220 ----- 28 files changed, 4 insertions(+), 4432 deletions(-) delete mode 100644 indra/viewer_components/updater/CMakeLists.txt delete mode 100644 indra/viewer_components/updater/llupdatechecker.cpp delete mode 100644 indra/viewer_components/updater/llupdatechecker.h delete mode 100644 indra/viewer_components/updater/llupdatedownloader.cpp delete mode 100644 indra/viewer_components/updater/llupdatedownloader.h delete mode 100644 indra/viewer_components/updater/llupdateinstaller.cpp delete mode 100644 indra/viewer_components/updater/llupdateinstaller.h delete mode 100644 indra/viewer_components/updater/llupdaterservice.cpp delete mode 100644 indra/viewer_components/updater/llupdaterservice.h 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 delete mode 100644 indra/viewer_components/updater/tests/llupdaterservice_test.cpp diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 1afcb118bc..84c2a14c6e 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -63,7 +63,7 @@ if (LINUX) include(LLAppearanceUtility) add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) endif (INSTALL_PROPRIETARY) - add_dependencies(viewer linux-crash-logger-strip-target linux-updater) + add_dependencies(viewer linux-crash-logger-strip-target) elseif (DARWIN) add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) add_dependencies(viewer mac-crash-logger) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 31e3711569..999165528a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -83,7 +83,6 @@ include_directories( ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLLOGIN_INCLUDE_DIRS} - ${UPDATER_INCLUDE_DIRS} ${LIBS_PREBUILT_DIR}/include/collada ${LIBS_PREBUILD_DIR}/include/hunspell ${OPENAL_LIB_INCLUDE_DIRS} @@ -1959,7 +1958,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${PNG_PRELOAD_ARCHIVES} ${ZLIB_PRELOAD_ARCHIVES} ${URIPARSER_PRELOAD_ARCHIVES} - ${UPDATER_LIBRARIES} ${GOOGLE_PERFTOOLS_LIBRARIES} ${LLAUDIO_LIBRARIES} ${LLCHARACTER_LIBRARIES} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6bc1f67e32..cf783b9f2f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -93,7 +93,6 @@ #include "llvocache.h" #include "llvopartgroup.h" #include "llweb.h" -#include "llupdaterservice.h" #include "llfloatertexturefetchdebugger.h" #include "llspellcheck.h" #include "llscenemonitor.h" @@ -263,7 +262,6 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance); // viewer.cpp - these are only used in viewer, should be easily moved. #if LL_DARWIN -const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer"; extern void init_apple_menu(const char* product); #endif // LL_DARWIN @@ -289,8 +287,6 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown) # define LL_PLATFORM_KEY "mac" #elif LL_LINUX # define LL_PLATFORM_KEY "lnx" -#elif LL_SOLARIS -# define LL_PLATFORM_KEY "sol" #else # error "Unknown Platform" #endif @@ -467,8 +463,6 @@ struct SettingsFiles : public LLInitParam::Block static std::string gWindowTitle; -LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; - //---------------------------------------------------------------------------- // Metrics logging control constants //---------------------------------------------------------------------------- @@ -695,7 +689,6 @@ LLAppViewer::LLAppViewer() mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", FALSE)), mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), mFastTimerLogThread(NULL), - mUpdater(new LLUpdaterService()), mSettingsLocationList(NULL) { if(NULL != sInstance) @@ -724,7 +717,6 @@ LLAppViewer::LLAppViewer() // OK to write stuff to logs now, we've now crash reported if necessary // - LLLoginInstance::instance().setUpdaterService(mUpdater.get()); LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString()); } @@ -732,8 +724,6 @@ LLAppViewer::~LLAppViewer() { delete mSettingsLocationList; LLViewerEventRecorder::instance().~LLViewerEventRecorder(); - - LLLoginInstance::instance().setUpdaterService(0); destroyMainloopTimeout(); @@ -881,14 +871,6 @@ bool LLAppViewer::init() writeSystemInfo(); - // Initialize updater service (now that we have an io pump) - initUpdater(); - if(isQuitting()) - { - // Early out here because updater set the quitting flag. - return true; - } - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -2888,224 +2870,6 @@ void LLAppViewer::initStrings() } } -namespace { - // *TODO - decide if there's a better place for these functions. - // do we need a file llupdaterui.cpp or something? -brad - - void apply_update_callback(LLSD const & notification, LLSD const & response) - { - LL_DEBUGS() << "LLUpdate user response: " << response << LL_ENDL; - if(response["OK_okcancelbuttons"].asBoolean()) - { - LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL; - static const bool install_if_ready = true; - // *HACK - this lets us launch the installer immediately for now - LLUpdaterService().startChecking(install_if_ready); - } - } - - void apply_update_ok_callback(LLSD const & notification, LLSD const & response) - { - LL_INFOS() << "LLUpdate restarting viewer" << LL_ENDL; - static const bool install_if_ready = true; - // *HACK - this lets us launch the installer immediately for now - LLUpdaterService().startChecking(install_if_ready); - } - - void on_update_downloaded(LLSD const & data) - { - std::string notification_name; - void (*apply_callback)(LLSD const &, LLSD const &) = NULL; - - /* Build up the notification name... - * it can be any of these, which are included here for the sake of grep: - * RequiredUpdateDownloadedDialog - * RequiredUpdateDownloadedVerboseDialog - * OtherChannelRequiredUpdateDownloadedDialog - * OtherChannelRequiredUpdateDownloadedVerbose - * DownloadBackgroundTip - * DownloadBackgroundDialog - * OtherChannelDownloadBackgroundTip - * OtherChannelDownloadBackgroundDialog - */ - { - LL_DEBUGS("UpdaterService") << "data = "; - std::ostringstream data_dump; - LLSDSerialize::toNotation(data, data_dump); - LL_CONT << data_dump.str() << LL_ENDL; - } - if(data["channel"].asString() != LLVersionInfo::getChannel()) - { - notification_name.append("OtherChannel"); - } - if(data["required"].asBoolean()) - { - if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT) - { - // The user never saw the progress bar. - apply_callback = &apply_update_ok_callback; - notification_name += "RequiredUpdateDownloadedVerboseDialog"; - } - else if(LLStartUp::getStartupState() < STATE_WORLD_INIT) - { - // The user is logging in but blocked. - apply_callback = &apply_update_ok_callback; - notification_name += "RequiredUpdateDownloadedDialog"; - } - else - { - // The user is already logged in; treat like an optional update. - apply_callback = &apply_update_callback; - notification_name += "DownloadBackgroundTip"; - } - } - else - { - apply_callback = &apply_update_callback; - if(LLStartUp::getStartupState() < STATE_STARTED) - { - // CHOP-262 we need to use a different notification - // method prior to login. - notification_name += "DownloadBackgroundDialog"; - } - else - { - notification_name += "DownloadBackgroundTip"; - } - } - - LLSD substitutions; - substitutions["VERSION"] = data["version"]; - std::string new_channel = data["channel"].asString(); - substitutions["NEW_CHANNEL"] = new_channel; - std::string info_url = data["info_url"].asString(); - if ( !info_url.empty() ) - { - substitutions["INFO_URL"] = info_url; - } - else - { - LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL; - - // truncate version at the rightmost '.' - std::string version_short(data["version"]); - size_t short_length = version_short.rfind('.'); - if (short_length != std::string::npos) - { - version_short.resize(short_length); - } - - LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); - relnotes_url.setArg("[VERSION_SHORT]", version_short); - - // *TODO thread the update service's response through to this point - std::string const & channel = LLVersionInfo::getChannel(); - boost::shared_ptr channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); - - relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); - relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); - substitutions["INFO_URL"] = relnotes_url.getString(); - } - - LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback); - } - - void install_error_callback(LLSD const & notification, LLSD const & response) - { - LLAppViewer::instance()->forceQuit(); - } - - bool notify_update(LLSD const & evt) - { - std::string notification_name; - switch (evt["type"].asInteger()) - { - case LLUpdaterService::DOWNLOAD_COMPLETE: - on_update_downloaded(evt); - break; - case LLUpdaterService::INSTALL_ERROR: - if(evt["required"].asBoolean()) { - LLNotificationsUtil::add("FailedRequiredUpdateInstall", LLSD(), LLSD(), &install_error_callback); - } else { - LLNotificationsUtil::add("FailedUpdateInstall"); - } - break; - default: - break; - } - - // let others also handle this event by default - return false; - } - - bool on_bandwidth_throttle(LLUpdaterService * updater, LLSD const & evt) - { - updater->setBandwidthLimit(evt.asInteger() * (1024/8)); - return false; // Let others receive this event. - }; -}; - -void LLAppViewer::initUpdater() -{ - // Initialize the updater service. - // Get Channel - // Get Version - - /***************************************************************** - * Previously, the url was derived from the settings - * UpdaterServiceURL - * UpdaterServicePath - * it is now obtained from the grid manager. The settings above - * are no longer used. - *****************************************************************/ - std::string channel = LLVersionInfo::getChannel(); - std::string version = LLVersionInfo::getVersion(); - - U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod"); - bool willing_to_test; - LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL; - - if (LLVersionInfo::TEST_VIEWER == LLVersionInfo::getViewerMaturity()) - { - LL_INFOS("UpdaterService") << "Test build: overriding willing_to_test by sending testno" << LL_ENDL; - willing_to_test = false; - } - else - { - willing_to_test = gSavedSettings.getBOOL("UpdaterWillingToTest"); - } - unsigned char unique_id[MD5HEX_STR_SIZE]; - if ( ! llHashedUniqueID(unique_id) ) - { - if ( willing_to_test ) - { - LL_WARNS("UpdaterService") << "Unable to provide a unique id; overriding willing_to_test by sending testno" << LL_ENDL; - } - willing_to_test = false; - } - - mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this)); - mUpdater->initialize(channel, - version, - gPlatform, - getOSInfo().getOSVersionString(), - unique_id, - willing_to_test - ); - mUpdater->setCheckPeriod(check_period); - mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8)); - gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()-> - connect(boost::bind(&on_bandwidth_throttle, mUpdater.get(), _2)); - if(gSavedSettings.getU32("UpdaterServiceSetting")) - { - bool install_if_ready = true; - mUpdater->startChecking(install_if_ready); - } - - LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()); - updater_pump.listen("notify_update", ¬ify_update); -} - // // This function decides whether the client machine meets the minimum requirements to // run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011. @@ -5663,143 +5427,6 @@ void LLAppViewer::handleLoginComplete() mSavePerAccountSettings=true; } -void LLAppViewer::launchUpdater() -{ - LLSD query_map = LLSD::emptyMap(); - query_map["os"] = gPlatform; - - // *TODO change userserver to be grid on both viewer and sim, since - // userserver no longer exists. - query_map["userserver"] = LLGridManager::getInstance()->getGridId(); - query_map["channel"] = LLVersionInfo::getChannel(); - // *TODO constantize this guy - // *NOTE: This URL is also used in win_setup/lldownloader.cpp - LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); - - if(LLAppViewer::sUpdaterInfo) - { - delete LLAppViewer::sUpdaterInfo; - } - LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ; - - // if a sim name was passed in via command line parameter (typically through a SLURL) - if ( LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION ) - { - // record the location to start at next time - gSavedSettings.setString( "NextLoginLocation", LLStartUp::getStartSLURL().getSLURLString()); - }; - -#if LL_WINDOWS - LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename(); - if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty()) - { - delete LLAppViewer::sUpdaterInfo ; - LLAppViewer::sUpdaterInfo = NULL ; - - // We're hosed, bail - LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL; - return; - } - - LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe"; - - std::string updater_source = gDirUtilp->getAppRODataDir(); - updater_source += gDirUtilp->getDirDelimiter(); - updater_source += "updater.exe"; - - LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source - << " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath - << LL_ENDL; - - - if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE)) - { - delete LLAppViewer::sUpdaterInfo ; - LLAppViewer::sUpdaterInfo = NULL ; - - LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL; - - return; - } - - LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\""; - - LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL; - - //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird. - LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails - - // *NOTE:Mani The updater is spawned as the last thing before the WinMain exit. - // see LLAppViewerWin32.cpp - -#elif LL_DARWIN - LLAppViewer::sUpdaterInfo->mUpdateExePath = "'"; - LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir(); - LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \""; - LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString(); - LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \""; - LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle(); - LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -bundleid \""; - LLAppViewer::sUpdaterInfo->mUpdateExePath += LL_VERSION_BUNDLE_ID; - LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &"; - - LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; - - // Run the auto-updater. - system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */ - -#elif (LL_LINUX || LL_SOLARIS) && LL_GTK - // we tell the updater where to find the xml containing string - // translations which it can use for its own UI - std::string xml_strings_file = "strings.xml"; - std::vector xui_path_vec = - gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_strings_file); - std::string xml_search_paths; - const char* delim = ""; - // build comma-delimited list of xml paths to pass to updater - BOOST_FOREACH(std::string this_skin_path, xui_path_vec) - { - // Although we already have the full set of paths with the filename - // appended, the linux-updater.bin command-line switches require us to - // snip the filename OFF and pass it as a separate switch argument. :-P - LL_INFOS() << "Got a XUI path: " << this_skin_path << LL_ENDL; - xml_search_paths.append(delim); - xml_search_paths.append(gDirUtilp->getDirName(this_skin_path)); - delim = ","; - } - // build the overall command-line to run the updater correctly - LLAppViewer::sUpdaterInfo->mUpdateExePath = - gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" + - " --url \"" + update_url.asString() + "\"" + - " --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" + - " --dest \"" + gDirUtilp->getAppRODataDir() + "\"" + - " --stringsdir \"" + xml_search_paths + "\"" + - " --stringsfile \"" + xml_strings_file + "\""; - - LL_INFOS("AppInit") << "Calling updater: " - << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; - - // *TODO: we could use the gdk equivalent to ensure the updater - // gets started on the same screen. - GError *error = NULL; - if (!g_spawn_command_line_async(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), &error)) - { - LL_ERRS() << "Failed to launch updater: " - << error->message - << LL_ENDL; - } - if (error) { - g_error_free(error); - } -#else - OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK); -#endif - - // *REMOVE:Mani - Saving for reference... - // LLAppViewer::instance()->forceQuit(); -} - - //virtual void LLAppViewer::setMasterSystemAudioMute(bool mute) { diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b5e674bd7b..35d85a9fb1 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -55,7 +55,6 @@ class LLTextureCache; class LLImageDecodeThread; class LLTextureFetch; class LLWatchdogTimeout; -class LLUpdaterService; class LLViewerJoystick; extern LLTrace::BlockTimerStatHandle FTM_FRAME; @@ -228,7 +227,6 @@ private: bool initThreads(); // Initialize viewer threads, return false on failure. bool initConfiguration(); // Initialize settings from the command line/config file. void initStrings(); // Initialize LLTrans machinery - void initUpdater(); // Initialize the updater service. bool initCache(); // Initialize local client cache. void checkMemory() ; @@ -310,27 +308,10 @@ private: LLAllocator mAlloc; LLFrameTimer mMemCheckTimer; - - boost::scoped_ptr mUpdater; // llcorehttp library init/shutdown helper LLAppCoreHttp mAppCoreHttp; - //--------------------------------------------- - //*NOTE: Mani - legacy updater stuff - // Still useable? -public: - - //some information for updater - typedef struct - { - std::string mUpdateExePath; - std::ostringstream mParams; - }LLUpdaterInfo ; - static LLUpdaterInfo *sUpdaterInfo ; - - void launchUpdater(); - //--------------------------------------------- }; // consts from viewer.h diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 4786f83bfd..6d879f6416 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -361,17 +361,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, delete viewer_app_ptr; viewer_app_ptr = NULL; - //start updater - if(LLAppViewer::sUpdaterInfo) - { - _spawnl(_P_NOWAIT, LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mParams.str().c_str(), NULL); - - delete LLAppViewer::sUpdaterInfo ; - LLAppViewer::sUpdaterInfo = NULL ; - } - - - // (NVAPI) (6) We clean up. This is analogous to doing a free() if (hSession) { diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index bababca652..0d262e73ef 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -39,7 +39,6 @@ #include "llslurl.h" #include "llvoiceclient.h" #include "lluictrlfactory.h" -#include "llupdaterservice.h" #include "llviewertexteditor.h" #include "llviewercontrol.h" #include "llviewerstats.h" @@ -91,10 +90,6 @@ public: void onClickCopyToClipboard(); void onClickUpdateCheck(); - // checks state of updater service and starts a check outside of schedule. - // subscribes callback for closest state update - static void setUpdateListener(); - private: void setSupportText(const std::string& server_release_notes_url); @@ -103,9 +98,6 @@ private: // callback method for manual checks static bool callbackCheckUpdate(LLSD const & event); - - // listener name for update checks - static const std::string sCheckUpdateListenerName; static void startFetchServerReleaseNotes(); static void handleServerReleaseNotes(LLSD results); @@ -139,9 +131,6 @@ BOOL LLFloaterAbout::postBuild() getChild("copy_btn")->setCommitCallback( boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this)); - getChild("update_btn")->setCommitCallback( - boost::bind(&LLFloaterAbout::onClickUpdateCheck, this)); - static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor"); if (gAgent.getRegion()) @@ -289,11 +278,6 @@ void LLFloaterAbout::onClickCopyToClipboard() support_widget->deselect(); } -void LLFloaterAbout::onClickUpdateCheck() -{ - setUpdateListener(); -} - void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url) { #if LL_WINDOWS @@ -314,68 +298,6 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url) FALSE, LLStyle::Params() .color(about_color)); } -///---------------------------------------------------------------------------- -/// Floater About Update-check related functions -///---------------------------------------------------------------------------- - -const std::string LLFloaterAbout::sCheckUpdateListenerName = "LLUpdateNotificationListener"; - -void LLFloaterAbout::showCheckUpdateNotification(S32 state) -{ - switch (state) - { - case LLUpdaterService::UP_TO_DATE: - LLNotificationsUtil::add("UpdateViewerUpToDate"); - break; - case LLUpdaterService::DOWNLOADING: - case LLUpdaterService::INSTALLING: - LLNotificationsUtil::add("UpdateDownloadInProgress"); - break; - case LLUpdaterService::TERMINAL: - // download complete, user triggered check after download pop-up appeared - LLNotificationsUtil::add("UpdateDownloadComplete"); - break; - default: - LLNotificationsUtil::add("UpdateCheckError"); - break; - } -} - -bool LLFloaterAbout::callbackCheckUpdate(LLSD const & event) -{ - if (!event.has("payload")) - { - return false; - } - - LLSD payload = event["payload"]; - if (payload.has("type") && payload["type"].asInteger() == LLUpdaterService::STATE_CHANGE) - { - LLEventPumps::instance().obtain("mainlooprepeater").stopListening(sCheckUpdateListenerName); - showCheckUpdateNotification(payload["state"].asInteger()); - } - return false; -} - -void LLFloaterAbout::setUpdateListener() -{ - LLUpdaterService update_service; - S32 service_state = update_service.getState(); - // Note: Do not set state listener before forceCheck() since it set's new state - if (update_service.forceCheck() || service_state == LLUpdaterService::CHECKING_FOR_UPDATE) - { - LLEventPump& mainloop(LLEventPumps::instance().obtain("mainlooprepeater")); - if (mainloop.getListener(sCheckUpdateListenerName) == LLBoundListener()) // dummy listener - { - mainloop.listen(sCheckUpdateListenerName, boost::bind(&callbackCheckUpdate, _1)); - } - } - else - { - showCheckUpdateNotification(service_state); - } -} - ///---------------------------------------------------------------------------- /// LLFloaterAboutUtil ///---------------------------------------------------------------------------- @@ -386,8 +308,3 @@ void LLFloaterAboutUtil::registerFloater() } -void LLFloaterAboutUtil::checkUpdatesAndNotify() -{ - LLFloaterAbout::setUpdateListener(); -} - diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index b4d0bb6823..b9e9c12aec 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -50,13 +50,12 @@ #include "llwindow.h" #include "llviewerwindow.h" #include "llprogressview.h" -#if LL_LINUX || LL_SOLARIS +#if LL_LINUX #include "lltrans.h" #endif #include "llsecapi.h" #include "llstartup.h" #include "llmachineid.h" -#include "llupdaterservice.h" #include "llevents.h" #include "llappviewer.h" @@ -68,406 +67,11 @@ public: virtual ~Disposable() {} }; -namespace { - class MandatoryUpdateMachine: - public LLLoginInstance::Disposable - { - public: - MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService); - - void start(void); - - LLNotificationsInterface& getNotificationsInterface() const - { - return mLoginInstance.getNotificationsInterface(); - } - - private: - class State; - class CheckingForUpdate; - class Error; - class ReadyToInstall; - class StartingUpdaterService; - class WaitingForDownload; - - boost::scoped_ptr mState; - LLLoginInstance & mLoginInstance; - LLUpdaterService & mUpdaterService; - - void setCurrentState(State * newState); - }; - - - class MandatoryUpdateMachine::State { - public: - virtual ~State() {} - virtual void enter(void) {} - virtual void exit(void) {} - }; - - - class MandatoryUpdateMachine::CheckingForUpdate: - public MandatoryUpdateMachine::State - { - public: - CheckingForUpdate(MandatoryUpdateMachine & machine); - - virtual void enter(void); - virtual void exit(void); - - private: - LLTempBoundListener mConnection; - MandatoryUpdateMachine & mMachine; - LLProgressView * mProgressView; - - bool onEvent(LLSD const & event); - }; - - - class MandatoryUpdateMachine::Error: - public MandatoryUpdateMachine::State - { - public: - Error(MandatoryUpdateMachine & machine); - - virtual void enter(void); - virtual void exit(void); - void onButtonClicked(const LLSD &, const LLSD &); - - private: - MandatoryUpdateMachine & mMachine; - }; - - - class MandatoryUpdateMachine::ReadyToInstall: - public MandatoryUpdateMachine::State - { - public: - ReadyToInstall(MandatoryUpdateMachine & machine); - - virtual void enter(void); - virtual void exit(void); - - private: - //MandatoryUpdateMachine & mMachine; - }; - - - class MandatoryUpdateMachine::StartingUpdaterService: - public MandatoryUpdateMachine::State - { - public: - StartingUpdaterService(MandatoryUpdateMachine & machine); - - virtual void enter(void); - virtual void exit(void); - void onButtonClicked(const LLSD & uiform, const LLSD & result); - private: - MandatoryUpdateMachine & mMachine; - }; - - - class MandatoryUpdateMachine::WaitingForDownload: - public MandatoryUpdateMachine::State - { - public: - WaitingForDownload(MandatoryUpdateMachine & machine); - - virtual void enter(void); - virtual void exit(void); - - private: - LLTempBoundListener mConnection; - MandatoryUpdateMachine & mMachine; - LLProgressView * mProgressView; - - bool onEvent(LLSD const & event); - }; -} - static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback"; static const char * const TOS_LISTENER_NAME = "lllogininstance_tos"; std::string construct_start_string(); - - -// MandatoryUpdateMachine -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService): - mLoginInstance(loginInstance), - mUpdaterService(updaterService) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::start(void) -{ - LL_INFOS() << "starting mandatory update machine" << LL_ENDL; - - if(mUpdaterService.isChecking()) { - switch(mUpdaterService.getState()) { - case LLUpdaterService::UP_TO_DATE: - mUpdaterService.stopChecking(); - mUpdaterService.startChecking(); - // Fall through. - case LLUpdaterService::INITIAL: - case LLUpdaterService::CHECKING_FOR_UPDATE: - setCurrentState(new CheckingForUpdate(*this)); - break; - case LLUpdaterService::TEMPORARY_ERROR: - setCurrentState(new Error(*this)); - break; - case LLUpdaterService::DOWNLOADING: - setCurrentState(new WaitingForDownload(*this)); - break; - case LLUpdaterService::TERMINAL: - if(LLUpdaterService::updateReadyToInstall()) { - setCurrentState(new ReadyToInstall(*this)); - } else { - setCurrentState(new Error(*this)); - } - break; - case LLUpdaterService::FAILURE: - setCurrentState(new Error(*this)); - break; - default: - llassert(!"unpossible case"); - break; - } - } else { - setCurrentState(new StartingUpdaterService(*this)); - } -} - - -void MandatoryUpdateMachine::setCurrentState(State * newStatePointer) -{ - { - boost::scoped_ptr newState(newStatePointer); - if(mState != 0) mState->exit(); - mState.swap(newState); - - // Old state will be deleted on exit from this block before the new state - // is entered. - } - if(mState != 0) mState->enter(); -} - - - -// MandatoryUpdateMachine::CheckingForUpdate -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::CheckingForUpdate::CheckingForUpdate(MandatoryUpdateMachine & machine): - mMachine(machine) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::CheckingForUpdate::enter(void) -{ - LL_INFOS() << "entering checking for update" << LL_ENDL; - - mProgressView = gViewerWindow->getProgressView(); - mProgressView->setMessage("Looking for update..."); - mProgressView->setText("There is a required update for your Second Life installation."); - mProgressView->setPercent(0); - mProgressView->setVisible(true); - mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()). - listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::CheckingForUpdate::onEvent, this, _1)); -} - - -void MandatoryUpdateMachine::CheckingForUpdate::exit(void) -{ -} - - -bool MandatoryUpdateMachine::CheckingForUpdate::onEvent(LLSD const & event) -{ - if(event["type"].asInteger() == LLUpdaterService::STATE_CHANGE) { - switch(event["state"].asInteger()) { - case LLUpdaterService::DOWNLOADING: - mMachine.setCurrentState(new WaitingForDownload(mMachine)); - break; - case LLUpdaterService::TEMPORARY_ERROR: - case LLUpdaterService::UP_TO_DATE: - case LLUpdaterService::TERMINAL: - case LLUpdaterService::FAILURE: - mProgressView->setVisible(false); - mMachine.setCurrentState(new Error(mMachine)); - break; - case LLUpdaterService::INSTALLING: - llassert(!"can't possibly be installing"); - break; - default: - break; - } - } else { - ; // Ignore. - } - - return false; -} - - - -// MandatoryUpdateMachine::Error -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::Error::Error(MandatoryUpdateMachine & machine): - mMachine(machine) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::Error::enter(void) -{ - LL_INFOS() << "entering error" << LL_ENDL; - mMachine.getNotificationsInterface().add("FailedRequiredUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2)); -} - - -void MandatoryUpdateMachine::Error::exit(void) -{ - LLAppViewer::instance()->forceQuit(); -} - - -void MandatoryUpdateMachine::Error::onButtonClicked(const LLSD &, const LLSD &) -{ - mMachine.setCurrentState(0); -} - - - -// MandatoryUpdateMachine::ReadyToInstall -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::ReadyToInstall::ReadyToInstall(MandatoryUpdateMachine & machine) //: - //mMachine(machine) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::ReadyToInstall::enter(void) -{ - LL_INFOS() << "entering ready to install" << LL_ENDL; - // Open update ready dialog. -} - - -void MandatoryUpdateMachine::ReadyToInstall::exit(void) -{ - // Restart viewer. -} - - - -// MandatoryUpdateMachine::StartingUpdaterService -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::StartingUpdaterService::StartingUpdaterService(MandatoryUpdateMachine & machine): - mMachine(machine) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::StartingUpdaterService::enter(void) -{ - LL_INFOS() << "entering start update service" << LL_ENDL; - mMachine.getNotificationsInterface().add("UpdaterServiceNotRunning", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked, this, _1, _2)); -} - - -void MandatoryUpdateMachine::StartingUpdaterService::exit(void) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked(const LLSD & uiform, const LLSD & result) -{ - if(result["OK_okcancelbuttons"].asBoolean()) { - mMachine.mUpdaterService.startChecking(false); - mMachine.setCurrentState(new CheckingForUpdate(mMachine)); - } else { - LLAppViewer::instance()->forceQuit(); - } -} - - - -// MandatoryUpdateMachine::WaitingForDownload -//----------------------------------------------------------------------------- - - -MandatoryUpdateMachine::WaitingForDownload::WaitingForDownload(MandatoryUpdateMachine & machine): - mMachine(machine), - mProgressView(0) -{ - ; // No op. -} - - -void MandatoryUpdateMachine::WaitingForDownload::enter(void) -{ - LL_INFOS() << "entering waiting for download" << LL_ENDL; - mProgressView = gViewerWindow->getProgressView(); - mProgressView->setMessage("Downloading update..."); - std::ostringstream stream; - stream << "There is a required update for your Second Life installation." << std::endl << - "Version " << mMachine.mUpdaterService.updatedVersion(); - mProgressView->setText(stream.str()); - mProgressView->setPercent(0); - mProgressView->setVisible(true); - mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()). - listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::WaitingForDownload::onEvent, this, _1)); -} - - -void MandatoryUpdateMachine::WaitingForDownload::exit(void) -{ - mProgressView->setVisible(false); -} - - -bool MandatoryUpdateMachine::WaitingForDownload::onEvent(LLSD const & event) -{ - switch(event["type"].asInteger()) { - case LLUpdaterService::DOWNLOAD_COMPLETE: - mMachine.setCurrentState(new ReadyToInstall(mMachine)); - break; - case LLUpdaterService::DOWNLOAD_ERROR: - mMachine.setCurrentState(new Error(mMachine)); - break; - case LLUpdaterService::PROGRESS: { - double downloadSize = event["download_size"].asReal(); - double bytesDownloaded = event["bytes_downloaded"].asReal(); - mProgressView->setPercent(100. * bytesDownloaded / downloadSize); - break; - } - default: - break; - } - - return false; -} - - - // LLLoginInstance //----------------------------------------------------------------------------- @@ -476,11 +80,9 @@ LLLoginInstance::LLLoginInstance() : mLoginModule(new LLLogin()), mNotifications(NULL), mLoginState("offline"), - mSkipOptionalUpdate(false), mAttemptComplete(false), mTransferRate(0.0f), - mDispatcher("LLLoginInstance", "change"), - mUpdaterService(0) + mDispatcher("LLLoginInstance", "change") { mLoginModule->getEventPump().listen("lllogininstance", boost::bind(&LLLoginInstance::handleLoginEvent, this, _1)); @@ -590,18 +192,11 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // (re)initialize the request params with creds. LLSD request_params = user_credential->getLoginParams(); - unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE]; - if ( ! llHashedUniqueID(hashed_unique_id_string) ) - { - LL_WARNS() << "Not providing a unique id in request params" << LL_ENDL; - } request_params["start"] = construct_start_string(); - request_params["skipoptional"] = mSkipOptionalUpdate; request_params["agree_to_tos"] = false; // Always false here. Set true in request_params["read_critical"] = false; // handleTOSResponse request_params["last_exec_event"] = mLastExecEvent; request_params["last_exec_duration"] = mLastExecDuration; - request_params["mac"] = (char*)hashed_unique_id_string; request_params["version"] = LLVersionInfo::getVersion(); request_params["channel"] = LLVersionInfo::getChannel(); request_params["platform"] = mPlatform; @@ -698,19 +293,6 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) boost::bind(&LLLoginInstance::handleTOSResponse, this, _1, "read_critical")); } - else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate")) - { - LL_INFOS() << "LLLoginInstance::handleLoginFailure update" << LL_ENDL; - - gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); - updateApp(true, message_response); - } - else if(reason_response == "optional") - { - LL_INFOS() << "LLLoginInstance::handleLoginFailure optional" << LL_ENDL; - - updateApp(false, message_response); - } else { LL_INFOS() << "LLLoginInstance::handleLoginFailure attemptComplete" << LL_ENDL; @@ -722,22 +304,7 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event) { LL_INFOS() << "LLLoginInstance::handleLoginSuccess" << LL_ENDL; - if(gSavedSettings.getBOOL("ForceMandatoryUpdate")) - { - LLSD response = event["data"]; - std::string message_response = response["message"].asString(); - - // Testing update... - gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE); - - // Don't confuse startup by leaving login "online". - mLoginModule->disconnect(); - updateApp(true, message_response); - } - else - { - attemptComplete(); - } + attemptComplete(); } void LLLoginInstance::handleDisconnect(const LLSD& event) @@ -787,135 +354,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) return true; } - -void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg) -{ - if(mandatory) - { - gViewerWindow->setShowProgress(false); - MandatoryUpdateMachine * machine = new MandatoryUpdateMachine(*this, *mUpdaterService); - mUpdateStateMachine.reset(machine); - machine->start(); - return; - } - - // store off config state, as we might quit soon - gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - LLUIColorTable::instance().saveUserSettings(); - - std::ostringstream message; - std::string msg; - if (!auth_msg.empty()) - { - msg = "(" + auth_msg + ") \n"; - } - - LLSD args; - args["MESSAGE"] = msg; - - LLSD payload; - payload["mandatory"] = mandatory; - - /* - * We're constructing one of the following 9 strings here: - * "DownloadWindowsMandatory" - * "DownloadWindowsReleaseForDownload" - * "DownloadWindows" - * "DownloadMacMandatory" - * "DownloadMacReleaseForDownload" - * "DownloadMac" - * "DownloadLinuxMandatory" - * "DownloadLinuxReleaseForDownload" - * "DownloadLinux" - * - * I've called them out explicitly in this comment so that they can be grepped for. - */ - std::string notification_name = "Download"; - -#if LL_WINDOWS - notification_name += "Windows"; -#elif LL_DARWIN - notification_name += "Mac"; -#else - notification_name += "Linux"; -#endif - - if (mandatory) - { - notification_name += "Mandatory"; - } - else - { -#if LL_RELEASE_FOR_DOWNLOAD - notification_name += "ReleaseForDownload"; -#endif - } - - if(mNotifications) - { - mNotifications->add(notification_name, args, payload, - boost::bind(&LLLoginInstance::updateDialogCallback, this, _1, _2)); - - gViewerWindow->setShowProgress(false); - } -} - -bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - std::string update_exe_path; - bool mandatory = notification["payload"]["mandatory"].asBoolean(); - -#if !LL_RELEASE_FOR_DOWNLOAD - if (option == 2) - { - // This condition attempts to skip the - // update if using a dev build. - // The relog probably won't work if the - // update is mandatory. :) - - // *REMOVE:Mani - Saving for reference... - //LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); - mSkipOptionalUpdate = true; - reconnect(); - return false; - } -#endif - - if (option == 1) - { - // ...user doesn't want to do it - if (mandatory) - { - // Mandatory update, user chose to not to update... - // The login attemp is complete, startup should - // quit when detecting this. - attemptComplete(); - - // *REMOVE:Mani - Saving for reference... - //LLAppViewer::instance()->forceQuit(); - // // Bump them back to the login screen. - // //reset_login(); - } - else - { - // Optional update, user chose to skip - mSkipOptionalUpdate = true; - reconnect(); - } - return false; - } - - if(mUpdaterLauncher) - { - mUpdaterLauncher(); - } - - attemptComplete(); - - return false; -} - std::string construct_start_string() { std::string start; diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index c6773bbf68..dfd39e4752 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -34,7 +34,6 @@ class LLLogin; class LLEventStream; class LLNotificationsInterface; -class LLUpdaterService; // This class hosts the login module and is used to // negotiate user authentication attempts. @@ -60,10 +59,6 @@ public: // Only valid when authSuccess == true. const F64 getLastTransferRateBPS() { return mTransferRate; } - - // Whether to tell login to skip optional update request. - // False by default. - void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; } void setSerialNumber(const std::string& sn) { mSerialNumber = sn; } void setLastExecEvent(int lee) { mLastExecEvent = lee; } void setLastExecDuration(S32 duration) { mLastExecDuration = duration; } @@ -72,10 +67,6 @@ public: void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; } - typedef boost::function UpdaterLauncherCallback; - void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; } - - void setUpdaterService(LLUpdaterService * updaterService) { mUpdaterService = updaterService; } private: void constructAuthParams(LLPointer user_credentials); void updateApp(bool mandatory, const std::string& message); @@ -97,7 +88,6 @@ private: std::string mLoginState; LLSD mRequestData; LLSD mResponseData; - bool mSkipOptionalUpdate; bool mAttemptComplete; F64 mTransferRate; std::string mSerialNumber; @@ -105,10 +95,7 @@ private: S32 mLastExecDuration; std::string mPlatform; std::string mPlatformVersion; - UpdaterLauncherCallback mUpdaterLauncher; LLEventDispatcher mDispatcher; - LLUpdaterService * mUpdaterService; - boost::scoped_ptr mUpdateStateMachine; }; #endif diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a2c8e7772e..62ca3434d7 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1009,7 +1009,6 @@ bool idle_startup() login->setSerialNumber(LLAppViewer::instance()->getSerialNumber()); login->setLastExecEvent(gLastExecEvent); login->setLastExecDuration(gLastExecDuration); - login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance())); // This call to LLLoginInstance::connect() starts the // authentication process. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 16f40fb747..2cf56582f5 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -74,7 +74,6 @@ #include "llspellcheck.h" #include "llslurl.h" #include "llstartup.h" -#include "llupdaterservice.h" // Third party library includes #include @@ -575,19 +574,6 @@ bool toggle_show_object_render_cost(const LLSD& newvalue) return true; } -void toggle_updater_service_active(const LLSD& new_value) -{ - if(new_value.asInteger()) - { - LLUpdaterService update_service; - if(!update_service.isChecking()) update_service.startChecking(); - } - else - { - LLUpdaterService().stopChecking(); - } -} - //////////////////////////////////////////////////////////////////////////// void settings_setup_listeners() @@ -735,7 +721,6 @@ void settings_setup_listeners() gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2)); gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2)); gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2)); - gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(boost::bind(&toggle_updater_service_active, _2)); gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2)); gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 99a9ed1d75..1b1bbd5071 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2119,22 +2119,6 @@ class LLAdvancedCheckShowObjectUpdates : public view_listener_t -/////////////////////// -// CHECK FOR UPDATES // -/////////////////////// - - - -class LLAdvancedCheckViewerUpdates : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFloaterAboutUtil::checkUpdatesAndNotify(); - return true; - } -}; - - //////////////////// // COMPRESS IMAGE // //////////////////// @@ -8918,7 +8902,6 @@ void initialize_menus() // Advanced (toplevel) view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates"); view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates"); - view_listener_t::addMenu(new LLAdvancedCheckViewerUpdates(), "Advanced.CheckViewerUpdates"); view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage"); view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings"); view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions"); diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 1b0334498e..b43aaeaa33 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -192,36 +192,6 @@ const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; } void LLAppViewer::forceQuit(void) {} LLAppViewer * LLAppViewer::sInstance = 0; -//----------------------------------------------------------------------------- -#include "llupdaterservice.h" - -std::string const & LLUpdaterService::pumpName(void) -{ - static std::string wakka = "wakka wakka wakka"; - return wakka; -} -bool LLUpdaterService::updateReadyToInstall(void) { return false; } -void LLUpdaterService::initialize(const std::string& channel, - const std::string& version, - const std::string& platform, - const std::string& platform_version, - const unsigned char uniqueid[MD5HEX_STR_SIZE], - const bool& willing_to_test - ) {} - -void LLUpdaterService::setCheckPeriod(unsigned int seconds) {} -void LLUpdaterService::startChecking(bool install_if_ready) {} -void LLUpdaterService::stopChecking() {} -bool LLUpdaterService::isChecking() { return false; } -LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; } -std::string LLUpdaterService::updatedVersion() { return ""; } - -bool llHashedUniqueID(unsigned char* id) -{ - memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE ); - return true; -} - //----------------------------------------------------------------------------- #include "llnotifications.h" #include "llfloaterreg.h" @@ -338,7 +308,6 @@ namespace tut gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO); gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO); gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO); - gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO); gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO); gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO); gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO); @@ -476,110 +445,4 @@ namespace tut logininstance->connect(test_uri, agentCredential); ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false); } - - template<> template<> - void lllogininstance_object::test<3>() - { - set_test_name("Test Mandatory Update User Accepts"); - - // Part 1 - Mandatory Update, with User accepts response. - // Test connect with update needed. - logininstance->connect(agentCredential); - - ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); - - // Update needed failure response. - LLSD response; - response["state"] = "offline"; - response["change"] = "fail.login"; - response["progress"] = 0.0; - response["transfer_rate"] = 7; - response["data"]["reason"] = "update"; - gTestPump.post(response); - - ensure_equals("Notification added", notifications.addedCount(), 1); - - notifications.sendYesResponse(); - - ensure("Disconnected", !(logininstance->authSuccess())); - } - - template<> template<> - void lllogininstance_object::test<4>() - { - set_test_name("Test Mandatory Update User Decline"); - - // Test connect with update needed. - logininstance->connect(agentCredential); - - ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); - - // Update needed failure response. - LLSD response; - response["state"] = "offline"; - response["change"] = "fail.login"; - response["progress"] = 0.0; - response["transfer_rate"] = 7; - response["data"]["reason"] = "update"; - gTestPump.post(response); - - ensure_equals("Notification added", notifications.addedCount(), 1); - notifications.sendNoResponse(); - - ensure("Disconnected", !(logininstance->authSuccess())); - } - - template<> template<> - void lllogininstance_object::test<6>() - { - set_test_name("Test Optional Update User Accept"); - - // Part 3 - Mandatory Update, with bogus response. - // Test connect with update needed. - logininstance->connect(agentCredential); - - ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); - - // Update needed failure response. - LLSD response; - response["state"] = "offline"; - response["change"] = "fail.login"; - response["progress"] = 0.0; - response["transfer_rate"] = 7; - response["data"]["reason"] = "optional"; - gTestPump.post(response); - - ensure_equals("Notification added", notifications.addedCount(), 1); - notifications.sendYesResponse(); - - ensure("Disconnected", !(logininstance->authSuccess())); - } - - template<> template<> - void lllogininstance_object::test<7>() - { - set_test_name("Test Optional Update User Denies"); - - // Part 3 - Mandatory Update, with bogus response. - // Test connect with update needed. - logininstance->connect(agentCredential); - - ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI); - - // Update needed failure response. - LLSD response; - response["state"] = "offline"; - response["change"] = "fail.login"; - response["progress"] = 0.0; - response["transfer_rate"] = 7; - response["data"]["reason"] = "optional"; - gTestPump.post(response); - - ensure_equals("Notification added", notifications.addedCount(), 1); - notifications.sendNoResponse(); - - // User skips, should be reconnecting. - ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI); - ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true); - } } diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt index 74c9b4568d..642dada7b2 100644 --- a/indra/viewer_components/CMakeLists.txt +++ b/indra/viewer_components/CMakeLists.txt @@ -1,4 +1,3 @@ # -*- cmake -*- add_subdirectory(login) -add_subdirectory(updater) diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt deleted file mode 100644 index 73e18aacb3..0000000000 --- a/indra/viewer_components/updater/CMakeLists.txt +++ /dev/null @@ -1,106 +0,0 @@ -# -*- cmake -*- - -project(updater_service) - -include(00-Common) -if(LL_TESTS) - include(LLAddBuildTest) -endif(LL_TESTS) -include(Boost) -include(CMakeCopyIfDifferent) -include(CURL) -include(LLCommon) -include(LLCoreHttp) -include(LLMessage) -include(LLPlugin) -include(LLVFS) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLPLUGIN_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${CURL_INCLUDE_DIRS} - ${CMAKE_SOURCE_DIR}/newview - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - -set(updater_service_SOURCE_FILES - llupdaterservice.cpp - llupdatechecker.cpp - llupdatedownloader.cpp - llupdateinstaller.cpp - ) - -set(updater_service_HEADER_FILES - llupdaterservice.h - llupdatechecker.h - llupdatedownloader.h - llupdateinstaller.h - ) - -set_source_files_properties(${updater_service_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -set_source_files_properties( - llupdaterservice.cpp - PROPERTIES - COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # see BuildVersion.cmake - ) - -list(APPEND - updater_service_SOURCE_FILES - ${updater_service_HEADER_FILES} - ) - -add_library(llupdaterservice - ${updater_service_SOURCE_FILES} - ) - -target_link_libraries(llupdaterservice - ${LLCOMMON_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLPLUGIN_LIBRARIES} - ${LLVFS_LIBRARIES} - ) - -if(LL_TESTS) -if (NOT LINUX) - SET(llupdater_service_TEST_SOURCE_FILES - llupdaterservice.cpp - ) - -set(test_libs - ${LLCOMMON_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) - -set_source_files_properties( - llupdaterservice.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES ${test_libs} -# *NOTE:Mani - I was trying to use the preprocessor seam to mock out -# llifstream (and other) llcommon classes. It didn't work -# because of the windows declspec(dllimport)attribute. -# LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream" - ) - - LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}" ${test_libs}) -endif (NOT LINUX) -endif(LL_TESTS) - -set(UPDATER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/viewer_components/updater - CACHE INTERNAL "" -) - -set(UPDATER_LIBRARIES - llupdaterservice - CACHE INTERNAL "" -) diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp deleted file mode 100644 index 1bb5e95740..0000000000 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @file llupdaterservice.cpp - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include -#include -#include "llsd.h" -#include "llupdatechecker.h" -#include "lluri.h" -#include "llcorehttputil.h" -#if LL_DARWIN -#include -#endif - -#if LL_WINDOWS -#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally -#endif - - -class LLUpdateChecker::CheckError: - public std::runtime_error -{ -public: - CheckError(const char * message): - std::runtime_error(message) - { - ; // No op. - } -}; - - -// LLUpdateChecker -//----------------------------------------------------------------------------- -LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client): - mImplementation(new LLUpdateChecker::Implementation(client)) -{ - ; // No op. -} - -void LLUpdateChecker::checkVersion(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test) -{ - mImplementation->checkVersion(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test); -} - - -// LLUpdateChecker::Implementation -//----------------------------------------------------------------------------- -const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.1"; - - -LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client): - mClient(client), - mInProgress(false), - mProtocol(sProtocolVersion) -{ - ; // No op. -} - - -LLUpdateChecker::Implementation::~Implementation() -{ - ; // No op. -} - - -void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test) -{ - if (!mInProgress) - { - mInProgress = true; - - mUrlBase = urlBase; - mChannel = channel; - mVersion = version; - mPlatform = platform; - mPlatformVersion = platform_version; - memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE); - mWillingToTest = willing_to_test; - - mProtocol = sProtocolVersion; - - std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test); - LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL; - - LLCoros::instance().launch("LLUpdateChecker::Implementation::checkVersionCoro", - boost::bind(&Implementation::checkVersionCoro, this, checkUrl)); - - } - else - { - LL_WARNS("UpdaterService") << "attempting to restart a check when one is in progress; ignored" << LL_ENDL; - } -} - -void LLUpdateChecker::Implementation::checkVersionCoro(std::string url) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("checkVersionCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LL_INFOS("checkVersionCoro") << "Getting update information from " << url << LL_ENDL; - - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - mInProgress = false; - - if (status != LLCore::HttpStatus(HTTP_OK)) - { - std::string server_error; - if (result.has("error_code")) - { - server_error += result["error_code"].asString(); - } - if (result.has("error_text")) - { - server_error += server_error.empty() ? "" : ": "; - server_error += result["error_text"].asString(); - } - - LL_WARNS("UpdaterService") << "response error " << status.getStatus() - << " " << status.toString() - << " (" << server_error << ")" - << LL_ENDL; - mClient.error(status.toString()); - return; - } - - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - mClient.response(result); -} - -std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test) -{ - LLSD path; - path.append(mProtocol); - path.append(channel); - path.append(version); - path.append(platform); - path.append(platform_version); - path.append(willing_to_test ? "testok" : "testno"); - path.append((char*)uniqueid); - return LLURI::buildHTTP(urlBase, path).asString(); -} diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h deleted file mode 100644 index d10ea4cf42..0000000000 --- a/indra/viewer_components/updater/llupdatechecker.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file llupdatechecker.h - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_UPDATERCHECKER_H -#define LL_UPDATERCHECKER_H - - -#include - -#include "llmd5.h" -#include "lleventcoro.h" -#include "llcoros.h" - -// -// Implements asynchronous checking for updates. -// -class LLUpdateChecker { -public: - // - // The client interface implemented by a requestor checking for an update. - // - class Client - { - public: - // An error occurred while checking for an update. - virtual void error(std::string const & message) = 0; - - // A successful response was received from the viewer version manager - virtual void response(LLSD const & content) = 0; - }; - - // An exception that may be raised on check errors. - class CheckError; - - LLUpdateChecker(Client & client); - - // Check status of current app on the given host for the channel and version provided. - void checkVersion(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test); - -private: - class Implementation - { - public: - typedef boost::shared_ptr ptr_t; - - Implementation(Client & client); - ~Implementation(); - void checkVersion(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test - ); - - - private: - static const char * sLegacyProtocolVersion; - static const char * sProtocolVersion; - const char* mProtocol; - - Client & mClient; - bool mInProgress; - std::string mVersion; - std::string mUrlBase; - std::string mChannel; - std::string mPlatform; - std::string mPlatformVersion; - unsigned char mUniqueId[MD5HEX_STR_SIZE]; - bool mWillingToTest; - - std::string buildUrl(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test); - - void checkVersionCoro(std::string url); - - LOG_CLASS(LLUpdateChecker::Implementation); - }; - - - Implementation::ptr_t mImplementation; - //LLPointer mImplementation; -}; - -#endif diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp deleted file mode 100644 index 382689afa0..0000000000 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/** - * @file llupdatedownloader.cpp - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llupdatedownloader.h" -#include "httpcommon.h" -#include -#include -#include -#include -#include "lldir.h" -#include "llevents.h" -#include "llfile.h" -#include "llmd5.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llthread.h" -#include "llupdaterservice.h" - -class LLUpdateDownloader::Implementation: - public LLThread -{ -public: - Implementation(LLUpdateDownloader::Client & client); - ~Implementation(); - void cancel(void); - void download(LLURI const & uri, - std::string const & hash, - std::string const & updateChannel, - std::string const & updateVersion, - std::string const & info_url, - bool required); - bool isDownloading(void); - size_t onHeader(void * header, size_t size); - size_t onBody(void * header, size_t size); - int onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded); - void resume(void); - void setBandwidthLimit(U64 bytesPerSecond); - -private: - curl_off_t mBandwidthLimit; - bool mCancelled; - LLUpdateDownloader::Client & mClient; - LLCore::LLHttp::CURL_ptr mCurl; - LLSD mDownloadData; - llofstream mDownloadStream; - unsigned char mDownloadPercent; - std::string mDownloadRecordPath; - curl_slist * mHeaderList; - - void initializeCurlGet(std::string const & url, bool processHeader); - void resumeDownloading(size_t startByte); - void run(void); - void startDownloading(LLURI const & uri, std::string const & hash); - void throwOnCurlError(CURLcode code); - bool validateDownload(const std::string& filePath); - bool validateOrRemove(const std::string& filePath); - - LOG_CLASS(LLUpdateDownloader::Implementation); -}; - - -namespace { - class DownloadError: - public std::runtime_error - { - public: - DownloadError(const char * message): - std::runtime_error(message) - { - ; // No op. - } - }; - - - const char * gSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml"; -}; - - - -// LLUpdateDownloader -//----------------------------------------------------------------------------- - - - -std::string LLUpdateDownloader::downloadMarkerPath(void) -{ - return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, gSecondLifeUpdateRecord); -} - - -LLUpdateDownloader::LLUpdateDownloader(Client & client): - mImplementation(new LLUpdateDownloader::Implementation(client)) -{ - ; // No op. -} - - -void LLUpdateDownloader::cancel(void) -{ - mImplementation->cancel(); -} - - -void LLUpdateDownloader::download(LLURI const & uri, - std::string const & hash, - std::string const & updateChannel, - std::string const & updateVersion, - std::string const & info_url, - bool required) -{ - mImplementation->download(uri, hash, updateChannel, updateVersion, info_url, required); -} - - -bool LLUpdateDownloader::isDownloading(void) -{ - return mImplementation->isDownloading(); -} - - -void LLUpdateDownloader::resume(void) -{ - mImplementation->resume(); -} - - -void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) -{ - mImplementation->setBandwidthLimit(bytesPerSecond); -} - - - -// LLUpdateDownloader::Implementation -//----------------------------------------------------------------------------- - - -namespace { - size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader) - { - size_t bytes = blockSize * blocks; - return reinterpret_cast(downloader)->onBody(data, bytes); - } - - - size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader) - { - size_t bytes = blockSize * blocks; - return reinterpret_cast(downloader)->onHeader(data, bytes); - } - - - int xferinfo_callback(void * downloader, - curl_off_t dowloadTotal, - curl_off_t downloadNow, - curl_off_t uploadTotal, - curl_off_t uploadNow) - { - return reinterpret_cast(downloader)-> - onProgress(dowloadTotal, downloadNow); - } -} - - -LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): - LLThread("LLUpdateDownloader"), - mBandwidthLimit(0), - mCancelled(false), - mClient(client), - mCurl(), - mDownloadPercent(0), - mHeaderList(0) -{ - CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. - llverify(code == CURLE_OK); // TODO: real error handling here. -} - - -LLUpdateDownloader::Implementation::~Implementation() -{ - if(isDownloading()) - { - cancel(); - shutdown(); - } - else - { - ; // No op. - } - mCurl.reset(); -} - - -void LLUpdateDownloader::Implementation::cancel(void) -{ - mCancelled = true; -} - - -void LLUpdateDownloader::Implementation::download(LLURI const & uri, - std::string const & hash, - std::string const & updateChannel, - std::string const & updateVersion, - std::string const & info_url, - bool required) -{ - if(isDownloading()) mClient.downloadError("download in progress"); - - mDownloadRecordPath = downloadMarkerPath(); - mDownloadData = LLSD(); - mDownloadData["required"] = required; - mDownloadData["update_channel"] = updateChannel; - mDownloadData["update_version"] = updateVersion; - if (!info_url.empty()) - { - mDownloadData["info_url"] = info_url; - } - try - { - startDownloading(uri, hash); - } - catch(DownloadError const & e) - { - mClient.downloadError(e.what()); - } -} - - -bool LLUpdateDownloader::Implementation::isDownloading(void) -{ - return !isStopped(); -} - - -void LLUpdateDownloader::Implementation::resume(void) -{ - mCancelled = false; - - if(isDownloading()) - { - mClient.downloadError("download in progress"); - } - - mDownloadRecordPath = downloadMarkerPath(); - llifstream dataStream(mDownloadRecordPath.c_str()); - if(!dataStream) - { - mClient.downloadError("no download marker"); - return; - } - - LLSDSerialize::fromXMLDocument(mDownloadData, dataStream); - - if(!mDownloadData.asBoolean()) - { - mClient.downloadError("no download information in marker"); - return; - } - - std::string filePath = mDownloadData["path"].asString(); - try - { - if(LLFile::isfile(filePath)) - { - llstat fileStatus; - LLFile::stat(filePath, &fileStatus); - if(fileStatus.st_size != mDownloadData["size"].asInteger()) - { - resumeDownloading(fileStatus.st_size); - } - else if(!validateOrRemove(filePath)) - { - download(LLURI(mDownloadData["url"].asString()), - mDownloadData["hash"].asString(), - mDownloadData["update_channel"].asString(), - mDownloadData["update_version"].asString(), - mDownloadData["info_url"].asString(), - mDownloadData["required"].asBoolean()); - } - else - { - mClient.downloadComplete(mDownloadData); - } - } - else - { - download(LLURI(mDownloadData["url"].asString()), - mDownloadData["hash"].asString(), - mDownloadData["update_channel"].asString(), - mDownloadData["update_version"].asString(), - mDownloadData["info_url"].asString(), - mDownloadData["required"].asBoolean()); - } - } - catch(DownloadError & e) - { - mClient.downloadError(e.what()); - } -} - - -void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond) -{ - if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) - { - llassert(static_cast(mCurl)); - mBandwidthLimit = bytesPerSecond; - CURLcode code = curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit); - if(code != CURLE_OK) - { - LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL; - } - } - else - { - mBandwidthLimit = bytesPerSecond; - } -} - - -size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) -{ - char const * headerPtr = reinterpret_cast (buffer); - std::string header(headerPtr, headerPtr + size); - size_t colonPosition = header.find(':'); - if(colonPosition == std::string::npos) return size; // HTML response; ignore. - - if(header.substr(0, colonPosition) == "Content-Length") { - try { - size_t firstDigitPos = header.find_first_of("0123456789", colonPosition); - size_t lastDigitPos = header.find_last_of("0123456789"); - std::string contentLength = header.substr(firstDigitPos, lastDigitPos - firstDigitPos + 1); - size_t size = boost::lexical_cast(contentLength); - LL_INFOS("UpdaterService") << "download size is " << size << LL_ENDL; - - mDownloadData["size"] = LLSD(LLSD::Integer(size)); - llofstream odataStream(mDownloadRecordPath.c_str()); - LLSDSerialize::toPrettyXML(mDownloadData, odataStream); - } catch (std::exception const & e) { - LL_WARNS("UpdaterService") << "unable to read content length (" - << e.what() << ")" << LL_ENDL; - } - } else { - ; // No op. - } - - return size; -} - - -size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) -{ - if(mCancelled) return 0; // Forces a write error which will halt curl thread. - if((size == 0) || (buffer == 0)) return 0; - - mDownloadStream.write(static_cast(buffer), size); - if(mDownloadStream.bad()) { - return 0; - } else { - return size; - } -} - - -int LLUpdateDownloader::Implementation::onProgress(curl_off_t downloadSize, curl_off_t bytesDownloaded) -{ - int downloadPercent = static_cast(100.0 * ((double) bytesDownloaded / (double) downloadSize)); - if(downloadPercent > mDownloadPercent) { - mDownloadPercent = downloadPercent; - - LLSD event; - event["pump"] = LLUpdaterService::pumpName(); - LLSD payload; - payload["type"] = LLSD(LLUpdaterService::PROGRESS); - payload["download_size"] = (LLSD::Integer) downloadSize; - payload["bytes_downloaded"] = (LLSD::Integer) bytesDownloaded; - event["payload"] = payload; - LLEventPumps::instance().obtain("mainlooprepeater").post(event); - - LL_INFOS("UpdaterService") << "progress event " << payload << LL_ENDL; - } else { - ; // Keep events to a reasonalbe number. - } - - return 0; -} - - -void LLUpdateDownloader::Implementation::run(void) -{ - CURLcode code = curl_easy_perform(mCurl.get()); - mDownloadStream.close(); - if(code == CURLE_OK) - { - LLFile::remove(mDownloadRecordPath); - if(validateOrRemove(mDownloadData["path"])) - { - LL_INFOS("UpdaterService") << "download successful" << LL_ENDL; - mClient.downloadComplete(mDownloadData); - } - else - { - mClient.downloadError("failed hash check"); - } - } - else if(mCancelled && (code == CURLE_WRITE_ERROR)) - { - LL_INFOS("UpdaterService") << "download canceled by user" << LL_ENDL; - // Do not call back client. - } - else - { - LL_WARNS("UpdaterService") << "download failed with error '" << - curl_easy_strerror(code) << "'" << LL_ENDL; - LLFile::remove(mDownloadRecordPath); - if(mDownloadData.has("path")) - { - std::string filePath = mDownloadData["path"].asString(); - LL_INFOS("UpdaterService") << "removing " << filePath << LL_ENDL; - LLFile::remove(filePath); - } - mClient.downloadError("curl error"); - } - - if(mHeaderList) - { - curl_slist_free_all(mHeaderList); - mHeaderList = 0; - } -} - - -void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader) -{ - if(!mCurl) - { - mCurl = LLCore::LLHttp::createEasyHandle(); - } - else - { - curl_easy_reset(mCurl.get()); - } - - if(!mCurl) - { - throw DownloadError("failed to initialize curl"); - } - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOSIGNAL, true)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_FOLLOWLOCATION, true)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEFUNCTION, &write_function)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_WRITEDATA, this)); - if(processHeader) - { - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERFUNCTION, &header_function)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HEADERDATA, this)); - } - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPGET, true)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_URL, url.c_str())); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFOFUNCTION, &xferinfo_callback)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_XFERINFODATA, this)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_NOPROGRESS, 0)); - // if it's a required update set the bandwidth limit to 0 (unlimited) - curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit; - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_MAX_RECV_SPEED_LARGE, limit)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_CAINFO, gDirUtilp->getCAFile().c_str())); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYHOST, 2)); - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_SSL_VERIFYPEER, 1)); - - mDownloadPercent = 0; -} - - -void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte) -{ - LL_INFOS("UpdaterService") << "resuming download from " << mDownloadData["url"].asString() - << " at byte " << startByte << LL_ENDL; - - initializeCurlGet(mDownloadData["url"].asString(), false); - - // The header 'Range: bytes n-' will request the bytes remaining in the - // source begining with byte n and ending with the last byte. - boost::format rangeHeaderFormat("Range: bytes=%u-"); - rangeHeaderFormat % startByte; - mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str()); - if(mHeaderList == 0) - { - throw DownloadError("cannot add Range header"); - } - throwOnCurlError(curl_easy_setopt(mCurl.get(), CURLOPT_HTTPHEADER, mHeaderList)); - - mDownloadStream.open(mDownloadData["path"].asString().c_str(), - std::ios_base::out | std::ios_base::binary | std::ios_base::app); - start(); -} - - -void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash) -{ - mDownloadData["url"] = uri.asString(); - mDownloadData["hash"] = hash; - mDownloadData["current_version"] = ll_get_version(); - LLSD path = uri.pathArray(); - if(path.size() == 0) throw DownloadError("no file path"); - std::string fileName = path[path.size() - 1].asString(); - std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName); - mDownloadData["path"] = filePath; - - LL_INFOS("UpdaterService") << "downloading " << filePath - << " from " << uri.asString() << LL_ENDL; - LL_INFOS("UpdaterService") << "hash of file is " << hash << LL_ENDL; - - llofstream dataStream(mDownloadRecordPath.c_str()); - LLSDSerialize::toPrettyXML(mDownloadData, dataStream); - - mDownloadStream.open(filePath.c_str(), std::ios_base::out | std::ios_base::binary); - initializeCurlGet(uri.asString(), true); - start(); -} - - -void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code) -{ - if(code != CURLE_OK) { - const char * errorString = curl_easy_strerror(code); - if(errorString != 0) { - throw DownloadError(curl_easy_strerror(code)); - } else { - throw DownloadError("unknown curl error"); - } - } else { - ; // No op. - } -} - -bool LLUpdateDownloader::Implementation::validateOrRemove(const std::string& filePath) -{ - bool valid = validateDownload(filePath); - if (! valid) - { - LL_INFOS("UpdaterService") << "removing " << filePath << LL_ENDL; - LLFile::remove(filePath); - } - return valid; -} - -bool LLUpdateDownloader::Implementation::validateDownload(const std::string& filePath) -{ - llifstream fileStream(filePath.c_str(), std::ios_base::in | std::ios_base::binary); - if(!fileStream) - { - LL_INFOS("UpdaterService") << "can't open " << filePath << ", invalid" << LL_ENDL; - return false; - } - - std::string hash = mDownloadData["hash"].asString(); - if (! hash.empty()) - { - char digest[33]; - LLMD5(fileStream).hex_digest(digest); - if (hash == digest) - { - LL_INFOS("UpdaterService") << "verified hash " << hash - << " for downloaded " << filePath << LL_ENDL; - return true; - } - else - { - LL_WARNS("UpdaterService") << "download hash mismatch for " - << filePath << ": expected " << hash - << " but computed " << digest << LL_ENDL; - return false; - } - } - else - { - LL_INFOS("UpdaterService") << "no hash specified for " << filePath - << ", unverified" << LL_ENDL; - return true; // No hash check provided. - } -} diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h deleted file mode 100644 index f759988f12..0000000000 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @file llupdatedownloader.h - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_UPDATE_DOWNLOADER_H -#define LL_UPDATE_DOWNLOADER_H - - -#include -#include -#include "lluri.h" - - -// -// An asynchronous download service for fetching updates. -// -class LLUpdateDownloader -{ -public: - class Client; - class Implementation; - - // Returns the path to the download marker file containing details of the - // latest download. - static std::string downloadMarkerPath(void); - - LLUpdateDownloader(Client & client); - - // Cancel any in progress download; a no op if none is in progress. The - // client will not receive a complete or error callback. - void cancel(void); - - // Start a new download. - void download(LLURI const & uri, - std::string const & hash, - std::string const & updateChannel, - std::string const & updateVersion, - std::string const & info_url, - bool required=false); - - // Returns true if a download is in progress. - bool isDownloading(void); - - // Resume a partial download. - void resume(void); - - // Set a limit on the dowload rate. - void setBandwidthLimit(U64 bytesPerSecond); - -private: - boost::shared_ptr mImplementation; -}; - - -// -// An interface to be implemented by clients initiating a update download. -// -class LLUpdateDownloader::Client { -public: - - // The download has completed successfully. - // data is a map containing the following items: - // url - source (remote) location - // hash - the md5 sum that should match the installer file. - // path - destination (local) location - // required - boolean indicating if this is a required update. - // size - the size of the installer in bytes - virtual void downloadComplete(LLSD const & data) = 0; - - // The download failed. - virtual void downloadError(std::string const & message) = 0; -}; - - -#endif diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp deleted file mode 100644 index a0e2c0b362..0000000000 --- a/indra/viewer_components/updater/llupdateinstaller.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file llupdateinstaller.cpp - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include -#include "llapr.h" -#include "llprocess.h" -#include "llupdateinstaller.h" -#include "lldir.h" -#include "llsd.h" - -#if defined(LL_WINDOWS) -#pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!). -#endif -#include - - -namespace { - class RelocateError {}; - - - std::string copy_to_temp(std::string const & path) - { - std::string scriptFile = gDirUtilp->getBaseFileName(path); - std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile); - apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp); - if(status != APR_SUCCESS) throw RelocateError(); - - return newPath; - } -} - - -int ll_install_update(std::string const & script, - std::string const & updatePath, - bool required, - LLInstallScriptMode mode) -{ - std::string actualScriptPath; - switch(mode) { - case LL_COPY_INSTALL_SCRIPT_TO_TEMP: - try { - actualScriptPath = copy_to_temp(script); - } - catch (RelocateError &) { - return -1; - } - break; - case LL_RUN_INSTALL_SCRIPT_IN_PLACE: - actualScriptPath = script; - break; - default: - llassert(!"unpossible copy mode"); - } - - LL_INFOS("Updater") << "UpdateInstaller: installing " << updatePath << " using " << - actualScriptPath << LL_ENDL; - - LLProcess::Params params; - params.executable = actualScriptPath; - params.args.add(updatePath); - params.args.add(ll_install_failed_marker_path()); - params.args.add(boost::lexical_cast(required)); - params.autokill = false; - return LLProcess::create(params)? 0 : -1; -} - - -std::string const & ll_install_failed_marker_path(void) -{ - static std::string path; - if(path.empty()) { - path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeInstallFailed.marker"); - } - return path; -} diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h deleted file mode 100644 index fe5b1d19b5..0000000000 --- a/indra/viewer_components/updater/llupdateinstaller.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file llupdateinstaller.h - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_UPDATE_INSTALLER_H -#define LL_UPDATE_INSTALLER_H - - -#include - - -enum LLInstallScriptMode { - LL_RUN_INSTALL_SCRIPT_IN_PLACE, - LL_COPY_INSTALL_SCRIPT_TO_TEMP -}; - -// -// Launch the installation script. -// -// The updater will overwrite the current installation, so it is highly recommended -// that the current application terminate once this function is called. -// -int ll_install_update( - std::string const & script, // Script to execute. - std::string const & updatePath, // Path to update file. - bool required, // Is the update required. - LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp? - - -// -// Returns the path which points to the failed install marker file, should it -// exist. -// -std::string const & ll_install_failed_marker_path(void); - - -#endif diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp deleted file mode 100644 index 788955a1b2..0000000000 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ /dev/null @@ -1,760 +0,0 @@ -/** - * @file llupdaterservice.cpp - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llupdaterservice.h" - -#include "llupdatedownloader.h" -#include "llevents.h" -#include "lltimer.h" -#include "llupdatechecker.h" -#include "llupdateinstaller.h" - -#include -#include -#include "lldir.h" -#include "llsdserialize.h" -#include "llfile.h" -#include "llviewernetwork.h" - -#if LL_WINDOWS -#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally -#endif - -#if ! defined(LL_VIEWER_VERSION_MAJOR) \ - || ! defined(LL_VIEWER_VERSION_MINOR) \ - || ! defined(LL_VIEWER_VERSION_PATCH) \ - || ! defined(LL_VIEWER_VERSION_BUILD) -#error "Version information is undefined" -#endif - -namespace -{ - boost::weak_ptr gUpdater; - - const std::string UPDATE_MARKER_FILENAME("SecondLifeUpdateReady.xml"); - std::string update_marker_path() - { - return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - UPDATE_MARKER_FILENAME); - } - - std::string install_script_path(void) - { -#ifdef LL_WINDOWS - std::string scriptFile = "update_install.bat"; -#elif LL_DARWIN - std::string scriptFile = "update_install.py"; -#else - std::string scriptFile = "update_install"; -#endif - return gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, scriptFile); - } - - LLInstallScriptMode install_script_mode(void) - { -#ifdef LL_WINDOWS - return LL_COPY_INSTALL_SCRIPT_TO_TEMP; -#else - // This is important on Mac because update_install.py looks at its own - // script pathname to discover the viewer app bundle to update. - return LL_RUN_INSTALL_SCRIPT_IN_PLACE; -#endif - }; - -} - -class LLUpdaterServiceImpl : - public LLUpdateChecker::Client, - public LLUpdateDownloader::Client -{ - static const std::string sListenerName; - - std::string mProtocolVersion; - std::string mChannel; - std::string mVersion; - std::string mPlatform; - std::string mPlatformVersion; - unsigned char mUniqueId[MD5HEX_STR_SIZE]; - bool mWillingToTest; - - unsigned int mCheckPeriod; - bool mIsChecking; - bool mIsDownloading; - - LLUpdateChecker mUpdateChecker; - LLUpdateDownloader mUpdateDownloader; - LLTimer mTimer; - - LLUpdaterService::app_exit_callback_t mAppExitCallback; - - LLUpdaterService::eUpdaterState mState; - - LOG_CLASS(LLUpdaterServiceImpl); - -public: - LLUpdaterServiceImpl(); - virtual ~LLUpdaterServiceImpl(); - - void initialize(const std::string& channel, - const std::string& version, - const std::string& platform, - const std::string& platform_version, - const unsigned char uniqueid[MD5HEX_STR_SIZE], - const bool& willing_to_test - ); - - void setCheckPeriod(unsigned int seconds); - void setBandwidthLimit(U64 bytesPerSecond); - - void startChecking(bool install_if_ready); - void stopChecking(); - bool forceCheck(); - bool isChecking(); - LLUpdaterService::eUpdaterState getState(); - - void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;} - std::string updatedVersion(void); - - bool checkForInstall(bool launchInstaller); // Test if a local install is ready. - bool checkForResume(); // Test for resumeable d/l. - - // LLUpdateChecker::Client: - virtual void error(std::string const & message); - - // A successful response was received from the viewer version manager - virtual void response(LLSD const & content); - - // LLUpdateDownloader::Client - void downloadComplete(LLSD const & data); - void downloadError(std::string const & message); - - bool onMainLoop(LLSD const & event); - -private: - std::string mNewChannel; - std::string mNewVersion; - - void restartTimer(unsigned int seconds); - void setState(LLUpdaterService::eUpdaterState state); - void stopTimer(); -}; - -const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl"; - -LLUpdaterServiceImpl::LLUpdaterServiceImpl() : - mIsChecking(false), - mIsDownloading(false), - mCheckPeriod(0), - mUpdateChecker(*this), - mUpdateDownloader(*this), - mState(LLUpdaterService::INITIAL) -{ -} - -LLUpdaterServiceImpl::~LLUpdaterServiceImpl() -{ - LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL; - LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); -} - -void LLUpdaterServiceImpl::initialize(const std::string& channel, - const std::string& version, - const std::string& platform, - const std::string& platform_version, - const unsigned char uniqueid[MD5HEX_STR_SIZE], - const bool& willing_to_test) -{ - if(mIsChecking || mIsDownloading) - { - throw LLUpdaterService::UsageError("LLUpdaterService::initialize call " - "while updater is running."); - } - - mChannel = channel; - mVersion = version; - mPlatform = platform; - mPlatformVersion = platform_version; - memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE); - mWillingToTest = willing_to_test; - LL_DEBUGS("UpdaterService") - << "\n channel: " << mChannel - << "\n version: " << mVersion - << "\n uniqueid: " << mUniqueId - << "\n willing: " << ( mWillingToTest ? "testok" : "testno" ) - << LL_ENDL; -} - -void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds) -{ - mCheckPeriod = seconds; -} - -void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond) -{ - mUpdateDownloader.setBandwidthLimit(bytesPerSecond); -} - -void LLUpdaterServiceImpl::startChecking(bool install_if_ready) -{ - if(mChannel.empty() || mVersion.empty()) - { - throw LLUpdaterService::UsageError("Set params before call to " - "LLUpdaterService::startCheck()."); - } - - mIsChecking = true; - - // Check to see if an install is ready. - bool has_install = checkForInstall(install_if_ready); - if(!has_install) - { - checkForResume(); // will set mIsDownloading to true if resuming - - if(!mIsDownloading) - { - setState(LLUpdaterService::CHECKING_FOR_UPDATE); - - // Checking can only occur during the mainloop. - // reset the timer to 0 so that the next mainloop event - // triggers a check; - restartTimer(0); - } - else - { - setState(LLUpdaterService::DOWNLOADING); - } - } -} - -void LLUpdaterServiceImpl::stopChecking() -{ - if(mIsChecking) - { - mIsChecking = false; - stopTimer(); - } - - if(mIsDownloading) - { - mUpdateDownloader.cancel(); - mIsDownloading = false; - } - - setState(LLUpdaterService::TERMINAL); -} - -bool LLUpdaterServiceImpl::forceCheck() -{ - if (!mIsDownloading && getState() != LLUpdaterService::CHECKING_FOR_UPDATE) - { - if (mIsChecking) - { - // Service is running, just reset the timer - if (mTimer.getStarted()) - { - mTimer.setTimerExpirySec(0); - setState(LLUpdaterService::CHECKING_FOR_UPDATE); - return true; - } - } - else if (!mChannel.empty() && !mVersion.empty()) - { - // one time check - bool has_install = checkForInstall(false); - if (!has_install) - { - std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL(); - if (!query_url.empty()) - { - setState(LLUpdaterService::CHECKING_FOR_UPDATE); - mUpdateChecker.checkVersion(query_url, mChannel, mVersion, - mPlatform, mPlatformVersion, mUniqueId, - mWillingToTest); - return true; - } - else - { - LL_WARNS("UpdaterService") - << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid() << LL_ENDL; - } - } - } - } - return false; -} - -bool LLUpdaterServiceImpl::isChecking() -{ - return mIsChecking; -} - -LLUpdaterService::eUpdaterState LLUpdaterServiceImpl::getState() -{ - return mState; -} - -std::string LLUpdaterServiceImpl::updatedVersion(void) -{ - return mNewVersion; -} - -bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller) -{ - bool foundInstall = false; // return true if install is found. - - llifstream update_marker(update_marker_path().c_str(), - std::ios::in | std::ios::binary); - - if(update_marker.is_open()) - { - // Found an update info - now lets see if its valid. - LLSD update_info; - LLSDSerialize::fromXMLDocument(update_info, update_marker); - update_marker.close(); - - // Get the path to the installer file. - std::string path(update_info.get("path")); - std::string downloader_version(update_info["current_version"]); - if (downloader_version != ll_get_version()) - { - // This viewer is not the same version as the one that downloaded - // the update. Do not install this update. - LL_INFOS("UpdaterService") << "ignoring update downloaded by " - << "different viewer version " - << downloader_version << LL_ENDL; - if (! path.empty()) - { - LL_INFOS("UpdaterService") << "removing " << path << LL_ENDL; - LLFile::remove(path); - LLFile::remove(update_marker_path()); - } - - foundInstall = false; - } - else if (path.empty()) - { - LL_WARNS("UpdaterService") << "Marker file " << update_marker_path() - << " 'path' entry empty, ignoring" << LL_ENDL; - foundInstall = false; - } - else if (! LLFile::isfile(path)) - { - LL_WARNS("UpdaterService") << "Nonexistent installer " << path - << ", ignoring" << LL_ENDL; - foundInstall = false; - } - else - { - if(launchInstaller) - { - setState(LLUpdaterService::INSTALLING); - - LLFile::remove(update_marker_path()); - - int result = ll_install_update(install_script_path(), - path, - update_info["required"].asBoolean(), - install_script_mode()); - - if((result == 0) && mAppExitCallback) - { - mAppExitCallback(); - } - else if(result != 0) - { - LL_WARNS("UpdaterService") << "failed to run update install script" << LL_ENDL; - } - else - { - ; // No op. - } - } - - foundInstall = true; - } - } - return foundInstall; -} - -bool LLUpdaterServiceImpl::checkForResume() -{ - bool result = false; - std::string download_marker_path = mUpdateDownloader.downloadMarkerPath(); - if(LLFile::isfile(download_marker_path)) - { - llifstream download_marker_stream(download_marker_path.c_str(), - std::ios::in | std::ios::binary); - if(download_marker_stream.is_open()) - { - LLSD download_info; - LLSDSerialize::fromXMLDocument(download_info, download_marker_stream); - download_marker_stream.close(); - std::string downloader_version(download_info["current_version"]); - if (downloader_version == ll_get_version()) - { - mIsDownloading = true; - mNewVersion = download_info["update_version"].asString(); - mNewChannel = download_info["update_channel"].asString(); - mUpdateDownloader.resume(); - result = true; - } - else - { - // The viewer that started this download is not the same as this viewer; ignore. - LL_INFOS("UpdaterService") << "ignoring partial download " - << "from different viewer version " - << downloader_version << LL_ENDL; - std::string path = download_info["path"].asString(); - if(!path.empty()) - { - LL_INFOS("UpdaterService") << "removing " << path << LL_ENDL; - LLFile::remove(path); - } - LLFile::remove(download_marker_path); - } - } - } - return result; -} - -void LLUpdaterServiceImpl::error(std::string const & message) -{ - setState(LLUpdaterService::TEMPORARY_ERROR); - if(mIsChecking) - { - restartTimer(mCheckPeriod); - } -} - -// A successful response was received from the viewer version manager -void LLUpdaterServiceImpl::response(LLSD const & content) -{ - if(!content.asBoolean()) // an empty response means "no update" - { - LL_INFOS("UpdaterService") << "up to date" << LL_ENDL; - if(mIsChecking) - { - restartTimer(mCheckPeriod); - } - - setState(LLUpdaterService::UP_TO_DATE); - } - else if ( content.isMap() && content.has("url") ) - { - // there is an update available... - stopTimer(); - mNewChannel = content["channel"].asString(); - if (mNewChannel.empty()) - { - LL_INFOS("UpdaterService") << "no channel supplied, assuming current channel" << LL_ENDL; - mNewChannel = mChannel; - } - mNewVersion = content["version"].asString(); - mIsDownloading = true; - setState(LLUpdaterService::DOWNLOADING); - BOOL required = content["required"].asBoolean(); - LLURI url(content["url"].asString()); - std::string more_info = content["more_info"].asString(); - LL_DEBUGS("UpdaterService") - << "Starting download of " - << ( required ? "required" : "optional" ) << " update" - << " to channel '" << mNewChannel << "' version " << mNewVersion - << " more info '" << more_info << "'" - << LL_ENDL; - mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required); - } - else - { - LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in " - << mCheckPeriod << " seconds" << LL_ENDL; - setState(LLUpdaterService::TEMPORARY_ERROR); - if (mIsChecking) - { - restartTimer(mCheckPeriod); - } - } -} - -void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) -{ - mIsDownloading = false; - - // Save out the download data to the SecondLifeUpdateReady - // marker file. - llofstream update_marker(update_marker_path().c_str()); - LLSDSerialize::toPrettyXML(data, update_marker); - - LLSD event; - event["pump"] = LLUpdaterService::pumpName(); - LLSD payload; - payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE); - payload["required"] = data["required"]; - payload["version"] = mNewVersion; - payload["channel"] = mNewChannel; - payload["info_url"] = data["info_url"]; - event["payload"] = payload; - LL_DEBUGS("UpdaterService") - << "Download complete " - << ( data["required"].asBoolean() ? "required" : "optional" ) - << " channel " << mNewChannel - << " version " << mNewVersion - << " info " << data["info_url"].asString() - << LL_ENDL; - - LLEventPumps::instance().obtain("mainlooprepeater").post(event); - - setState(LLUpdaterService::TERMINAL); -} - -void LLUpdaterServiceImpl::downloadError(std::string const & message) -{ - LL_INFOS("UpdaterService") << "Error downloading: " << message << LL_ENDL; - - mIsDownloading = false; - - // Restart the timer on error - if(mIsChecking) - { - restartTimer(mCheckPeriod); - } - - LLSD event; - event["pump"] = LLUpdaterService::pumpName(); - LLSD payload; - payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_ERROR); - payload["message"] = message; - event["payload"] = payload; - LLEventPumps::instance().obtain("mainlooprepeater").post(event); - - setState(LLUpdaterService::FAILURE); -} - -void LLUpdaterServiceImpl::restartTimer(unsigned int seconds) -{ - LL_INFOS("UpdaterService") << "will check for update again in " << - seconds << " seconds" << LL_ENDL; - mTimer.start(); - mTimer.setTimerExpirySec((F32)seconds); - LLEventPumps::instance().obtain("mainloop").listen( - sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1)); -} - -void LLUpdaterServiceImpl::setState(LLUpdaterService::eUpdaterState state) -{ - if(state != mState) - { - mState = state; - - LLSD event; - event["pump"] = LLUpdaterService::pumpName(); - LLSD payload; - payload["type"] = LLSD(LLUpdaterService::STATE_CHANGE); - payload["state"] = state; - event["payload"] = payload; - LLEventPumps::instance().obtain("mainlooprepeater").post(event); - - LL_INFOS("UpdaterService") << "setting state to " << state << LL_ENDL; - } - else - { - ; // State unchanged; noop. - } -} - -void LLUpdaterServiceImpl::stopTimer() -{ - mTimer.stop(); - LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName); -} - -bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event) -{ - if(mTimer.getStarted() && mTimer.hasExpired()) - { - stopTimer(); - - // Check for failed install. - if(LLFile::isfile(ll_install_failed_marker_path())) - { - LL_DEBUGS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL; - int requiredValue = 0; - { - llifstream stream(ll_install_failed_marker_path().c_str()); - stream >> requiredValue; - if(stream.fail()) - { - requiredValue = 0; - } - } - // TODO: notify the user. - LL_WARNS("UpdaterService") << "last install attempt failed" << LL_ENDL;; - LLFile::remove(ll_install_failed_marker_path()); - - LLSD event; - event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR); - event["required"] = LLSD(requiredValue); - LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event); - - setState(LLUpdaterService::TERMINAL); - } - else - { - std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL(); - if ( !query_url.empty() ) - { - mUpdateChecker.checkVersion(query_url, mChannel, mVersion, - mPlatform, mPlatformVersion, mUniqueId, - mWillingToTest); - setState(LLUpdaterService::CHECKING_FOR_UPDATE); - } - else - { - LL_WARNS("UpdaterService") - << "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid() - << "' will check again in " << mCheckPeriod << " seconds" - << LL_ENDL; - // Because the grid can be changed after the viewer is started (when the first check takes place) - // but before the user logs in, the next check may be on a different grid, so set the retry timer - // even though this check did not happen. The default time is once an hour, and if we're not - // doing the check anyway the performance impact is completely insignificant. - restartTimer(mCheckPeriod); - } - } - } - else - { - // Keep on waiting... - } - - return false; -} - - -//----------------------------------------------------------------------- -// Facade interface - -std::string const & LLUpdaterService::pumpName(void) -{ - static std::string name("updater_service"); - return name; -} - -bool LLUpdaterService::updateReadyToInstall(void) -{ - return LLFile::isfile(update_marker_path()); -} - -LLUpdaterService::LLUpdaterService() -{ - if(gUpdater.expired()) - { - mImpl = - boost::shared_ptr(new LLUpdaterServiceImpl()); - gUpdater = mImpl; - } - else - { - mImpl = gUpdater.lock(); - } -} - -LLUpdaterService::~LLUpdaterService() -{ -} - -void LLUpdaterService::initialize(const std::string& channel, - const std::string& version, - const std::string& platform, - const std::string& platform_version, - const unsigned char uniqueid[MD5HEX_STR_SIZE], - const bool& willing_to_test -) -{ - mImpl->initialize(channel, version, platform, platform_version, uniqueid, willing_to_test); -} - -void LLUpdaterService::setCheckPeriod(unsigned int seconds) -{ - mImpl->setCheckPeriod(seconds); -} - -void LLUpdaterService::setBandwidthLimit(U64 bytesPerSecond) -{ - mImpl->setBandwidthLimit(bytesPerSecond); -} - -void LLUpdaterService::startChecking(bool install_if_ready) -{ - mImpl->startChecking(install_if_ready); -} - -void LLUpdaterService::stopChecking() -{ - mImpl->stopChecking(); -} - -bool LLUpdaterService::forceCheck() -{ - return mImpl->forceCheck(); -} - -bool LLUpdaterService::isChecking() -{ - return mImpl->isChecking(); -} - -LLUpdaterService::eUpdaterState LLUpdaterService::getState() -{ - return mImpl->getState(); -} - -void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) -{ - return mImpl->setAppExitCallback(aecb); -} - -std::string LLUpdaterService::updatedVersion(void) -{ - return mImpl->updatedVersion(); -} - - -std::string const & ll_get_version(void) { - static std::string version(""); - - if (version.empty()) { - std::ostringstream stream; - stream << LL_VIEWER_VERSION_MAJOR << "." - << LL_VIEWER_VERSION_MINOR << "." - << LL_VIEWER_VERSION_PATCH << "." - << LL_VIEWER_VERSION_BUILD; - version = stream.str(); - } - - return version; -} - diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h deleted file mode 100644 index 95bbe1695c..0000000000 --- a/indra/viewer_components/updater/llupdaterservice.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file llupdaterservice.h - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_UPDATERSERVICE_H -#define LL_UPDATERSERVICE_H - -#include -#include -#include "llhasheduniqueid.h" - -class LLUpdaterServiceImpl; - -class LLUpdaterService -{ -public: - class UsageError: public std::runtime_error - { - public: - UsageError(const std::string& msg) : std::runtime_error(msg) {} - }; - - // Name of the event pump through which update events will be delivered. - static std::string const & pumpName(void); - - // Returns true if an update has been completely downloaded and is now ready to install. - static bool updateReadyToInstall(void); - - // Type codes for events posted by this service. Stored the event's 'type' element. - enum eUpdaterEvent { - INVALID, - DOWNLOAD_COMPLETE, - DOWNLOAD_ERROR, - INSTALL_ERROR, - PROGRESS, - STATE_CHANGE - }; - - enum eUpdaterState { - INITIAL, - CHECKING_FOR_UPDATE, - TEMPORARY_ERROR, - DOWNLOADING, - INSTALLING, - UP_TO_DATE, - TERMINAL, - FAILURE - }; - - LLUpdaterService(); - ~LLUpdaterService(); - - void initialize(const std::string& channel, - const std::string& version, - const std::string& platform, - const std::string& platform_version, - const unsigned char uniqueid[MD5HEX_STR_SIZE], - const bool& willing_to_test - ); - - void setCheckPeriod(unsigned int seconds); - void setBandwidthLimit(U64 bytesPerSecond); - - void startChecking(bool install_if_ready = false); - void stopChecking(); - bool forceCheck(); - bool isChecking(); - eUpdaterState getState(); - - typedef boost::function app_exit_callback_t; - template - void setAppExitCallback(F const &callable) - { - app_exit_callback_t aecb = callable; - setImplAppExitCallback(aecb); - } - - // If an update is or has been downloaded, this method will return the - // version string for that update. An empty string will be returned - // otherwise. - std::string updatedVersion(void); - -private: - boost::shared_ptr mImpl; - void setImplAppExitCallback(app_exit_callback_t aecb); -}; - -// Returns the full version as a string. -std::string const & ll_get_version(void); - -#endif // LL_UPDATERSERVICE_H 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 "$*" "$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 diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp deleted file mode 100644 index 759e41ef4c..0000000000 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @file llupdaterservice_test.cpp - * @brief Tests of llupdaterservice.cpp. - * - * $LicenseInfo:firstyear=2010&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// Precompiled header -#include "linden_common.h" -// associated header -#include "../llupdaterservice.h" -#include "../llupdatechecker.h" -#include "../llupdatedownloader.h" -#include "../llupdateinstaller.h" - -#include "../../../test/lltut.h" -//#define DEBUG_ON -#include "../../../test/debug.h" - -#include "llevents.h" -#include "lldir.h" - -/***************************************************************************** -* MOCK'd -*****************************************************************************/ -LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client) -{} -void LLUpdateChecker::checkVersion(std::string const & urlBase, - std::string const & channel, - std::string const & version, - std::string const & platform, - std::string const & platform_version, - unsigned char uniqueid[MD5HEX_STR_SIZE], - bool willing_to_test) -{} -LLUpdateDownloader::LLUpdateDownloader(Client & ) {} -void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, std::string const &, std::string const &, bool){} - -class LLDir_Mock : public LLDir -{ - void initAppDirs(const std::string &app_name, - const std::string& app_read_only_data_dir = "") {} - U32 countFilesInDir(const std::string &dirname, const std::string &mask) - { - return 0; - } - - void getRandomFileInDir(const std::string &dirname, - const std::string &mask, - std::string &fname) {} - std::string getCurPath() { return ""; } - bool fileExists(const std::string &filename) const { return false; } - std::string getLLPluginLauncher() { return ""; } - std::string getLLPluginFilename(std::string base_name) { return ""; } - -} gDirUtil; -LLDir* gDirUtilp = &gDirUtil; -LLDir::LLDir() {} -LLDir::~LLDir() {} -S32 LLDir::deleteFilesInDir(const std::string &dirname, - const std::string &mask) -{ return 0; } - -void LLDir::setChatLogsDir(const std::string &path){} -void LLDir::setPerAccountChatLogsDir(const std::string &username){} -void LLDir::setLindenUserDir(const std::string &username){} -void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language){} -std::string LLDir::getSkinFolder() const { return "default"; } -std::string LLDir::getLanguage() const { return "en"; } -bool LLDir::setCacheDir(const std::string &path){ return true; } -void LLDir::dumpCurrentDirectories() {} -void LLDir::updatePerAccountChatLogsDir() {} - -#include "llviewernetwork.h" -LLGridManager::LLGridManager() : - mGrid("test.grid.lindenlab.com"), - mIsInProductionGrid(false) -{ -} -std::string LLGridManager::getUpdateServiceURL() -{ - return "https://update.secondlife.com/update"; -} -LLGridManager::~LLGridManager() -{ -} - - -std::string LLDir::getExpandedFilename(ELLPath location, - const std::string &filename) const -{ - return ""; -} - -std::string LLUpdateDownloader::downloadMarkerPath(void) -{ - return ""; -} - -void LLUpdateDownloader::resume(void) {} -void LLUpdateDownloader::cancel(void) {} -void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {} - -int ll_install_update(std::string const &, std::string const &, bool, LLInstallScriptMode) -{ - return 0; -} - -std::string const & ll_install_failed_marker_path() -{ - static std::string wubba; - return wubba; -} - -/* -#pragma warning(disable: 4273) -llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename, - ios_base::openmode _Mode, - int _Prot) : - std::basic_istream >(NULL,true) -{} - -llus_mock_llifstream::~llus_mock_llifstream() {} -bool llus_mock_llifstream::is_open() const {return true;} -void llus_mock_llifstream::close() {} -*/ - -/***************************************************************************** -* TUT -*****************************************************************************/ -namespace tut -{ - struct llupdaterservice_data - { - llupdaterservice_data() : - pumps(LLEventPumps::instance()), - test_url("dummy_url"), - test_channel("dummy_channel"), - test_version("dummy_version") - {} - LLEventPumps& pumps; - std::string test_url; - std::string test_channel; - std::string test_version; - }; - - typedef test_group llupdaterservice_group; - typedef llupdaterservice_group::object llupdaterservice_object; - llupdaterservice_group llupdaterservicegrp("LLUpdaterService"); - - template<> template<> - void llupdaterservice_object::test<1>() - { - DEBUG; - LLUpdaterService updater; - bool got_usage_error = false; - try - { - updater.startChecking(); - } - catch(LLUpdaterService::UsageError) - { - got_usage_error = true; - } - ensure("Caught start before params", got_usage_error); - } - - template<> template<> - void llupdaterservice_object::test<2>() - { - DEBUG; - LLUpdaterService updater; - bool got_usage_error = false; - try - { - unsigned char id1[MD5HEX_STR_SIZE] = "11111111111111111111111111111111"; - updater.initialize(test_channel, test_version, "win", "1.2.3", id1, true); - updater.startChecking(); - unsigned char id2[MD5HEX_STR_SIZE] = "22222222222222222222222222222222"; - updater.initialize(test_channel, test_version, "win", "4.5.6", id2, true); - } - catch(LLUpdaterService::UsageError) - { - got_usage_error = true; - } - ensure("Caught params while running", got_usage_error); - } - - template<> template<> - void llupdaterservice_object::test<3>() - { - DEBUG; - LLUpdaterService updater; - unsigned char id[MD5HEX_STR_SIZE] = "33333333333333333333333333333333"; - updater.initialize(test_channel, test_version, "win", "7.8.9", id, true); - updater.startChecking(); - ensure(updater.isChecking()); - updater.stopChecking(); - ensure(!updater.isChecking()); - } -} From 01ee14c0fc71e2b84d1f489b9856f87b667ad521 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 19 Aug 2016 12:12:48 -0700 Subject: [PATCH 045/183] SL-323: put back mac addr hash --- indra/newview/CMakeLists.txt | 1 + indra/newview/lllogininstance.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 999165528a..7a0df8d207 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2300,6 +2300,7 @@ if (LL_TESTS) set_source_files_properties( lllogininstance.cpp + llhasheduniqueid.cpp PROPERTIES LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" ) diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index b9e9c12aec..374efa2986 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -192,11 +192,19 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // (re)initialize the request params with creds. LLSD request_params = user_credential->getLoginParams(); + unsigned char hashed_unique_id_string[MD5HEX_STR_SIZE]; + if ( ! llHashedUniqueID(hashed_unique_id_string) ) + { + + LL_WARNS() << "Not providing a unique id in request params" << LL_ENDL; + + } request_params["start"] = construct_start_string(); request_params["agree_to_tos"] = false; // Always false here. Set true in request_params["read_critical"] = false; // handleTOSResponse request_params["last_exec_event"] = mLastExecEvent; request_params["last_exec_duration"] = mLastExecDuration; + request_params["mac"] = (char*)hashed_unique_id_string; request_params["version"] = LLVersionInfo::getVersion(); request_params["channel"] = LLVersionInfo::getChannel(); request_params["platform"] = mPlatform; From 2699ef356aae4f31246ab6ccb6613676a2e2cc0f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 22 Aug 2016 09:36:00 -0700 Subject: [PATCH 046/183] SL-323: ripping out old code completed --- indra/newview/CMakeLists.txt | 1 - indra/newview/tests/lllogininstance_test.cpp | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7a0df8d207..999165528a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2300,7 +2300,6 @@ if (LL_TESTS) set_source_files_properties( lllogininstance.cpp - llhasheduniqueid.cpp PROPERTIES LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" ) diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index b43aaeaa33..aa05897c0b 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -186,6 +186,13 @@ void LLUIColorTable::saveUserSettings(void)const {} #include "../llversioninfo.h" const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; } const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; } +const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null + +bool llHashedUniqueID(unsigned char* id) +{ + memcpy( id, "66666666666666666666666666666666", MD5HEX_STR_SIZE ); + return true; +} //----------------------------------------------------------------------------- #include "../llappviewer.h" From 069c938eb6ebfd77f6a415207331c66f72270e5f Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC" Date: Tue, 28 Feb 2017 22:35:01 +0000 Subject: [PATCH 047/183] pull from rev d22beb597e52ecbf1c98f25d4489ea0425eda4b0 of sl-321 --- .../manager/InstallerError.py | 49 - .../manager/InstallerUserMessage.py | 316 ----- indra/viewer_components/manager/SL_Launcher | 199 --- .../viewer_components/manager/apply_update.py | 277 ---- .../manager/download_update.py | 105 -- .../manager/tests/data/settings.xml | 1184 ----------------- .../manager/tests/summary.json | 1 - .../manager/tests/test_InstallerError.py | 45 - .../test_check_for_completed_download.py | 59 - .../tests/test_convert_version_file_style.py | 61 - .../manager/tests/test_get_filename.py | 66 - .../manager/tests/test_get_log_file_handle.py | 68 - .../manager/tests/test_get_parent_path.py | 83 -- .../manager/tests/test_get_platform_key.py | 44 - .../manager/tests/test_get_settings.py | 87 -- .../manager/tests/test_make_VVM_UUID_hash.py | 47 - .../manager/tests/test_make_download_dir.py | 47 - .../manager/tests/test_query_vvm.py | 73 - .../manager/tests/test_silent_write.py | 49 - .../manager/tests/test_summary.py | 45 - .../manager/tests/with_setup_args.py | 68 - .../manager/update_manager.py | 547 -------- 22 files changed, 3520 deletions(-) delete mode 100644 indra/viewer_components/manager/InstallerError.py delete mode 100644 indra/viewer_components/manager/InstallerUserMessage.py delete mode 100755 indra/viewer_components/manager/SL_Launcher delete mode 100755 indra/viewer_components/manager/apply_update.py delete mode 100755 indra/viewer_components/manager/download_update.py delete mode 100644 indra/viewer_components/manager/tests/data/settings.xml delete mode 100644 indra/viewer_components/manager/tests/summary.json delete mode 100644 indra/viewer_components/manager/tests/test_InstallerError.py delete mode 100644 indra/viewer_components/manager/tests/test_check_for_completed_download.py delete mode 100644 indra/viewer_components/manager/tests/test_convert_version_file_style.py delete mode 100644 indra/viewer_components/manager/tests/test_get_filename.py delete mode 100644 indra/viewer_components/manager/tests/test_get_log_file_handle.py delete mode 100644 indra/viewer_components/manager/tests/test_get_parent_path.py delete mode 100644 indra/viewer_components/manager/tests/test_get_platform_key.py delete mode 100644 indra/viewer_components/manager/tests/test_get_settings.py delete mode 100644 indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py delete mode 100644 indra/viewer_components/manager/tests/test_make_download_dir.py delete mode 100644 indra/viewer_components/manager/tests/test_query_vvm.py delete mode 100644 indra/viewer_components/manager/tests/test_silent_write.py delete mode 100644 indra/viewer_components/manager/tests/test_summary.py delete mode 100644 indra/viewer_components/manager/tests/with_setup_args.py delete mode 100755 indra/viewer_components/manager/update_manager.py diff --git a/indra/viewer_components/manager/InstallerError.py b/indra/viewer_components/manager/InstallerError.py deleted file mode 100644 index 3b199ea231..0000000000 --- a/indra/viewer_components/manager/InstallerError.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - -"""\ -@file InstallerError.py -@author coyot -@date 2016-05-16 -@brief custom exception class for VMP - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -""" -usage: - ->>> import InstallerError ->>> import os ->>> try: -... os.mkdir('/tmp') -... except OSError, oe: -... ie = InstallerError.InstallerError(oe, "foo") -... raise ie - -Traceback (most recent call last): - File "", line 5, in -InstallerError.InstallerError: [Errno [Errno 17] File exists: '/tmp'] foo -""" - -class InstallerError(OSError): - def __init___(self, message): - Exception.__init__(self, message) diff --git a/indra/viewer_components/manager/InstallerUserMessage.py b/indra/viewer_components/manager/InstallerUserMessage.py deleted file mode 100644 index 8002399659..0000000000 --- a/indra/viewer_components/manager/InstallerUserMessage.py +++ /dev/null @@ -1,316 +0,0 @@ -#!/usr/bin/env python - -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $LicenseInfo:firstyear=2013&license=viewerlgpl$ -# Copyright (c) 2013, Linden Research, Inc. -# $/LicenseInfo$ - -""" -@file InstallerUserMessage.py -@author coyot -@date 2016-05-16 -""" - -""" -This does everything the old updater/scripts/darwin/messageframe.py script did and some more bits. -Pushed up the manager directory to be multiplatform. -""" - -import os -import Queue -import threading -import time -import Tkinter as tk -import ttk - - -class InstallerUserMessage(tk.Tk): - #Goals for this class: - # Provide a uniform look and feel - # Provide an easy to use convenience class for other scripts - # Provide windows that automatically disappear when done (for differing notions of done) - # Provide a progress bar that isn't a glorified spinner, but based on download progress - #Non-goals: - # No claim to threadsafety is made or warranted. Your mileage may vary. - # Please consult a doctor if you experience thread pain. - - #Linden standard green color, from Marketing - linden_green = "#487A7B" - - def __init__(self, text="", title="", width=500, height=200, wraplength = 400, icon_name = None, icon_path = None): - tk.Tk.__init__(self) - self.grid() - self.title(title) - self.choice = tk.BooleanVar() - self.config(background = 'black') - # background="..." doesn't work on MacOS for radiobuttons or progress bars - # http://tinyurl.com/tkmacbuttons - ttk.Style().configure('Linden.TLabel', foreground=InstallerUserMessage.linden_green, background='black') - ttk.Style().configure('Linden.TButton', foreground=InstallerUserMessage.linden_green, background='black') - ttk.Style().configure("black.Horizontal.TProgressbar", foreground=InstallerUserMessage.linden_green, background='black') - - #This bit of configuration centers the window on the screen - # The constants below are to adjust for typical overhead from the - # frame borders. - self.xp = (self.winfo_screenwidth() / 2) - (width / 2) - 8 - self.yp = (self.winfo_screenheight() / 2) - (height / 2) - 20 - self.geometry('{0}x{1}+{2}+{3}'.format(width, height, self.xp, self.yp)) - - #find a few things - self.script_dir = os.path.dirname(os.path.realpath(__file__)) - self.contents_dir = os.path.dirname(self.script_dir) - self.icon_dir = os.path.abspath(os.path.join(self.contents_dir, 'Resources/vmp_icons')) - - #finds the icon and creates the widget - self.find_icon(icon_path, icon_name) - - #defines what to do when window is closed - self.protocol("WM_DELETE_WINDOW", self._delete_window) - - #callback id - self.id = -1 - - def _delete_window(self): - #capture and discard all destroy events before the choice is set - if not ((self.choice == None) or (self.choice == "")): - try: - #initialized value. If we have an outstanding callback, kill it before killing ourselves - if self.id != -1: - self.after_cancel(self.id) - self.destroy() - except: - #tk may try to destroy the same object twice - pass - - def set_colors(self, widget): - # #487A7B is "Linden Green" - widget.config(foreground = InstallerUserMessage.linden_green) - widget.config(background='black') - - def find_icon(self, icon_path = None, icon_name = None): - #we do this in each message, let's do it just once instead. - if not icon_path: - icon_path = self.icon_dir - icon_path = os.path.join(icon_path, icon_name) - print icon_path - if os.path.exists(icon_path): - icon = tk.PhotoImage(file=icon_path) - self.image_label = tk.Label(image = icon) - self.image_label.image = icon - else: - #default to text if image not available - self.image_label = tk.Label(text = "Second Life") - - def auto_resize(self, row_count = 0, column_count = 0, heavy_row = None, heavy_column = None): - #auto resize window to fit all rows and columns - #"heavy" gets extra weight - for x in range(column_count): - if x == heavy_column: - self.columnconfigure(x, weight = 2) - else: - self.columnconfigure(x, weight=1) - - for y in range(row_count): - if y == heavy_row: - self.rowconfigure(y, weight = 2) - else: - self.rowconfigure(x, weight=1) - - def basic_message(self, message): - #message: text to be displayed - #icon_path: directory holding the icon, defaults to icons subdir of script dir - #icon_name: filename of icon to be displayed - self.choice.set(True) - self.text_label = tk.Label(text = message) - self.set_colors(self.text_label) - self.set_colors(self.image_label) - #pad, direction and weight are all experimentally derived by retrying various values - self.image_label.grid(row = 1, column = 1, sticky = 'W') - self.text_label.grid(row = 1, column = 2, sticky = 'W', padx =100) - self.auto_resize(row_count = 1, column_count = 2) - self.mainloop() - - def binary_choice_message(self, message, true = 'Yes', false = 'No'): - #true: first option, returns True - #false: second option, returns False - #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice - #usage: - # frame = InstallerUserMessage.InstallerUserMessage( ... ) - # frame = frame.binary_choice_message( ... ) - # (wait for user to click) - # value = frame.choice.get() - - self.text_label = tk.Label(text = message) - #command registers the callback to the method named. We want the frame to go away once clicked. - #button 1 returns True/1, button 2 returns False/0 - self.button_one = ttk.Radiobutton(text = true, variable = self.choice, value = True, - command = self._delete_window, style = 'Linden.TButton') - self.button_two = ttk.Radiobutton(text = false, variable = self.choice, value = False, - command = self._delete_window, style = 'Linden.TButton') - self.set_colors(self.text_label) - self.set_colors(self.image_label) - #pad, direction and weight are all experimentally derived by retrying various values - self.image_label.grid(row = 1, column = 1, rowspan = 3, sticky = 'W') - self.text_label.grid(row = 1, column = 2, rowspan = 3) - self.button_one.grid(row = 1, column = 3, sticky = 'W', pady = 40) - self.button_two.grid(row = 2, column = 3, sticky = 'W', pady = 0) - self.auto_resize(row_count = 2, column_count = 3, heavy_column = 3) - #self.button_two.deselect() - self.update() - self.mainloop() - - def trinary_choice_message(self, message, one = 1, two = 2, three = 3): - #one: first option, returns 1 - #two: second option, returns 2 - #three: third option, returns 3 - #usage is kind of opaque and relies on this object persisting after the window destruction to pass back choice - #usage: - # frame = InstallerUserMessage.InstallerUserMessage( ... ) - # frame = frame.binary_choice_message( ... ) - # (wait for user to click) - # value = frame.choice.get() - - self.text_label = tk.Label(text = message) - #command registers the callback to the method named. We want the frame to go away once clicked. - self.button_one = ttk.Radiobutton(text = one, variable = self.choice, value = 1, - command = self._delete_window, style = 'Linden.TButton') - self.button_two = ttk.Radiobutton(text = two, variable = self.choice, value = 2, - command = self._delete_window, style = 'Linden.TButton') - self.button_three = ttk.Radiobutton(text = three, variable = self.choice, value = 3, - command = self._delete_window, style = 'Linden.TButton') - self.set_colors(self.text_label) - self.set_colors(self.image_label) - #pad, direction and weight are all experimentally derived by retrying various values - self.image_label.grid(row = 1, column = 1, rowspan = 4, sticky = 'W') - self.text_label.grid(row = 1, column = 2, rowspan = 4, padx = 5) - self.button_one.grid(row = 1, column = 3, sticky = 'W', pady = 5) - self.button_two.grid(row = 2, column = 3, sticky = 'W', pady = 5) - self.button_three.grid(row = 3, column = 3, sticky = 'W', pady = 5) - self.auto_resize(row_count = 3, column_count = 3, heavy_column = 3) - #self.button_two.deselect() - self.update() - self.mainloop() - - def progress_bar(self, message = None, size = 0, interval = 100, pb_queue = None): - #Best effort attempt at a real progress bar - # This is what Tk calls "determinate mode" rather than "indeterminate mode" - #size: denominator of percent complete - #interval: frequency, in ms, of how often to poll the file for progress - #pb_queue: queue object used to send updates to the bar - self.text_label = tk.Label(text = message) - self.set_colors(self.text_label) - self.set_colors(self.image_label) - self.image_label.grid(row = 1, column = 1, sticky = 'NSEW') - self.text_label.grid(row = 2, column = 1, sticky = 'NSEW') - self.progress = ttk.Progressbar(self, style = 'black.Horizontal.TProgressbar', orient="horizontal", length=100, mode="determinate") - self.progress.grid(row = 3, column = 1, sticky = 'NSEW') - self.value = 0 - self.progress["maximum"] = size - self.auto_resize(row_count = 1, column_count = 3) - self.queue = pb_queue - self.check_scheduler() - - def check_scheduler(self): - try: - if self.value < self.progress["maximum"]: - self.check_queue() - self.id = self.after(100, self.check_scheduler) - else: - #prevent a race condition between polling and the widget destruction - self.after_cancel(self.id) - except tk.TclError: - #we're already dead, just die quietly - pass - - def check_queue(self): - while self.queue.qsize(): - try: - msg = float(self.queue.get(0)) - #custom signal, time to tear down - if msg == -1: - self.choice.set(True) - self.destroy() - else: - self.progress.step(msg) - self.value = msg - except Queue.Empty: - #nothing to do - return - -class ThreadedClient(threading.Thread): - #for test only, not part of the functional code - def __init__(self, queue): - threading.Thread.__init__(self) - self.queue = queue - - def run(self): - for x in range(1, 90, 10): - time.sleep(1) - print "run " + str(x) - self.queue.put(10) - #tkk progress bars wrap at exactly 100 percent, look full at 99% - print "leftovers" - self.queue.put(9) - time.sleep(5) - # -1 is a custom signal to the progress_bar to quit - self.queue.put(-1) - -if __name__ == "__main__": - #When run as a script, just test the InstallUserMessage. - #To proceed with the test, close the first window, select on the second and fourth. The third will close by itself. - import sys - import tempfile - - def set_and_check(frame, value): - print "value: " + str(value) - frame.progress.step(value) - if frame.progress["value"] < frame.progress["maximum"]: - print "In Progress" - else: - print "Over now" - - #basic message window test - frame2 = InstallerUserMessage(text = "Something in the way she moves....", title = "Beatles Quotes for 100", icon_name="head-sl-logo.gif") - print frame2.contents_dir - print frame2.icon_dir - frame2.basic_message(message = "...attracts me like no other.") - print "Destroyed!" - sys.stdout.flush() - - #binary choice test. User destroys window when they select. - frame3 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") - frame3.binary_choice_message(message = "And all I have to do is think of her.", - true = "Don't want to leave her now", false = 'You know I believe and how') - print frame3.choice.get() - sys.stdout.flush() - - #progress bar - queue = Queue.Queue() - thread = ThreadedClient(queue) - thread.start() - print "thread started" - - frame4 = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 300", icon_name="head-sl-logo.gif") - frame4.progress_bar(message = "You're asking me will my love grow", size = 100, pb_queue = queue) - print "frame defined" - frame4.mainloop() - - #trinary choice test. User destroys window when they select. - frame3a = InstallerUserMessage(text = "Something in the way she knows....", title = "Beatles Quotes for 200", icon_name="head-sl-logo.gif") - frame3a.trinary_choice_message(message = "And all I have to do is think of her.", - one = "Don't want to leave her now", two = 'You know I believe and how', three = 'John is Dead') - print frame3a.choice.get() - sys.stdout.flush() diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher deleted file mode 100755 index 257543187c..0000000000 --- a/indra/viewer_components/manager/SL_Launcher +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python - -# $LicenseInfo:firstyear=2016&license=internal$ -# -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ -# Copyright (c) 2013, Linden Research, Inc. - -import os -import sys - -#module globals -log_file_handle = None -cwd = os.path.dirname(os.path.realpath(__file__)) -sys.path.insert(0, os.path.join(cwd, 'llbase')) - -import argparse -import collections -import InstallerUserMessage -#NOTA BENE: -# For POSIX platforms, llsd.py will be imported from the same directory. -# For Windows, llsd.py will be compiled into the executable by pyinstaller -try: - from llbase import llsd -except: - #if Windows, this is expected, if not, we're dead - if os.name == 'nt': - pass -import platform -import subprocess -import update_manager - - -def silent_write(log_file_handle, text): - #if we have a log file, write. If not, do nothing. - #this is so we don't have to keep trapping for an exception with a None handle - #oh and because it is best effort, it is also a holey_write ;) - if (log_file_handle): - #prepend text for easy grepping - timestamp = datetime.utcnow().strftime("%Y-%m-%D %H:%M:%S") - log_file_handle.write(timestamp + " LAUNCHER: " + text + "\n") - -def get_cmd_line(): - platform_name = platform.system() - #find the parent of the logs and user_settings directories - if (platform_name == 'Darwin'): - settings_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'Resources/app_settings/cmd_line.xml') - elif (platform_name == 'Linux'): - settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') - #using list format of join is important here because the Windows pathsep in a string escapes the next char - elif (platform_name == 'Windows'): - settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml') - else: - settings_file = None - - try: - cmd_line = llsd.parse((open(settings_file)).read()) - except: - silent_write(log_file_handle, "Could not parse settings file %s" % settings_file) - cmd_line = None - - return cmd_line - -def get_settings(): - #return the settings file parsed into a dict - try: - settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) - settings = llsd.parse((open(settings_file)).read()) - except llsd.LLSDParseError as lpe: - silent_write(log_file_handle, "Could not parse settings file %s" % lpe) - return None - return settings - -def capture_vmp_args(arg_list = None, cmd_line = None): - #expected input format: arg_list = ['--set', 'foo', 'bar', '-X', '-Y', 'qux'] - #take a copy of the viewer parameters that are of interest to VMP. - #the regex for a parameter is -- {opt1} {opt2} - cli_overrides = {} - cmd_line = get_cmd_line() - - vmp_params = {'--channel':'channel', '--settings':'settings', '--update-service':'update-service', '--set':'set'} - #the settings set with --set. All such settings have only one argument. - vmp_setters = ('UpdaterMaximumBandwidth', 'UpdaterServiceCheckPeriod', 'UpdaterServicePath', 'UpdaterServiceSetting', 'UpdaterServiceURL', 'UpdaterWillingToTest') - - #Here turn the list into a queue, popping off the left as we go. Note that deque() makes a copy by value, not by reference - #Because of the complexity introduced by the uncertainty of how many options a parameter can take, this is far less complicated code than the more - #pythonic (x,y) = since we will sometimes have (x), sometimes (x,y) and sometimes (x,y,z) - #also, because the pop is destructive, we prevent ourselves from iterating back over list elements that iterator methods would peek ahead at - vmp_queue = collections.deque(arg_list) - while (len(vmp_queue)): - param = vmp_queue.popleft() - #if it is not one of ours, pop through args until we get to the next parameter - if param in vmp_params.keys(): - if param == '--set': - setting_name = vmp_queue.popleft() - setting_value = vmp_queue.popleft() - if setting_name in vmp_setters: - cli_overrides[vmp_params[param]] = (setting_name, setting_value) - else: - #find out how many args this parameter has - no_dashes = vmp_params[param] - count = cmd_line[no_dashes]['count'] - param_args = [] - if count > 0: - for argh in range(0,count): - param_args.append(vmp_queue.popleft()) - #the parameter name is the key, the (possibly empty) list of args is the value - cli_overrides[vmp_params[param]] = param_args - - #to prevent KeyErrors on missing keys, set the remainder to None - for key in vmp_params: - if key != '--set': - try: - cli_overrides[key] - except KeyError: - cli_overrides[key] = None - else: - cli_overrides["--set"] = {} - for arg in vmp_setters: - try: - cli_overrides[key][arg] - except KeyError: - cli_overrides[key][arg] = None - return cli_overrides - -#main entry point -#this and a few other update manager methods really should be refactored into a util lib -parent_dir = update_manager.get_parent_path(update_manager.get_platform_key()) -log_file_handle = update_manager.get_log_file_handle(parent_dir, 'launcher.log') - -executable_name = "" -if sys.platform.startswith('darwin'): - executable_name = "Second Life" -elif sys.platform.startswith("win") or sys.platform.startswith("cyg"): - if os.path.isfile(os.path.join(cwd,"SecondLifeViewer.exe")): - executable_name = "SecondLifeViewer.exe" - elif os.path.isfile(os.path.join(cwd,"SecondLifeTest.exe")): - executable_name = "SecondLifeTest.exe" - else: - sys.exit("Can't find Windows viewer binary") -elif sys.platform.startswith("linux"): - executable_name = "secondlife" -else: - #SL doesn't run on VMS or punch cards - sys.exit("Unsupported platform") - -#find the viewer to be lauched -viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name) - -parser = argparse.ArgumentParser() -args = parser.parse_known_args(sys.argv) -#args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname -args_list_to_pass = args[1][1:] -vmp_args = capture_vmp_args(args_list_to_pass) -#make a copy by value, not by reference -command = list(args_list_to_pass) - -(success, state, condition) = update_manager.update_manager(vmp_args) -# From update_manager: -# (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) -# (False, 'download', version): we failed to download the new version -# (False, 'apply', version): we failed to apply the new version -# (True, None, None): No update found -# (True, 'in place', True): update applied in place -# (True, 'in place', path_to_new_launcher): Update applied by a new install to a new location -# (True, 'background', True): background download initiated -#These boil down three cases: -# Success is False, then pop up a message and launch the current viewer -# No update, update succeeded in place in foreground, or background update started: silently launch the current viewer channel -# Updated succeed to a different channel, launch that viewer and exit -if not success: - msg = 'Update failed in the %s process. Please check logs. Viewer will launch starting momentarily.' % state - update_manager.after_frame(msg) - command.insert(0,viewer_binary) - viewer_process = subprocess.Popen(command) - #at the moment, we just exit here. Later, the crash monitor will be launched at this point -elif (success == True and - (state == None - or (state == 'background' and condition == True) - or (state == 'in_place' and condition == True))): - command.insert(0,viewer_binary) - viewer_process = subprocess.Popen(command) - #at the moment, we just exit here. Later, the crash monitor will be launched at this point -else: - #'condition' is the path to the new launcher. - command.insert(0,condition) - viewer_process = subprocess.Popen(command) - sys.exit(0) diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py deleted file mode 100755 index 643e4ad2bc..0000000000 --- a/indra/viewer_components/manager/apply_update.py +++ /dev/null @@ -1,277 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $LicenseInfo:firstyear=2016&license=viewerlgpl$ -# Copyright (c) 2016, Linden Research, Inc. -# $/LicenseInfo$ - -""" -@file apply_update.py -@author coyot -@date 2016-06-28 -""" - -""" -Applies an already downloaded update. -""" - -import argparse -import errno -import fnmatch -import InstallerUserMessage as IUM -import os -import os.path -import plistlib -import re -import shutil -import subprocess -import sys -import tarfile -import tempfile - -#Module level variables - -#fnmatch expressions -LNX_REGEX = '*' + '.bz2' -MAC_REGEX = '*' + '.dmg' -MAC_APP_REGEX = '*' + '.app' -WIN_REGEX = '*' + '.exe' - -#which install the updater is run from -INSTALL_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) - -#whether the update is to the INSTALL_DIR or not. Most of the time this is the case. -IN_PLACE = True - -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") - -def silent_write(log_file_handle, text): - #if we have a log file, write. If not, do nothing. - if (log_file_handle): - #prepend text for easy grepping - log_file_handle.write("APPLY UPDATE: " + text + "\n") - -def get_filename(download_dir = None): - #given a directory that supposedly has the download, find the installable - #if you are on platform X and you give the updater a directory with an installable - #for platform Y, you are either trying something fancy or get what you deserve - #or both - for filename in os.listdir(download_dir): - if (fnmatch.fnmatch(filename, LNX_REGEX) - or fnmatch.fnmatch(filename, MAC_REGEX) - or fnmatch.fnmatch(filename, WIN_REGEX)): - return os.path.join(download_dir, filename) - #someone gave us a bad directory - return None - -def try_dismount(log_file_handle = None, installable = None, tmpdir = None): - #best effort cleanup try to dismount the dmg file if we have mounted one - #the French judge gave it a 5.8 - try: - #use the df command to find the device name - #Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on - #/dev/disk1s2 2047936 643280 1404656 32% 80408 175582 31% /private/tmp/mnt/Second Life Installer - command = ["df", os.path.join(tmpdir, "Second Life Installer")] - output = subprocess.check_output(command) - #first word of second line of df output is the device name - mnt_dev = output.split('\n')[1].split()[0] - #do the dismount - command = ["hdiutil", "detach", "-force", mnt_dev] - output = subprocess.check_output(command) - silent_write(log_file_handle, "hdiutil detach succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not detach dmg file %s. Error messages: %s" % (installable, e.message)) - -def apply_update(download_dir = None, platform_key = None, log_file_handle = None, in_place = True): - #for lnx and mac, returns path to newly installed viewer - #for win, return the name of the executable - #returns None on failure for all three - #throws an exception if it can't find an installable at all - - IN_PLACE = in_place - - installable = get_filename(download_dir) - if not installable: - #could not find the download - raise ValueError("Could not find installable in " + download_dir) - - #apply update using the platform specific tools - if platform_key == 'lnx': - installed = apply_linux_update(installable, log_file_handle) - elif platform_key == 'mac': - installed = apply_mac_update(installable, log_file_handle) - elif platform_key == 'win': - installed = apply_windows_update(installable, log_file_handle) - else: - #wtf? - raise ValueError("Unknown Platform: " + platform_key) - - if not installed: - #only mark the download as done when everything is done - done_filename = os.path.join(os.path.dirname(installable), ".done") - open(done_filename, 'w+').close() - - return installed - -def apply_linux_update(installable = None, log_file_handle = None): - try: - #untar to tmpdir - tmpdir = tempfile.mkdtemp() - tar = tarfile.open(name = installable, mode="r:bz2") - tar.extractall(path = tmpdir) - if IN_PLACE: - #rename current install dir - shutil.move(INSTALL_DIR,install_dir + ".bak") - #mv new to current - shutil.move(tmpdir, INSTALL_DIR) - #delete tarball on success - os.remove(installable) - except Exception, e: - silent_write(log_file_handle, "Update failed due to " + repr(e)) - return None - return INSTALL_DIR - -def apply_mac_update(installable = None, log_file_handle = None): - #INSTALL_DIR is something like /Applications/Second Life Viewer.app/Contents/MacOS, need to jump up two levels for the install base - install_base = os.path.dirname(INSTALL_DIR) - install_base = os.path.dirname(install_base) - - #verify dmg file - try: - output = subprocess.check_output(["hdiutil", "verify", installable], stderr=subprocess.STDOUT) - silent_write(log_file_handle, "dmg verification succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not verify dmg file %s. Error messages: %s" % (installable, e.message)) - return None - #make temp dir and mount & attach dmg - tmpdir = tempfile.mkdtemp() - try: - output = subprocess.check_output(["hdiutil", "attach", installable, "-mountroot", tmpdir]) - silent_write(log_file_handle, "hdiutil attach succeeded") - silent_write(log_file_handle, output) - except Exception, e: - silent_write(log_file_handle, "Could not attach dmg file %s. Error messages: %s" % (installable, e.message)) - return None - #verify plist - mounted_appdir = None - for top_dir in os.listdir(tmpdir): - for appdir in os.listdir(os.path.join(tmpdir, top_dir)): - appdir = os.path.join(os.path.join(tmpdir, top_dir), appdir) - if fnmatch.fnmatch(appdir, MAC_APP_REGEX): - try: - plist = os.path.join(appdir, "Contents", "Info.plist") - CFBundleIdentifier = plistlib.readPlist(plist)["CFBundleIdentifier"] - mounted_appdir = appdir - except: - #there is no except for this try because there are multiple directories that legimately don't have what we are looking for - pass - if not mounted_appdir: - silent_write(log_file_handle, "Could not find app bundle in dmg %s." % (installable,)) - return None - if CFBundleIdentifier != BUNDLE_IDENTIFIER: - silent_write(log_file_handle, "Wrong or null bundle identifier for dmg %s. Bundle identifier: %s" % (installable, CFBundleIdentifier)) - try_dismount(log_file_handle, installable, tmpdir) - return None - #do the install, finally - if IN_PLACE: - # swap out old install directory - bundlename = os.path.basename(mounted_appdir) - silent_write(log_file_handle, "Updating %s" % bundlename) - swapped_out = os.path.join(tmpdir, INSTALL_DIR.lstrip('/')) - shutil.move(install_base, swapped_out) - else: - silent_write(log_file_handle, "Installing %s" % install_base) - - # copy over the new bits - try: - shutil.copytree(mounted_appdir, install_base, symlinks=True) - retcode = 0 - except Exception, e: - # try to restore previous viewer - if os.path.exists(swapped_out): - silent_write(log_file_handle, "Install of %s failed, rolling back to previous viewer." % installable) - shutil.move(swapped_out, installed_test) - retcode = 1 - finally: - try_dismount(log_file_handle, installable, tmpdir) - if retcode: - return None - - #see MAINT-3331 - try: - shutil.rmtree(STATE_DIR) - except Exception, e: - #if we fail to delete something that isn't there, that's okay - if e[0] == errno.ENOENT: - pass - else: - raise e - - os.remove(installable) - return install_base - -def apply_windows_update(installable = None, log_file_handle = None): - #the windows install is just running the NSIS installer executable - #from VMP's perspective, it is a black box - try: - output = subprocess.check_output(installable, stderr=subprocess.STDOUT) - silent_write(log_file_handle, "Install of %s succeeded." % installable) - silent_write(log_file_handle, output) - except subprocess.CalledProcessError, cpe: - silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." % - (cpe.cmd, cpe.returncode, cpe.message)) - return None - #Due to the black box nature of the install, we have to derive the application path from the - #name of the installable. This is essentially reverse-engineering app_name()/app_name_oneword() - #in viewer_manifest.py - #the format of the filename is: Second_Life_{Project Name}_A-B-C-XXXXXX_i686_Setup.exe - #which deploys to C:\Program Files (x86)\SecondLifeProjectName\ - #so we want all but the last four phrases and tack on Viewer if there is no project - if re.search('Project', installable): - winstall = os.path.join("C:\\Program Files (x86)\\", "".join(installable.split("_")[:-3])) - else: - winstall = os.path.join("C:\\Program Files (x86)\\", "".join(installable.split("_")[:-3])+"Viewer") - return winstall - -def main(): - parser = argparse.ArgumentParser("Apply Downloaded Update") - parser.add_argument('--dir', dest = 'download_dir', help = 'directory to find installable', required = True) - parser.add_argument('--pkey', dest = 'platform_key', help =' OS: lnx|mac|win', required = True) - parser.add_argument('--in_place', action = 'store_false', help = 'This upgrade is for a different channel', default = True) - parser.add_argument('--log_file', dest = 'log_file', default = None, help = 'file to write messages to') - args = parser.parse_args() - - if args.log_file: - try: - f = open(args.log_file,'w+') - except: - print "%s could not be found or opened" % args.log_file - sys.exit(1) - - IN_PLACE = args.in_place - result = apply_update(download_dir = args.download_dir, platform_key = args.platform_key, log_file_handle = f) - if not result: - sys.exit("Update failed") - else: - sys.exit(0) - - -if __name__ == "__main__": - main() diff --git a/indra/viewer_components/manager/download_update.py b/indra/viewer_components/manager/download_update.py deleted file mode 100755 index a5e365fa37..0000000000 --- a/indra/viewer_components/manager/download_update.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2016, Linden Research, Inc. -# -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -# -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $LicenseInfo:firstyear=2016&license=viewerlgpl$ -# Copyright (c) 2016, Linden Research, Inc. -# $/LicenseInfo$ - -""" -@file download_update.py -@author coyot -@date 2016-06-23 -""" - -""" -Performs a download of an update. In a separate script from update_manager so that we can -call it with subprocess. -""" - -import argparse -import InstallerUserMessage as IUM -import os -import Queue -import requests -import threading - -#module default -CHUNK_SIZE = 1024 - -def download_update(url = None, download_dir = None, size = None, progressbar = False, chunk_size = CHUNK_SIZE): - #url to download from - #download_dir to download to - #total size (for progressbar) of download - #progressbar: whether to display one (not used for background downloads) - #chunk_size is in bytes, amount to download at once - - queue = Queue.Queue() - if not os.path.exists(download_dir): - os.makedirs(download_dir) - #the url split provides the basename of the filename - filename = os.path.join(download_dir, url.split('/')[-1]) - req = requests.get(url, stream=True) - down_thread = ThreadedDownload(req, filename, chunk_size, progressbar, queue) - down_thread.start() - - if progressbar: - frame = IUM.InstallerUserMessage(title = "Second Life Downloader", icon_name="head-sl-logo.gif") - frame.progress_bar(message = "Download Progress", size = size, pb_queue = queue) - frame.mainloop() - else: - #nothing for the main thread to do - down_thread.join() - -class ThreadedDownload(threading.Thread): - def __init__(self, req, filename, chunk_size, progressbar, in_queue): - #req is a python request object - #target filename to download to - #chunk_size is in bytes, amount to download at once - #progressbar: whether to display one (not used for background downloads) - #in_queue mediates communication between this thread and the progressbar - threading.Thread.__init__(self) - self.req = req - self.filename = filename - self.chunk_size = int(chunk_size) - self.progressbar = progressbar - self.in_queue = in_queue - - def run(self): - with open(self.filename, 'wb') as fd: - #keep downloading until we run out of chunks, then download the last bit - for chunk in self.req.iter_content(self.chunk_size): - fd.write(chunk) - if self.progressbar: - #this will increment the progress bar by len(chunk)/size units - self.in_queue.put(len(chunk)) - #signal value saying to the progress bar that it is done and can destroy itself - #if len(chunk) is ever -1, we get to file a bug against Python - self.in_queue.put(-1) - -def main(): - #main method is for standalone use such as support and QA - #VMP will import this module and run download_update directly - parser = argparse.ArgumentParser("Download URI to directory") - parser.add_argument('--url', dest='url', help='URL of file to be downloaded', required=True) - parser.add_argument('--dir', dest='download_dir', help='directory to be downloaded to', required=True) - parser.add_argument('--pb', dest='progressbar', help='whether or not to show a progressbar', action="store_true", default = False) - parser.add_argument('--size', dest='size', help='size of download for progressbar') - parser.add_argument('--chunk_size', dest='chunk_size', default=CHUNK_SIZE, help='max portion size of download to be loaded in memory in bytes.') - args = parser.parse_args() - - download_update(url = args.url, download_dir = args.download_dir, size = args.size, progressbar = args.progressbar, chunk_size = args.chunk_size) - - -if __name__ == "__main__": - main() diff --git a/indra/viewer_components/manager/tests/data/settings.xml b/indra/viewer_components/manager/tests/data/settings.xml deleted file mode 100644 index 07e420dcb3..0000000000 --- a/indra/viewer_components/manager/tests/data/settings.xml +++ /dev/null @@ -1,1184 +0,0 @@ - - - AllowMultipleViewers - - Comment - Allow multiple viewers. - Type - Boolean - Value - 1 - - AllowTapTapHoldRun - - Comment - Tapping a direction key twice and holding it down makes avatar run - Type - Boolean - Value - 0 - - AppearanceCameraMovement - - Comment - When entering appearance editing mode, camera zooms in on currently selected portion of avatar - Type - Boolean - Value - 0 - - AudioLevelMedia - - Comment - Audio level of Quicktime movies - Type - F32 - Value - 0.699999988079071044921875 - - AudioLevelMic - - Comment - Audio level of microphone input - Type - F32 - Value - 0.1749999970197677612304688 - - AudioLevelMusic - - Comment - Audio level of streaming music - Type - F32 - Value - 0 - - AudioLevelSFX - - Comment - Audio level of in-world sound effects - Type - F32 - Value - 0.699999988079071044921875 - - AudioLevelVoice - - Comment - Audio level of voice chat - Type - F32 - Value - 1 - - AudioStreamingMedia - - Comment - Enable streaming - Type - Boolean - Value - 0 - - AvatarAxisDeadZone0 - - Comment - Avatar axis 0 dead zone. - Type - F32 - Value - 0.1000000014901161193847656 - - AvatarAxisDeadZone1 - - Comment - Avatar axis 1 dead zone. - Type - F32 - Value - 0.1000000014901161193847656 - - AvatarAxisDeadZone2 - - Comment - Avatar axis 2 dead zone. - Type - F32 - Value - 0.1000000014901161193847656 - - AvatarAxisDeadZone3 - - Comment - Avatar axis 3 dead zone. - Type - F32 - Value - 1 - - AvatarAxisDeadZone4 - - Comment - Avatar axis 4 dead zone. - Type - F32 - Value - 0.01999999955296516418457031 - - AvatarAxisDeadZone5 - - Comment - Avatar axis 5 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - AvatarAxisScale3 - - Comment - Avatar axis 3 scaler. - Type - F32 - Value - 0 - - AvatarAxisScale4 - - Comment - Avatar axis 4 scaler. - Type - F32 - Value - 2 - - AvatarAxisScale5 - - Comment - Avatar axis 5 scaler. - Type - F32 - Value - 2 - - AvatarFeathering - - Comment - Avatar feathering (less is softer) - Type - F32 - Value - 6 - - AvatarFileName - - Comment - Alternative avatar file name - Type - String - Value - avatar_lad_tentacles.xml - - BuildAxisDeadZone0 - - Comment - Build axis 0 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisDeadZone1 - - Comment - Build axis 1 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisDeadZone2 - - Comment - Build axis 2 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisDeadZone3 - - Comment - Build axis 3 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisDeadZone4 - - Comment - Build axis 4 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisDeadZone5 - - Comment - Build axis 5 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - BuildAxisScale0 - - Comment - Build axis 0 scaler. - Type - F32 - Value - 6 - - BuildAxisScale1 - - Comment - Build axis 1 scaler. - Type - F32 - Value - 6 - - BuildAxisScale2 - - Comment - Build axis 2 scaler. - Type - F32 - Value - 6 - - BuildAxisScale3 - - Comment - Build axis 3 scaler. - Type - F32 - Value - 6 - - BuildAxisScale4 - - Comment - Build axis 4 scaler. - Type - F32 - Value - 6 - - BuildAxisScale5 - - Comment - Build axis 5 scaler. - Type - F32 - Value - 6 - - BuildFeathering - - Comment - Build feathering (less is softer) - Type - F32 - Value - 12 - - BulkChangeEveryoneCopy - - Comment - Bulk changed objects can be copied by everyone - Type - Boolean - Value - 1 - - BulkChangeNextOwnerCopy - - Comment - Bulk changed objects can be copied by next owner - Type - Boolean - Value - 1 - - BulkChangeNextOwnerModify - - Comment - Bulk changed objects can be modified by next owner - Type - Boolean - Value - 1 - - BulkChangeShareWithGroup - - Comment - Bulk changed objects are shared with the currently active group - Type - Boolean - Value - 1 - - CacheValidateCounter - - Comment - Used to distribute cache validation - Type - U32 - Value - 122 - - CameraPosOnLogout - - Comment - Camera position when last logged out (global coordinates) - Type - Vector3D - Value - - 288290.4477181434631347656 - 275988.5277819633483886719 - 49.10921102762222290039062 - - - ClickToWalk - - Comment - Click in world to walk to location - Type - Boolean - Value - 0 - - ConversationSortOrder - - Comment - Specifies sort key for conversations - Type - U32 - Value - 0 - - CurrentGrid - - Comment - Currently Selected Grid - Type - String - Value - util.agni.lindenlab.com - - Cursor3D - - Comment - Treat Joystick values as absolute positions (not deltas). - Type - Boolean - Value - 0 - - FirstLoginThisInstall - - Comment - Specifies that you have not logged in with the viewer since you performed a clean install - Type - Boolean - Value - 0 - - FirstRunThisInstall - - Comment - Specifies that you have not run the viewer since you performed a clean install - Type - Boolean - Value - 0 - - FlycamAxisDeadZone0 - - Comment - Flycam axis 0 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone1 - - Comment - Flycam axis 1 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone2 - - Comment - Flycam axis 2 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone3 - - Comment - Flycam axis 3 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone4 - - Comment - Flycam axis 4 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone5 - - Comment - Flycam axis 5 dead zone. - Type - F32 - Value - 0.009999999776482582092285156 - - FlycamAxisDeadZone6 - - Comment - Flycam axis 6 dead zone. - Type - F32 - Value - 1 - - FlycamAxisScale0 - - Comment - Flycam axis 0 scaler. - Type - F32 - Value - 42 - - FlycamAxisScale1 - - Comment - Flycam axis 1 scaler. - Type - F32 - Value - 40 - - FlycamAxisScale2 - - Comment - Flycam axis 2 scaler. - Type - F32 - Value - 40 - - FlycamAxisScale3 - - Comment - Flycam axis 3 scaler. - Type - F32 - Value - 0 - - FlycamAxisScale4 - - Comment - Flycam axis 4 scaler. - Type - F32 - Value - 2 - - FlycamAxisScale5 - - Comment - Flycam axis 5 scaler. - Type - F32 - Value - 3 - - FlycamAxisScale6 - - Comment - Flycam axis 6 scaler. - Type - F32 - Value - 0 - - FlycamFeathering - - Comment - Flycam feathering (less is softer) - Type - F32 - Value - 5 - - FocusPosOnLogout - - Comment - Camera focus point when last logged out (global coordinates) - Type - Vector3D - Value - - 288287.8830481640761718154 - 275991.5973855691263452172 - 47.96361158013021963597566 - - - ForceShowGrid - - Comment - Always show grid dropdown on login screen - Type - Boolean - Value - 1 - - HttpProxyType - - Comment - Proxy type to use for HTTP operations - Type - String - Value - None - - JoystickInitialized - - Comment - Whether or not a joystick has been detected and initiailized. - Type - String - Value - UnknownDevice - - LSLFindCaseInsensitivity - - Comment - Use case insensitivity when searching in LSL editor - Type - Boolean - Value - 1 - - LastFeatureVersion - - Comment - [DO NOT MODIFY] Feature Table Version number for tracking rendering system changes - Type - S32 - Value - 37 - - LastGPUString - - Comment - [DO NOT MODIFY] previous GPU id string for tracking hardware changes - Type - String - Value - NVIDIA Corporation NVIDIA GeForce GT 750M OpenGL Engine - - LastPrefTab - - Comment - Last selected tab in preferences window - Type - S32 - Value - 1 - - LastRunVersion - - Comment - Version number of last instance of the viewer that you ran - Type - String - Value - Second Life Project Bento 5.0.0.315657 - - LocalCacheVersion - - Comment - Version number of cache - Type - S32 - Value - 7 - - LoginLocation - - Comment - Default Login location ('last', 'home') preference - Type - String - Value - home - - MapScale - - Comment - World map zoom level (pixels per region) - Type - F32 - Value - 256 - - MaxJointsPerMeshObject - - Comment - Maximum joints per rigged mesh object - Type - U32 - Value - 51 - - MediaEnablePopups - - Comment - If true, enable targeted links and javascript in media to open new media browser windows without a prompt. - Type - Boolean - Value - 1 - - MediaShowOnOthers - - Comment - Whether or not to show media on other avatars - Type - Boolean - Value - 1 - - MigrateCacheDirectory - - Comment - Check for old version of disk cache to migrate to current location - Type - Boolean - Value - 0 - - NavBarShowParcelProperties - - Comment - Show parcel property icons in navigation bar - Type - Boolean - Value - 0 - - NextLoginLocation - - Comment - Location to log into for this session - set from command line or the login panel, cleared following a successfull login. - Type - String - Value - home - - NotificationConferenceIMOptions - - Comment - - Specifies how the UI responds to Conference IM Notifications. - Allowed values: [openconversations,toast,flash,noaction] - - Type - String - Value - none - - NotificationFriendIMOptions - - Comment - - Specifies how the UI responds to Friend IM Notifications. - Allowed values: [openconversations,toast,flash,noaction] - - Type - String - Value - openconversations - - NotificationGroupChatOptions - - Comment - - Specifies how the UI responds to Group Chat Notifications. - Allowed values: [openconversations,toast,flash,noaction] - - Type - String - Value - none - - NotificationNearbyChatOptions - - Comment - - Specifies how the UI responds to Nearby Chat Notifications. - Allowed values: [openconversations,toast,flash,noaction] - - Type - String - Value - none - - NotificationNonFriendIMOptions - - Comment - - Specifies how the UI responds to Non Friend IM Notifications. - Allowed values: [openconversations,toast,flash,noaction] - - Type - String - Value - openconversations - - NumSessions - - Comment - Number of successful logins to Second Life - Type - S32 - Value - 1674 - - PlayTypingAnim - - Comment - Your avatar plays the typing animation whenever you type in the chat bar - Type - Boolean - Value - 0 - - PoolSizeExpCache - - Comment - Coroutine Pool size for ExpCache - Type - U32 - Value - 5 - - PreferredBrowserBehavior - - Comment - Use system browser for any links (0), use builtin browser for SL links and system one for others (1) or use builtin browser only (2). - Type - U32 - Value - 0 - - PreferredMaturity - - Comment - Setting for the user's preferred maturity level (consts in indra_constants.h) - Type - U32 - Value - 42 - - PresetGraphicActive - - Comment - Name of currently selected preference - Type - String - Value - Default - - ProbeHardwareOnStartup - - Comment - Query current hardware configuration on application startup - Type - Boolean - Value - 0 - - QAMode - - Comment - Enable Testing Features. - Type - Boolean - Value - 1 - - RenderAnisotropic - - Comment - Render textures using anisotropic filtering - Type - Boolean - Value - 1 - - RenderAvatarCloth - - Comment - Controls if avatars use wavy cloth - Type - Boolean - Value - 0 - - RenderAvatarLODFactor - - Comment - Controls level of detail of avatars (multiplier for current screen area when calculated level of detail) - Type - F32 - Value - 1 - - RenderFSAASamples - - Comment - Number of samples to use for FSAA (0 = no AA). - Type - U32 - Value - 2 - - RenderFarClip - - Comment - Distance of far clip plane from camera (meters) - Type - F32 - Value - 128 - - RenderMaxPartCount - - Comment - Maximum number of particles to display on screen - Type - S32 - Value - 2048 - - RenderQualityPerformance - - Comment - Which graphics settings you've chosen - Type - U32 - Value - 4 - - RenderReflectionDetail - - Comment - Detail of reflection render pass. - Type - S32 - Value - 0 - - RenderTerrainLODFactor - - Comment - Controls level of detail of terrain (multiplier for current screen area when calculated level of detail) - Type - F32 - Value - 2 - - RenderVBOEnable - - Comment - Use GL Vertex Buffer Objects - Type - Boolean - Value - 0 - - RenderVolumeLODFactor - - Comment - Controls level of detail of primitives (multiplier for current screen area when calculated level of detail) - Type - F32 - Value - 1.125 - - ShowAdvancedGraphicsSettings - - Comment - Show advanced graphics settings - Type - Boolean - Value - 1 - - ShowBanLines - - Comment - Show in-world ban/access borders - Type - Boolean - Value - 0 - - ShowStartLocation - - Comment - Display starting location menu on login screen - Type - Boolean - Value - 1 - - SkeletonFileName - - Comment - Alternative skeleton file name - Type - String - Value - avatar_skeleton_tentacles.xml - - SkyPresetName - - Comment - Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName). - Type - String - Value - Sunset - - SnapshotConfigURL - - Comment - URL to fetch Snapshot Sharing configuration data from. - Type - String - Value - http://photos.apps.avatarsunited.com/viewer_config - - SnapshotFormat - - Comment - Save snapshots in this format (0 = PNG, 1 = JPEG, 2 = BMP) - Type - S32 - Value - 1 - - SnapshotQuality - - Comment - Quality setting of postcard JPEGs (0 = worst, 100 = best) - Type - S32 - Value - 100 - - SpellCheck - - Comment - Enable spellchecking on line and text editors - Type - Boolean - Value - 0 - - SpellCheckDictionary - - Comment - Current primary and secondary dictionaries used for spell checking - Type - String - Value - English (United States) - - TextureMemory - - Comment - Amount of memory to use for textures in MB (0 = autodetect) - Type - S32 - Value - 256 - - UseDayCycle - - Comment - Whether to use use a day cycle or a fixed sky. - Type - Boolean - Value - 0 - - UseDebugMenus - - Comment - Turns on "Debug" menu - Type - Boolean - Value - 1 - - UseEnvironmentFromRegion - - Comment - Choose whether to use the region's environment settings, or override them with the local settings. - Type - Boolean - Value - 0 - - VFSOldSize - - Comment - [DO NOT MODIFY] Controls resizing of local file cache - Type - U32 - Value - 102 - - VFSSalt - - Comment - [DO NOT MODIFY] Controls local file caching behavior - Type - U32 - Value - 260093998 - - VersionChannelName - - Comment - Version information generated by running the viewer - Type - String - Value - Second Life Release - - VertexShaderEnable - - Comment - Enable/disable all GLSL shaders (debug) - Type - Boolean - Value - 1 - - VoiceInputAudioDevice - - Comment - Audio input device to use for voice - Type - String - Value - C-Media USB Audio Device - - VoiceOutputAudioDevice - - Comment - Audio output device to use for voice - Type - String - Value - C-Media USB Audio Device - - WLSkyDetail - - Comment - Controls vertex detail on the WindLight sky. Lower numbers will give better performance and uglier skies. - Type - U32 - Value - 48 - - WebProfileFloaterRect - - Comment - Web profile floater dimensions - Type - Rect - Value - - 1189 - 957 - 1674 - 277 - - - WindowHeight - - Comment - SL viewer window height - Type - U32 - Value - 1000 - - WindowWidth - - Comment - SL viewer window width - Type - U32 - Value - 1626 - - WindowX - - Comment - X coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels) - Type - S32 - Value - 50 - - WindowY - - Comment - Y coordinate of upper left corner of SL viewer window, relative to upper left corner of primary display (pixels) - Type - S32 - Value - 50 - - - diff --git a/indra/viewer_components/manager/tests/summary.json b/indra/viewer_components/manager/tests/summary.json deleted file mode 100644 index b78859d427..0000000000 --- a/indra/viewer_components/manager/tests/summary.json +++ /dev/null @@ -1 +0,0 @@ -{"Type":"viewer","Version":"4.0.5.315117","Channel":"Second Life Release"} diff --git a/indra/viewer_components/manager/tests/test_InstallerError.py b/indra/viewer_components/manager/tests/test_InstallerError.py deleted file mode 100644 index 9139447932..0000000000 --- a/indra/viewer_components/manager/tests/test_InstallerError.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python - -"""\ -@file test_InstallerError.py -@author coyot -@date 2016-06-01 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - - -from nose.tools import assert_equal - -import InstallerError -import os - -def test_InstallerError(): - try: - #try to make our own homedir, this will fail on all three platforms - homedir = os.path.abspath(os.path.expanduser('~')) - os.mkdir(homedir) - except OSError, oe: - ie = InstallerError.InstallerError(oe, "Installer failed to create a homedir that already exists.") - - assert_equal( str(ie), - "[Errno [Errno 17] File exists: '%s'] Installer failed to create a homedir that already exists." % homedir) diff --git a/indra/viewer_components/manager/tests/test_check_for_completed_download.py b/indra/viewer_components/manager/tests/test_check_for_completed_download.py deleted file mode 100644 index bcaaef4c3f..0000000000 --- a/indra/viewer_components/manager/tests/test_check_for_completed_download.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_check_for_completed_download.py -@author coyot -@date 2016-06-03 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * -from nose import with_setup - -import os -import shutil -import tempfile -import update_manager -import with_setup_args - -def check_for_completed_download_setup(): - tmpdir1 = tempfile.mkdtemp(prefix = 'test1') - tmpdir2 = tempfile.mkdtemp(prefix = 'test2') - tempfile.mkstemp(suffix = '.done', dir = tmpdir1) - - return [tmpdir1,tmpdir2], {} - -def check_for_completed_download_teardown(tmpdir1,tmpdir2): - shutil.rmtree(tmpdir1, ignore_errors = True) - shutil.rmtree(tmpdir2, ignore_errors = True) - -@with_setup_args.with_setup_args(check_for_completed_download_setup, check_for_completed_download_teardown) -def test_completed_check_for_completed_download(tmpdir1,tmpdir2): - assert_equal(update_manager.check_for_completed_download(tmpdir1), 'done'), "Failed to find completion marker" - -@with_setup_args.with_setup_args(check_for_completed_download_setup, check_for_completed_download_teardown) -def test_incomplete_check_for_completed_download(tmpdir1,tmpdir2): - #should return False - incomplete = not update_manager.check_for_completed_download(tmpdir2) - assert incomplete, "False positive, should not mark complete without a marker" diff --git a/indra/viewer_components/manager/tests/test_convert_version_file_style.py b/indra/viewer_components/manager/tests/test_convert_version_file_style.py deleted file mode 100644 index 244c22c458..0000000000 --- a/indra/viewer_components/manager/tests/test_convert_version_file_style.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -"""\ -@file test_convert_version_file_style.py -@author coyot -@date 2016-06-01 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - - -from nose.tools import assert_equal - -import update_manager - -def test_normal_form(): - version = '1.2.3.456789' - golden = '1_2_3_456789' - converted = update_manager.convert_version_file_style(version) - - assert_equal(golden, converted) - -def test_short_form(): - version = '1.23' - golden = '1_23' - converted = update_manager.convert_version_file_style(version) - - assert_equal(golden, converted) - -def test_idempotent(): - version = '123' - golden = '123' - converted = update_manager.convert_version_file_style(version) - - assert_equal(golden, converted) - -def test_none(): - version = None - golden = None - converted = update_manager.convert_version_file_style(version) - - assert_equal(golden, converted) diff --git a/indra/viewer_components/manager/tests/test_get_filename.py b/indra/viewer_components/manager/tests/test_get_filename.py deleted file mode 100644 index efb6349374..0000000000 --- a/indra/viewer_components/manager/tests/test_get_filename.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_get_filename.py -@author coyot -@date 2016-06-30 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * -from nose import with_setup - -import os -import shutil -import tempfile -import apply_update -import with_setup_args - -def get_filename_setup(): - tmpdir1 = tempfile.mkdtemp(prefix = 'lnx') - tmpdir2 = tempfile.mkdtemp(prefix = 'mac') - tmpdir3 = tempfile.mkdtemp(prefix = 'win') - tmpdir4 = tempfile.mkdtemp(prefix = 'bad') - tempfile.mkstemp(suffix = '.bz2', dir = tmpdir1) - tempfile.mkstemp(suffix = '.dmg', dir = tmpdir2) - tempfile.mkstemp(suffix = '.exe', dir = tmpdir3) - - return [tmpdir1,tmpdir2, tmpdir3, tmpdir4], {} - -def get_filename_teardown(tmpdir1,tmpdir2, tmpdir3, tmpdir4): - shutil.rmtree(tmpdir1, ignore_errors = True) - shutil.rmtree(tmpdir2, ignore_errors = True) - shutil.rmtree(tmpdir3, ignore_errors = True) - shutil.rmtree(tmpdir4, ignore_errors = True) - -@with_setup_args.with_setup_args(get_filename_setup, get_filename_teardown) -def test_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): - assert_is_not_none(apply_update.get_filename(tmpdir1)), "Failed to find installable" - assert_is_not_none(apply_update.get_filename(tmpdir2)), "Failed to find installable" - assert_is_not_none(apply_update.get_filename(tmpdir3)), "Failed to find installable" - -@with_setup_args.with_setup_args(get_filename_setup, get_filename_teardown) -def test_missing_get_filename(tmpdir1, tmpdir2, tmpdir3, tmpdir4): - not_found = not apply_update.get_filename(tmpdir4) - assert not_found, "False positive, should not find an installable in an empty dir" diff --git a/indra/viewer_components/manager/tests/test_get_log_file_handle.py b/indra/viewer_components/manager/tests/test_get_log_file_handle.py deleted file mode 100644 index 5ea821acf7..0000000000 --- a/indra/viewer_components/manager/tests/test_get_log_file_handle.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python - -""" -@file test_get_log_file_handle.py -@author coyot -@date 2016-06-08 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import os -import shutil -import tempfile -import update_manager -import with_setup_args - -def get_log_file_handle_setup(): - tmpdir1 = tempfile.mkdtemp(prefix = 'test1') - tmpdir2 = tempfile.mkdtemp(prefix = 'test2') - log_file_path = os.path.abspath(os.path.join(tmpdir1,"update_manager.log")) - #not using tempfile because we want a particular filename - open(log_file_path, 'w+').close - - return [tmpdir1,tmpdir2,log_file_path], {} - -def get_log_file_handle_teardown(tmpdir1,tmpdir2,log_file_path): - shutil.rmtree(tmpdir1, ignore_errors = True) - shutil.rmtree(tmpdir2, ignore_errors = True) - -@with_setup_args.with_setup_args(get_log_file_handle_setup, get_log_file_handle_teardown) -def test_existing_get_log_file_handle(tmpdir1,tmpdir2,log_file_path): - handle = update_manager.get_log_file_handle(tmpdir1) - if not handle: - print "Failed to find existing log file" - assert False - elif not os.path.exists(os.path.abspath(log_file_path+".old")): - print "Failed to rotate update manager log" - assert False - assert True - -@with_setup_args.with_setup_args(get_log_file_handle_setup, get_log_file_handle_teardown) -def test_missing_get_log_file_handle(tmpdir1,tmpdir2,log_file_path): - handle = update_manager.get_log_file_handle(tmpdir2) - if not os.path.exists(log_file_path): - print "Failed to touch new log file" - assert False - assert True diff --git a/indra/viewer_components/manager/tests/test_get_parent_path.py b/indra/viewer_components/manager/tests/test_get_parent_path.py deleted file mode 100644 index 6e4b9dfaff..0000000000 --- a/indra/viewer_components/manager/tests/test_get_parent_path.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_get_parent_path.py -@author coyot -@date 2016-06-02 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * -from nose import with_setup - -import os -import shutil -import update_manager -import with_setup_args - -def get_parent_path_setup(): - key = update_manager.get_platform_key() - try: - if key == 'mac': - settings_dir = os.path.join(os.path.expanduser('~'),'Library','Application Support','SecondLife') - elif key == 'lnx': - settings_dir = os.path.join(os.path.expanduser('~'),'.secondlife') - elif key == 'win': - settings_dir = os.path.join(os.path.expanduser('~'),'AppData','Roaming','SecondLife') - else: - raise Exception("Invalid Platform Key") - - #preserve existing settings dir if any - if os.path.exists(settings_dir): - old_dir = settings_dir + ".tmp" - if os.path.exists(old_dir): - shutil.rmtree(old_dir, ignore_errors = True) - os.rename(settings_dir, old_dir) - os.makedirs(settings_dir) - except Exception, e: - print "get_parent_path_setup failed due to: %s" % str(e) - assert False - - #this is we don't have to rediscover settings_dir for test and teardown - return [settings_dir], {} - -def get_parent_path_teardown(settings_dir): - try: - shutil.rmtree(settings_dir, ignore_errors = True) - #restore previous settings dir if any - old_dir = settings_dir + ".tmp" - if os.path.exists(old_dir): - os.rename(old_dir, settings_dir) - except: - #cleanup is best effort - pass - -@with_setup_args.with_setup_args(get_parent_path_setup, get_parent_path_teardown) -def test_get_parent_path(settings_dir): - key = update_manager.get_platform_key() - got_settings_dir = update_manager.get_parent_path(key) - - assert settings_dir, "test_get_parent_path failed to obtain parent path" - - assert_equal(settings_dir, got_settings_dir) diff --git a/indra/viewer_components/manager/tests/test_get_platform_key.py b/indra/viewer_components/manager/tests/test_get_platform_key.py deleted file mode 100644 index eeaca1dff7..0000000000 --- a/indra/viewer_components/manager/tests/test_get_platform_key.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python - -""" -@file test_get_platform_key.py -@author coyot -@date 2016-06-01 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import assert_equal - -import platform -import update_manager - -def test_get_platform_key(): - key = update_manager.get_platform_key() - if key == 'mac': - assert_equal(platform.system(),'Darwin') - elif key == 'lnx': - assert_equal(platform.system(),'Linux') - elif key == 'win': - assert_equal(platform.system(),'Windows') - else: - assert_equal(key, None) diff --git a/indra/viewer_components/manager/tests/test_get_settings.py b/indra/viewer_components/manager/tests/test_get_settings.py deleted file mode 100644 index 7efcf62673..0000000000 --- a/indra/viewer_components/manager/tests/test_get_settings.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_get_settings.py -@author coyot -@date 2016-06-03 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * -from nose import with_setup - -import os -import shutil -import update_manager -import with_setup_args - -def get_settings_setup(): - try: - key = update_manager.get_platform_key() - settings_dir = os.path.join(update_manager.get_parent_path(key), "user_settings") - print settings_dir - - #preserve existing settings dir if any - if os.path.exists(settings_dir): - old_dir = settings_dir + ".tmp" - if os.path.exists(old_dir): - shutil.rmtree(old_dir, ignore_errors = True) - os.rename(settings_dir, old_dir) - os.makedirs(settings_dir) - - #the data subdir of the tests dir that this script is in - data_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "data") - #the test settings file - settings_file = os.path.join(data_dir, "settings.xml") - shutil.copyfile(settings_file, os.path.join(settings_dir, "settings.xml")) - - except Exception, e: - print "get_settings_setup failed due to: %s" % str(e) - assert False - - #this is we don't have to rediscover settings_dir for test and teardown - return [settings_dir], {} - -def get_settings_teardown(settings_dir): - try: - shutil.rmtree(settings_dir, ignore_errors = True) - #restore previous settings dir if any - old_dir = settings_dir + ".tmp" - if os.path.exists(old_dir): - os.rename(old_dir, settings_dir) - except: - #cleanup is best effort - pass - -@with_setup_args.with_setup_args(get_settings_setup, get_settings_teardown) -def test_get_settings(settings_dir): - key = update_manager.get_platform_key() - parent = update_manager.get_parent_path(key) - log_file = update_manager.get_log_file_handle(parent) - got_settings = update_manager.get_settings(log_file, parent) - - assert got_settings, "test_get_settings failed to find a settings.xml file" - - #test one key just to make sure it parsed - assert_equal(got_settings['CurrentGrid']['Value'], 'util.agni.lindenlab.com') diff --git a/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py b/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py deleted file mode 100644 index 5939e5806a..0000000000 --- a/indra/viewer_components/manager/tests/test_make_VVM_UUID_hash.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_make_VVM_UUID_hash.py -@author coyot -@date 2016-06-03 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import update_manager - -def test_make_VVM_UUID_hash(): - #because the method returns different results on different hosts - #it is not easy to unit test it reliably. - #About the best we can do is check for the exception from subprocess - key = update_manager.get_platform_key() - try: - UUID_hash = update_manager.make_VVM_UUID_hash(key) - except Exception, e: - print "Test failed due to: %s" % str(e) - assert False - - #make_UUID_hash returned None - assert UUID_hash, "make_UUID_hash failed to make a hash." diff --git a/indra/viewer_components/manager/tests/test_make_download_dir.py b/indra/viewer_components/manager/tests/test_make_download_dir.py deleted file mode 100644 index e3f9cb83fe..0000000000 --- a/indra/viewer_components/manager/tests/test_make_download_dir.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -""" -@file test_make_download_dir.py -@author coyot -@date 2016-06-03 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import update_manager - -def test_make_download_dir(): - key = update_manager.get_platform_key() - path = update_manager.get_parent_path(key) - version = '1.2.3.456789' - try: - download_dir = update_manager.make_download_dir(path, version) - except OSError, e: - print "make_download_dir failed to eat OSError %s" % str(e) - assert False - except Exception, e: - print "make_download_dir raised an unexpected exception %s" % str(e) - assert False - - assert download_dir, "make_download_dir returned None for path %s and version %s" % (path, version) diff --git a/indra/viewer_components/manager/tests/test_query_vvm.py b/indra/viewer_components/manager/tests/test_query_vvm.py deleted file mode 100644 index 79c8ede480..0000000000 --- a/indra/viewer_components/manager/tests/test_query_vvm.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_query_vvm.py -@author coyot -@date 2016-06-08 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import os -import re -import shutil -import tempfile -import update_manager -import with_setup_args - -def query_vvm_setup(): - tmpdir1 = tempfile.mkdtemp(prefix = 'test1') - handle = update_manager.get_log_file_handle(tmpdir1) - - return [tmpdir1,handle], {} - -def query_vvm_teardown(tmpdir1, handle): - shutil.rmtree(tmpdir1, ignore_errors = True) - -@with_setup_args.with_setup_args(query_vvm_setup, query_vvm_teardown) -def test_query_vvm(tmpdir1, handle): - key = update_manager.get_platform_key() - parent = update_manager.get_parent_path(key) - settings = update_manager.get_settings(handle, parent) - launcher_path = os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))) - summary = update_manager.get_summary(key, launcher_path) - - #for unit testing purposes, just testing a value from results. If no update, then None and it falls through - #for formal QA see: - # https://docs.google.com/document/d/1WNjOPdKlq0j_7s7gdNe_3QlyGnQDa3bFNvtyVM6Hx8M/edit - # https://wiki.lindenlab.com/wiki/Login_Test#Test_Viewer_Updater - #for test plans on all cases, as it requires setting up a fake VVM service - - try: - results = update_manager.query_vvm(handle, key, settings, summary) - except Exception, e: - print "query_vvm threw unexpected exception %s" % str(e) - assert False - - if results: - pattern = re.compile('Second Life') - assert pattern.search(results['channel']), "Bad results returned %s" % str(results) - - assert True diff --git a/indra/viewer_components/manager/tests/test_silent_write.py b/indra/viewer_components/manager/tests/test_silent_write.py deleted file mode 100644 index ad286787e2..0000000000 --- a/indra/viewer_components/manager/tests/test_silent_write.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_silent_write.py -@author coyot -@date 2016-06-02 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import tempfile -import update_manager - -def test_silent_write_to_file(): - test_log = tempfile.TemporaryFile() - try: - update_manager.silent_write(test_log, "This is a test.") - except Exception, e: - print "Test failed due to: %s" % str(e) - assert False - -def test_silent_write_to_null(): - try: - update_manager.silent_write(None, "This is a test.") - except Exception, e: - print "Test failed due to: %s" % str(e) - assert False diff --git a/indra/viewer_components/manager/tests/test_summary.py b/indra/viewer_components/manager/tests/test_summary.py deleted file mode 100644 index f2f2af7347..0000000000 --- a/indra/viewer_components/manager/tests/test_summary.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python - - -""" -@file test_summary.py -@author coyot -@date 2016-06-02 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -from nose.tools import * - -import os.path -import tempfile -import update_manager - -def test_get_summary(): - key = update_manager.get_platform_key() - #launcher is one dir above tests - launcher_path = os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__)))) - summary_json = update_manager.get_summary(key, launcher_path) - - #we aren't testing the JSON library, one key pair is enough - #so we will use the one pair that is actually a constant - assert_equal(summary_json['Type'],'viewer') diff --git a/indra/viewer_components/manager/tests/with_setup_args.py b/indra/viewer_components/manager/tests/with_setup_args.py deleted file mode 100644 index 94d33aa5fe..0000000000 --- a/indra/viewer_components/manager/tests/with_setup_args.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python - -""" -@file with_setup_args.py -@author garyvdm -@date 2016-06-02 - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -def with_setup_args(setup, teardown=None): - """Decorator to add setup and/or teardown methods to a test function:: - @with_setup_args(setup, teardown) - def test_something(): - " ... " - The setup function should return (args, kwargs) which will be passed to - test function, and teardown function. - Note that `with_setup_args` is useful *only* for test functions, not for test - methods or inside of TestCase subclasses. - """ - def decorate(func): - args = [] - kwargs = {} - - def test_wrapped(): - func(*args, **kwargs) - - test_wrapped.__name__ = func.__name__ - - def setup_wrapped(): - a, k = setup() - args.extend(a) - kwargs.update(k) - if hasattr(func, 'setup'): - func.setup() - test_wrapped.setup = setup_wrapped - - if teardown: - def teardown_wrapped(): - if hasattr(func, 'teardown'): - func.teardown() - teardown(*args, **kwargs) - - test_wrapped.teardown = teardown_wrapped - else: - if hasattr(func, 'teardown'): - test_wrapped.teardown = func.teardown() - return test_wrapped - return decorate diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py deleted file mode 100755 index 7962568119..0000000000 --- a/indra/viewer_components/manager/update_manager.py +++ /dev/null @@ -1,547 +0,0 @@ -#!/usr/bin/env python - -"""\ -@file update_manager.py -@author coyot -@date 2016-05-16 -@brief executes viewer update checking and manages downloading and applying of updates - -$LicenseInfo:firstyear=2016&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2016, Linden Research, Inc. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; -version 2.1 of the License only. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -$/LicenseInfo$ -""" - -import os - -#NOTA BENE: -# For POSIX platforms, llbase will be imported from the same directory. -# For Windows, llbase will be compiled into the executable by pyinstaller -try: - from llbase import llrest - from llbase.llrest import RESTError - from llbase import llsd -except: - #if Windows, this is expected, if not, we're dead - if os.name == 'nt': - pass - -from copy import deepcopy -from datetime import datetime -from urlparse import urljoin - -import apply_update -import download_update -import errno -import fnmatch -import hashlib -import InstallerUserMessage -import json -import platform -import re -import shutil -import subprocess -import sys -import tempfile -import thread -import urllib - -def silent_write(log_file_handle, text): - #if we have a log file, write. If not, do nothing. - #this is so we don't have to keep trapping for an exception with a None handle - #oh and because it is best effort, it is also a holey_write ;) - if (log_file_handle): - #prepend text for easy grepping - timestamp = datetime.utcnow().strftime("%Y-%m-%D %H:%M:%S") - log_file_handle.write(timestamp + " UPDATE MANAGER: " + text + "\n") - -def after_frame(message, timeout = 10000): - #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds - #note that this blocks the caller for the duration of timeout - frame = InstallerUserMessage.InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") - #this is done before basic_message so that we aren't blocked by mainloop() - #frame.after(timeout, lambda: frame._delete_window) - frame.after(timeout, lambda: frame.destroy()) - frame.basic_message(message = message) - -def convert_version_file_style(version): - #converts a version string a.b.c.d to a_b_c_d as used in downloaded filenames - #re will throw a TypeError if it gets None, just return that. - try: - pattern = re.compile('\.') - return pattern.sub('_', version) - except TypeError, te: - return None - -def get_platform_key(): - #this is the name that is inserted into the VVM URI - #and carried forward through the rest of the updater to determine - #platform specific actions as appropriate - platform_dict = {'Darwin':'mac', 'Linux':'lnx', 'Windows':'win'} - platform_uname = platform.system() - try: - return platform_dict[platform_uname] - except KeyError: - return None - -def get_summary(platform_name, launcher_path): - #get the contents of the summary.json file. - #for linux and windows, this file is in the same directory as the script - #for mac, the script is in ../Contents/MacOS/ and the file is in ../Contents/Resources/ - script_dir = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) - if (platform_name == 'mac'): - summary_dir = os.path.abspath(os.path.join(script_dir, "../Resources")) - else: - summary_dir = script_dir - summary_file = os.path.join(summary_dir,"summary.json") - with open(summary_file) as summary_handle: - return json.load(summary_handle) - -def get_parent_path(platform_name): - #find the parent of the logs and user_settings directories - if (platform_name == 'mac'): - settings_dir = os.path.join(os.path.expanduser('~'),'Library','Application Support','SecondLife') - elif (platform_name == 'lnx'): - settings_dir = os.path.join(os.path.expanduser('~'),'.secondlife') - #using list format of join is important here because the Windows pathsep in a string escapes the next char - elif (platform_name == 'win'): - settings_dir = os.path.join(os.path.expanduser('~'),'AppData','Roaming','SecondLife') - else: - settings_dir = None - return settings_dir - -def make_download_dir(parent_dir, new_version): - #make a canonical download dir if it does not already exist - #format: ../user_settings/downloads/1.2.3.456789 - #we do this so that multiple viewers on the same host can update separately - #this also functions as a getter - try: - download_dir = os.path.join(parent_dir, "downloads", new_version) - os.makedirs(download_dir) - except OSError, hell: - #Directory already exists, that's okay. Other OSErrors are not okay. - if hell[0] == errno.EEXIST: - pass - else: - raise hell - return download_dir - -def check_for_completed_download(download_dir): - #there will be two files on completion, the download and a marker file called "".done"" - #for optional upgrades, there may also be a .skip file to skip this particular upgrade - #or .next to install on next run - completed = None - marker_regex = '*' + '.done' - skip_regex = '*' + '.skip' - next_regex = '*' + '.next' - for filename in os.listdir(download_dir): - if fnmatch.fnmatch(filename, marker_regex): - completed = 'done' - elif fnmatch.fnmatch(filename, skip_regex): - completed = 'skip' - elif fnmatch.fnmatch(filename, next_regex): - #so we don't skip infinitely - os.remove(filename) - completed = 'next' - if not completed: - #cleanup - shutil.rmtree(download_dir) - return completed - -def get_settings(log_file_handle, parent_dir): - #return the settings file parsed into a dict - try: - settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) - #this happens when the path to settings file happens on the command line - #we get a full path and don't need to munge it - if not os.path.exists(settings_file): - settings_file = parent_dir - settings = llsd.parse((open(settings_file)).read()) - except llsd.LLSDParseError as lpe: - silent_write(log_file_handle, "Could not parse settings file %s" % lpe) - return None - return settings - -def get_log_file_handle(parent_dir, filename = None): - #return a write handle on the log file - #plus log rotation and not dying on failure - if not filename: - return None - log_file = os.path.join(parent_dir, filename) - old_file = log_file + '.old' - #if someone's log files are present but not writable, they've screwed up their install. - if os.access(log_file, os.W_OK): - if os.access(old_file, os.W_OK): - os.unlink(old_file) - os.rename(log_file, old_file) - elif not os.path.exists(log_file): - #reimplement TOUCH(1) in Python - #perms default to 644 which is fine - open(log_file, 'w+').close() - try: - f = open(log_file,'w+') - except Exception as e: - #we don't have a log file to write to, make a best effort and sally onward - print "Could not open update manager log file %s" % log_file - f = None - return f - -def make_VVM_UUID_hash(platform_key): - #NOTE: There is no python library support for a persistent machine specific UUID - # AND all three platforms do this a different way, so exec'ing out is really the best we can do - #Lastly, this is a best effort service. If we fail, we should still carry on with the update - uuid = None - if (platform_key == 'lnx'): - uuid = subprocess.check_output(['/usr/bin/hostid']).rstrip() - elif (platform_key == 'mac'): - #this is absurdly baroque - #/usr/sbin/system_profiler SPHardwareDataType | fgrep 'Serial' | awk '{print $NF}' - uuid = subprocess.check_output(["/usr/sbin/system_profiler", "SPHardwareDataType"]) - #findall[0] does the grep for the value we are looking for: "Serial Number (system): XXXXXXXX" - #split(:)[1] gets us the XXXXXXX part - #lstrip shaves off the leading space that was after the colon - uuid = re.split(":", re.findall('Serial Number \(system\): \S*', uuid)[0])[1].lstrip() - elif (platform_key == 'win'): - # wmic csproduct get UUID | grep -v UUID - uuid = subprocess.check_output(['wmic','csproduct','get','UUID']) - #outputs in two rows: - #UUID - #XXXXXXX-XXXX... - uuid = re.split('\n',uuid)[1].rstrip() - if uuid is not None: - return hashlib.md5(uuid).hexdigest() - else: - #fake it - return hashlib.md5(str(uuid.uuid1())).hexdigest() - -def query_vvm(log_file_handle = None, platform_key = None, settings = None, summary_dict = None, UpdaterServiceURL = None, UpdaterWillingToTest = None): - result_data = None - baseURI = None - #URI template /update/v1.1/channelname/version/platformkey/platformversion/willing-to-test/uniqueid - #https://wiki.lindenlab.com/wiki/Viewer_Version_Manager_REST_API#Viewer_Update_Query - #note that the only two valid options are: - # # version-phx0.damballah.lindenlab.com - # # version-qa.secondlife-staging.com - print "updater service host: " + repr(UpdaterServiceURL) - if UpdaterServiceURL: - #we can't really expect the users to put the protocol or base dir on, they will give us a host - base_URI = urljoin('https://' + UpdaterServiceURL[0], '/update/') - else: - base_URI = 'https://update.secondlife.com/update/' - channelname = summary_dict['Channel'] - #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version in one string - version = summary_dict['Version'] - #we need to use the dotted versions of the platform versions in order to be compatible with VVM rules and arithmetic - if platform_key == 'win': - platform_version = platform.win32_ver()[1] - elif platform_key == 'mac': - platform_version = platform.mac_ver()[0] - else: - platform_version = platform.release() - #this will always return something usable, error handling in method - UUID = str(make_VVM_UUID_hash(platform_key)) - #note that this will not normally be in a settings.xml file and is only here for test builds. - #for test builds, add this key to the ../user_settings/settings.xml - """ - test - - Comment - Tell update manager you aren't willing to test. - Type - String - Value - testno - - - """ - if UpdaterWillingToTest is not None: - if UpdaterWillingToTest: - test_ok = 'testok' - else: - test_ok = 'testno' - else: - try: - test_ok = settings['test']['Value'] - except KeyError: - #normal case, no testing key - test_ok = 'testok' - #because urljoin can't be arsed to take multiple elements - #channelname is a list because although it is only one string, it is a kind of argument and viewer args can take multiple keywords. - query_string = urllib.quote('v1.0/' + channelname[0] + '/' + version + '/' + platform_key + '/' + platform_version + '/' + test_ok + '/' + UUID) - silent_write(log_file_handle, "About to query VVM: %s" % base_URI + query_string) - VVMService = llrest.SimpleRESTService(name='VVM', baseurl=base_URI) - try: - result_data = VVMService.get(query_string) - except RESTError as re: - silent_write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string), re)) - return None - return result_data - -def download(url = None, version = None, download_dir = None, size = 0, background = False, chunk_size = None, log_file_handle = None): - download_tries = 0 - download_success = False - if not chunk_size: - chunk_size = 1024 - #for background execution - path_to_downloader = os.path.join(os.path.dirname(os.path.realpath(__file__)), "download_update.py") - #three strikes and you're out - while download_tries < 3 and not download_success: - #323: Check for a partial update of the required update; in either event, display an alert that a download is required, initiate the download, and then install and launch - if download_tries == 0: - after_frame(message = "Downloading new version " + version + " Please wait.", timeout = 5000) - else: - after_frame(message = "Trying again to download new version " + version + " Please wait.", timeout = 5000) - if not background: - try: - download_update.download_update(url = url, download_dir = download_dir, size = size, progressbar = True, chunk_size = chunk_size) - download_success = True - except Exception, e: - download_tries += 1 - silent_write(log_file_handle, "Failed to download new version " + version + ". Trying again.") - silent_write(log_file_handle, "Logging download exception: %s" % e.message) - else: - try: - #Python does not have a facility to multithread a method, so we make the method a standalone - #and subprocess that - subprocess.call(path_to_downloader, "--url = %s --dir = %s --pb --size = %s --chunk_size = %s" % (url, download_dir, size, chunk_size)) - download_success = True - except: - download_tries += 1 - silent_write(log_file_handle, "Failed to download new version " + version + ". Trying again.") - if not download_success: - silent_write(log_file_handle, "Failed to download new version " + version) - after_frame(message = "Failed to download new version " + version + " Please check connectivity.") - return False - return True - -def install(platform_key = None, download_dir = None, log_file_handle = None, in_place = None, downloaded = None): - #user said no to this one - if downloaded != 'skip': - after_frame(message = "New version downloaded. Installing now, please wait.") - success = apply_update.apply_update(download_dir, platform_key, log_file_handle, in_place) - version = download_dir.split('/')[-1] - if success: - silent_write(log_file_handle, "successfully updated to " + version) - shutil.rmtree(download_dir) - #this is either True for in place or the path to the new install for not in place - return success - else: - after_frame(message = "Failed to apply " + version) - silent_write(log_file_handle, "Failed to update viewer to " + version) - return False - -def download_and_install(downloaded = None, url = None, version = None, download_dir = None, size = None, - platform_key = None, log_file_handle = None, in_place = None, chunk_size = 1024): - #extracted to a method because we do it twice in update_manager() and this makes the logic clearer - if not downloaded: - #do the download, exit if we fail - if not download(url = url, version = version, download_dir = download_dir, size = size, chunk_size = chunk_size, log_file_handle = log_file_handle): - return (False, 'download', version) - #do the install - path_to_new_launcher = install(platform_key = platform_key, download_dir = download_dir, - log_file_handle = log_file_handle, in_place = in_place, downloaded = downloaded) - if path_to_new_launcher: - #if we succeed, propagate the success type upwards - if in_place: - return (True, 'in place', True) - else: - return (True, 'in place', path_to_new_launcher) - else: - #propagate failure - return (False, 'apply', version) - -def update_manager(cli_overrides = None): - #cli_overrides is a dict where the keys are specific parameters of interest and the values are the arguments to - #comments that begin with '323:' are steps taken from the algorithm in the description of SL-323. - # Note that in the interest of efficiency, such as determining download success once at the top - # The code does follow precisely the same order as the algorithm. - #return values rather than exit codes. All of them are to communicate with launcher - #we print just before we return so that __main__ outputs something - returns are swallowed - # (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing) - # (False, 'download', version): we failed to download the new version - # (False, 'apply', version): we failed to apply the new version - # (True, None, None): No update found - # (True, 'in place, True): update applied in place - # (True, 'in place', path_to_new_launcher): Update applied by a new install to a new location - # (True, 'background', True): background download initiated - - #setup and getting initial parameters - platform_key = get_platform_key() - parent_dir = get_parent_path(platform_key) - log_file_handle = get_log_file_handle(parent_dir, 'update_manager.log') - settings = None - - #check to see if user has install rights - #get the owner of the install and the current user - script_owner_id = os.stat(os.path.realpath(__file__)).st_uid - user_id = os.geteuid() - #if we are on lnx or mac, we can pretty print the IDs as names using the pwd module - #win does not provide this support and Python will throw an ImportError there, so just use raw IDs - if script_owner_id != user_id: - if platform_key != 'win': - import pwd - script_owner_name = pwd.getpwuid(script_owner_id)[0] - username = pwd.getpwuid(user_id)[0] - else: - username = user_id - script_owner_name = script_owner_id - silent_write(log_file_handle, "Upgrade notification attempted by userid " + username) - frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") - frame.binary_choice_message(message = "Second Life was installed by userid " + script_owner_name - + ". Do you have privileges to install?", true = "Yes", false = 'No') - if not frame.choice.get(): - silent_write(log_file_handle, "Upgrade attempt declined by userid " + username) - after_frame(message = "Please find a system admin to upgrade Second Life") - print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) - return (False, 'setup', None) - - if cli_overrides is not None: - if 'settings' in cli_overrides.keys(): - if cli_overrides['settings'] is not None: - settings = get_settings(log_file_handle, cli_overrides['settings'][0]) - else: - settings = get_settings(log_file_handle, parent_dir) - - if settings is None: - silent_write(log_file_handle, "Failed to load viewer settings") - print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) - return (False, 'setup', None) - - #323: If a complete download of that update is found, check the update preference: - #settings['UpdaterServiceSetting'] = 0 is manual install - """ - UpdaterServiceSetting - - Comment - Configure updater service. - Type - U32 - Value - 0 - - """ - if cli_overrides is not None: - if 'set' in cli_overrides.keys(): - if 'UpdaterServiceSetting' in cli_overrides['set'].keys(): - install_automatically = cli_overrides['set']['UpdaterServiceSetting'] - else: - try: - install_automatically = settings['UpdaterServiceSetting']['Value'] - #because, for some godforsaken reason, we delete the setting rather than changing the value - except KeyError: - install_automatically = 1 - - #use default chunk size if none is given - if cli_overrides is not None: - if 'set' in cli_overrides.keys(): - if 'UpdaterMaximumBandwidth' in cli_overrides['set'].keys(): - chunk_size = cli_overrides['set']['UpdaterMaximumBandwidth'] - else: - chunk_size = 1024 - else: - chunk_size = 1024 - - #get channel and version - try: - summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) - #we send the override to the VVM, but retain the summary.json version for in_place computations - channel_override_summary = deepcopy(summary_dict) - if cli_overrides is not None: - if 'channel' in cli_overrides.keys(): - channel_override_summary['Channel'] = cli_overrides['channel'] - except Exception, e: - silent_write(log_file_handle, "Could not obtain channel and version, exiting.") - silent_write(log_file_handle, e.message) - print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) - return (False, 'setup', None) - - #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. - if cli_overrides is not None: - if 'update-service' in cli_overrides.keys(): - UpdaterServiceURL = cli_overrides['update-service'] - else: - #tells query_vvm to use the default - UpdaterServiceURL = None - else: - UpdaterServiceURL = None - result_data = query_vvm(log_file_handle, platform_key, settings, channel_override_summary, UpdaterServiceURL) - - #nothing to do or error - if not result_data: - silent_write(log_file_handle, "No update found.") - print "Update manager exited with (%s, %s, %s)" % (True, None, None) - return (True, None, None) - - #get download directory, if there are perm issues or similar problems, give up - try: - download_dir = make_download_dir(parent_dir, result_data['version']) - except Exception, e: - print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None) - return (False, 'setup', None) - - #if the channel name of the response is the same as the channel we are launched from, the update is "in place" - #and launcher will launch the viewer in this install location. Otherwise, it will launch the Launcher from - #the new location and kill itself. - in_place = (summary_dict['Channel'] == result_data['channel']) - print "summary %s, result %s, in_place %s" % (summary_dict['Channel'], result_data['channel'], in_place) - - #determine if we've tried this download before - downloaded = check_for_completed_download(download_dir) - - #323: If the response indicates that there is a required update: - if result_data['required'] or (not result_data['required'] and install_automatically): - #323: Check for a completed download of the required update; if found, display an alert, install the required update, and launch the newly installed viewer. - #323: If [optional download and] Install Automatically: display an alert, install the update and launch updated viewer. - return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, - size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place, chunk_size = chunk_size) - else: - #323: If the update response indicates that there is an optional update: - #323: Check to see if the optional update has already been downloaded. - #323: If a complete download of that update is found, check the update preference: - #note: automatic install handled above as the steps are the same as required upgrades - #323: If Install Manually: display a message with the update information and ask the user whether or not to install the update with three choices: - #323: Skip this update: create a marker that subsequent launches should not prompt for this update as long as it is optional, - # but leave the download in place so that if it becomes required it will be there. - #323: Install next time: create a marker that skips the prompt and installs on the next launch - #323: Install and launch now: do it. - if downloaded is not None and downloaded != 'skip': - frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") - #The choices are reordered slightly to encourage immediate install and slightly discourage skipping - frame.trinary_message(message = "Please make a selection", - one = "Install new version now.", two = 'Install the next time the viewer is launched.', three = 'Skip this update.') - choice = frame.choice.get() - if choice == 1: - return download_and_install(downloaded = downloaded, url = result_data['url'], version = result_data['version'], download_dir = download_dir, - size = result_data['size'], platform_key = platform_key, log_file_handle = log_file_handle, in_place = in_place, chunk_size = chunk_size) - elif choice == 2: - tempfile.mkstmp(suffix = ".next", dir = download_dir) - return (True, None, None) - else: - tempfile.mkstmp(suffix = ".skip", dir = download_dir) - return (True, None, None) - else: - #multithread a download - download(url = result_data['url'], version = result_data['version'], download_dir = download_dir, size = result_data['size'], background = True, log_file_handle = log_file_handle) - print "Update manager exited with (%s, %s, %s)" % (True, 'background', True) - return (True, 'background', True) - - -if __name__ == '__main__': - #there is no argument parsing or other main() work to be done - update_manager() From a50a2e170d4cf99507d2dd974aed7f73424376cf Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 1 Mar 2017 11:01:40 -0800 Subject: [PATCH 048/183] SL-321: fix merge removal of mIsFirstRun definition, remove pyinstaller from viewer cmake, now in VMP package cmake --- indra/newview/CMakeLists.txt | 50 ------------------------------------ indra/newview/llappviewer.h | 2 ++ 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 394a9c8578..9badc95a72 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1758,56 +1758,6 @@ if (WINDOWS) endif (FMODEX) get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY) - - # http://pythonhosted.org/PyInstaller/#options - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SL_Launcher.exe - COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe - ARGS - --onefile - --log-level WARN - --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - ${CMAKE_SOURCE_DIR}/viewer_components/manager/SL_Launcher - COMMENT "Performing pyinstaller compile of SL_Launcher" -) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/apply_update.exe - COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe - ARGS - --onefile - --log-level WARN - --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - ${CMAKE_SOURCE_DIR}/viewer_components/manager/apply_update.py - COMMENT "Performing pyinstaller compile of updater" -) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/download_update.exe - COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe - ARGS - --onefile - --log-level WARN - --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - ${CMAKE_SOURCE_DIR}/viewer_components/manager/download_update.py - COMMENT "Performing pyinstaller compile of update downloader" -) - - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/update_manager.exe - COMMAND ${PYTHON_DIRECTORY}/Scripts/pyinstaller.exe - ARGS - --onefile - --log-level WARN - --distpath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - ${CMAKE_SOURCE_DIR}/viewer_components/manager/update_manager.py - COMMENT "Performing pyinstaller compile of update manager" -) - -add_custom_target(compile_w_viewer_launcher ALL DEPENDS ${CMAKE_CFG_INTDIR}/SL_Launcher.exe) -add_custom_target(compile_w_viewer_updater ALL DEPENDS ${CMAKE_CFG_INTDIR}/apply_update.exe) -add_custom_target(compile_w_viewer_downloader ALL DEPENDS ${CMAKE_CFG_INTDIR}/download_update.exe) -add_custom_target(compile_w_viewer_update_manager ALL DEPENDS ${CMAKE_CFG_INTDIR}/update_manager.exe) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 91d79c4260..272209fc79 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -313,6 +313,8 @@ private: // llcorehttp library init/shutdown helper LLAppCoreHttp mAppCoreHttp; + bool mIsFirstRun; + }; // consts from viewer.h From 9ec3b1bb039bdb40fce6aee66ce68ce8cabfb785 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 1 Mar 2017 13:19:34 -0800 Subject: [PATCH 049/183] SL-321: fix merge removal of llhasheduniqueid from from llloginstance_test's include path --- indra/newview/tests/lllogininstance_test.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 55dcb83567..5397feeab8 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -31,6 +31,9 @@ #include "../llviewernetwork.h" #include "../lllogininstance.h" + // Needed for Auth Test + #include "../llhasheduniqueid.h" + // STL headers // std headers // external library headers From 49552a874c659a7e4864e276f4250d498676a559 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 1 Mar 2017 23:28:11 -0800 Subject: [PATCH 050/183] SL-321: remove redundant const declaration of MD5HEX_STR_SIZE in llversioninfo, remove extraneous python variable assignment in CMakeLists, run tests with INFO --- indra/cmake/run_build_test.py | 2 +- indra/newview/CMakeLists.txt | 2 -- indra/newview/tests/lllogininstance_test.cpp | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index f02c5e98b4..210e43b232 100755 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -312,7 +312,7 @@ if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("-d", "--debug", dest="loglevel", action="store_const", - const=logging.DEBUG, default=logging.WARNING) + const=logging.DEBUG, default=logging.INFO) parser.add_argument("-D", "--define", dest="vars", default=[], action="append", metavar="VAR=value", help="Add VAR=value to the env variables defined") diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9badc95a72..fe360171fb 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1756,8 +1756,6 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll ) endif (FMODEX) - - get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY) add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index 5397feeab8..3b7ec48d61 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -190,7 +190,6 @@ void LLUIColorTable::saveUserSettings(void)const {} #include "../llversioninfo.h" const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; } const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; } -const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null bool llHashedUniqueID(unsigned char* id) { From 9c5332b301c0e17cd0133944670f79fd485cf7fe Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 6 Mar 2017 14:43:57 -0800 Subject: [PATCH 051/183] SL-321: reintegration of autobuild as package, build changes for mac integration --- autobuild.xml | 46 ++++++++++++++++++++++ indra/newview/CMakeLists.txt | 1 + indra/newview/llversioninfo.cpp | 1 + indra/newview/tests/llversioninfo_test.cpp | 6 ++- indra/newview/viewer_manifest.py | 46 ++++++++-------------- 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index a655c7cae2..2f7ad05ecd 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3023,6 +3023,52 @@ version 0.8.0.1 + viewer-manager + + copyright + Copyright (c) 2000-2012, Linden Research, Inc. + description + Linden Lab Viewer Management Process suite. + license + Proprietary + license_file + LICENSE + name + viewer-manager + platforms + + darwin64 + + archive + + hash + b7a7d155a70413bce9a7a25ad54c37e7 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3073/7235/viewer_manager-1.0-darwin64-503061.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + 0c1a369a3e5ed6363a306e6135797851 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3074/7241/viewer_manager-1.0-windows-503061.tar.bz2 + + name + windows + + + source + https://bitbucket.org/lindenlab/vmp-standalone + source_type + hg + version + 1.0 + vlc-bin copyright diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fe360171fb..7a62d8baec 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -47,6 +47,7 @@ include(TemplateCheck) include(UI) include(UnixInstall) include(ViewerMiscLibs) +include(ViewerManager) include(VisualLeakDetector) include(ZLIB) include(URIPARSER) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 375dce485d..bf9d98ee91 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -64,6 +64,7 @@ S32 LLVersionInfo::getPatch() //static S32 LLVersionInfo::getBuild() { + std::cout << "What we have IN llversioninfo: " << LL_VIEWER_VERSION_BUILD << std::endl; return LL_VIEWER_VERSION_BUILD; } diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index f1f69f33f1..2f7a4e9601 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -29,6 +29,8 @@ #include "../llversioninfo.h" + #include + // LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The // macro expands to the string name of the channel, but without quotes. We // need to turn it into a quoted string. This macro trick does that. @@ -81,7 +83,9 @@ namespace tut template<> template<> void versioninfo_object_t::test<1>() - { + { + std::cout << "What we parsed from CMake: " << LL_VIEWER_VERSION_BUILD << std::endl; + std::cout << "What we get from llversioninfo: " << LLVersionInfo::getBuild() << std::endl; ensure_equals("Major version", LLVersionInfo::getMajor(), LL_VIEWER_VERSION_MAJOR); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 35d63c33fc..1dc178dcf8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -223,7 +223,7 @@ class ViewerManifest(LLManifest): return channel_type def channel_variant_app_suffix(self): - # get any part of the compiled channel name after the CHANNEL_VENDOR_BASE + # get any part of the channel name after the CHANNEL_VENDOR_BASE suffix=self.channel_variant() # by ancient convention, we don't use Release in the app name if self.channel_type() == 'release': @@ -346,15 +346,12 @@ class WindowsManifest(ViewerManifest): if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) - # include the compiled launcher script so that it gets included in the file_list - self.path(src='%s/SL_Launcher.exe' % self.args['configuration'], dst="SL_Launcher.exe") # Plugin host application self.path2basename(os.path.join(os.pardir, 'llplugin', 'slplugin', self.args['configuration']), "slplugin.exe") - #note, launcher and friends do not need viewer_manifest in Windows as the scripts are compiled into executables # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): @@ -709,28 +706,29 @@ class DarwinManifest(ViewerManifest): pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") - llbasedir = os.path.join(pkgdir, os.pardir) + vmpdir = os.path.join(pkgdir, "VMP") + llbasedir = os.path.join(pkgdir, "VMP") if self.prefix(src="", dst="Contents"): # everything goes in Contents self.path("Info.plist", dst="Info.plist") # copy additional libs in /Contents/MacOS/ self.path(os.path.join(relpkgdir, "libndofdev.dylib"), dst="Resources/libndofdev.dylib") - self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") + self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") if self.prefix(dst="MacOS"): - self.path2basename("../viewer_components/updater/scripts/darwin", "*.py") #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 - self.path2basename("../viewer_components/manager","SL_Launcher") - self.path2basename("../viewer_components/manager","*.py") + self.path2basename(vmpdir,"SL_Launcher") + self.path2basename(vmpdir,"*.py") llbase_path = os.path.join(self.get_dst_prefix(),'llbase') if not os.path.exists(llbase_path): os.makedirs(llbase_path) + #before, we only needed llbase at build time. With VMP, we need it at run time. if self.prefix(dst="llbase"): - self.path2basename("../packages/llbase","*.py") - self.path2basename("../packages/llbase","_cllsd.so") + self.path2basename(llbasedir,"*.py") + self.path2basename(llbasedir,"_cllsd.so") self.end_prefix() - self.end_prefix() + self.end_prefix() # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): @@ -749,6 +747,12 @@ class DarwinManifest(ViewerManifest): self.path("secondlife.icns") self.end_prefix(icon_path) + #VMP Tkinter icons + if self.prefix("vmp_icons"): + self.path("*.png") + self.path("*.gif") + self.end_prefix("vmp_icons") + self.path("SecondLife.nib") # Translations @@ -773,12 +777,6 @@ class DarwinManifest(ViewerManifest): self.path("uk.lproj") self.path("zh-Hans.lproj") - #VMP icons - if self.prefix("vmp_icons"): - self.path("*.png") - self.path("*.gif") - self.end_prefix("vmp_icons") - def path_optional(src, dst): """ For a number of our self.path() calls, not only do we want @@ -1145,17 +1143,7 @@ class LinuxManifest(ViewerManifest): if self.prefix(src="", dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") - self.path2basename("../llplugin/slplugin", "SLPlugin") - #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 - self.path2basename("../viewer_components/manager","SL_Launcher") - self.path2basename("../viewer_components/manager","*.py") - llbase_path = os.path.join(self.get_dst_prefix(),'llbase') - if not os.path.exists(llbase_path): - os.makedirs(llbase_path) - if self.prefix(dst="llbase"): - self.path2basename("../packages/llbase","*.py") - self.path2basename("../packages/llbase","_cllsd.so") - self.end_prefix() + self.path2basename("../llplugin/slplugin", "SLPlugin") self.end_prefix("bin") if self.prefix("res-sdl"): From b69831b691e72f925c6097cf8bfa529be23b806d Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 6 Mar 2017 15:36:50 -0800 Subject: [PATCH 052/183] SL-321: add new ViewerManager.cmake file, knowingly overriding commit hooks --- indra/cmake/ViewerManager.cmake | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 indra/cmake/ViewerManager.cmake diff --git a/indra/cmake/ViewerManager.cmake b/indra/cmake/ViewerManager.cmake new file mode 100644 index 0000000000..793ed78b6c --- /dev/null +++ b/indra/cmake/ViewerManager.cmake @@ -0,0 +1,2 @@ +include (Prebuilt) +use_prebuilt_binary(viewer-manager) \ No newline at end of file From cf8dc0d97a2a34c038d1bedc5d0fd7a1badbcd86 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 7 Mar 2017 15:05:42 -0800 Subject: [PATCH 053/183] SL-321: reintegration of autobuild as package, build changes for linux and windows integration --- indra/newview/viewer_manifest.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 1dc178dcf8..8c51719031 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -346,6 +346,13 @@ class WindowsManifest(ViewerManifest): if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) + # include the compiled launcher scripts so that it gets included in the file_list + self.path(src='%s/apply_update.exe' % self.args['configuration'], dst="apply_update.exe") + self.path(src='%s/download_update.exe' % self.args['configuration'], dst="download_update.exe") + self.path(src='%s/SL_Launcher.exe' % self.args['configuration'], dst="SL_Launcher.exe") + self.path(src='%s/update_manager.exe' % self.args['configuration'], dst="update_manager.exe") + #IUM is not normally executed directly, just imported. No exe needed. + self.path2basename("../viewer_components/manager","InstallerUserMessage.py") # Plugin host application self.path2basename(os.path.join(os.pardir, @@ -677,7 +684,17 @@ class WindowsManifest(ViewerManifest): if not python or python == "${PYTHON}": python = 'python' if os.path.exists(sign_py): + print "about to run signing of: ", self.dst_path_of(installer_file).replace('\\', '\\\\\\\\') self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of(installer_file).replace('\\', '\\\\\\\\'))) + #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. + print "about to run signing of: ", self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\'))) else: print "Skipping code signing,", sign_py, "does not exist" self.created_path(self.dst_path_of(installer_file)) @@ -1143,7 +1160,16 @@ class LinuxManifest(ViewerManifest): if self.prefix(src="", dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") - self.path2basename("../llplugin/slplugin", "SLPlugin") + self.path2basename("../llplugin/slplugin", "SLPlugin") + #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 + self.path2basename("../viewer_components/manager","SL_Launcher") + self.path2basename("../viewer_components/manager","*.py") + llbase_path = os.path.join(self.get_dst_prefix(),'llbase') + if not os.path.exists(llbase_path): + os.makedirs(llbase_path) + if self.prefix(dst="llbase"): + self.path2basename("../packages/llbase","*.py") + self.path2basename("../packages/llbase","_cllsd.so") self.end_prefix("bin") if self.prefix("res-sdl"): From c69db33ded0a860060a9702495cfcddc26008d09 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 8 Mar 2017 12:34:11 -0800 Subject: [PATCH 054/183] SL-321: fix windows pathing, add icons --- indra/newview/viewer_manifest.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 8c51719031..4fbdc52e30 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -342,17 +342,23 @@ class WindowsManifest(ViewerManifest): pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") + vmpdir = os.path.join(pkgdir, "VMP") if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) # include the compiled launcher scripts so that it gets included in the file_list - self.path(src='%s/apply_update.exe' % self.args['configuration'], dst="apply_update.exe") - self.path(src='%s/download_update.exe' % self.args['configuration'], dst="download_update.exe") - self.path(src='%s/SL_Launcher.exe' % self.args['configuration'], dst="SL_Launcher.exe") - self.path(src='%s/update_manager.exe' % self.args['configuration'], dst="update_manager.exe") + self.path(src='%s/apply_update.exe' % vmpdir, dst="apply_update.exe") + self.path(src='%s/download_update.exe' % vmpdir, dst="download_update.exe") + self.path(src='%s/SL_Launcher.exe' % vmpdir, dst="SL_Launcher.exe") + self.path(src='%s/update_manager.exe' % vmpdir, dst="update_manager.exe") #IUM is not normally executed directly, just imported. No exe needed. - self.path2basename("../viewer_components/manager","InstallerUserMessage.py") + self.path2basename(vmpdir,"InstallerUserMessage.py") + #VMP Tkinter icons + if self.prefix("vmp_icons"): + self.path("*.png") + self.path("*.gif") + self.end_prefix("vmp_icons") # Plugin host application self.path2basename(os.path.join(os.pardir, From 2e011225754192cc35af8438d898da55a8596904 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 9 Mar 2017 10:28:16 -0800 Subject: [PATCH 055/183] SL-321: add local llbase support for Windows --- indra/newview/viewer_manifest.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 4fbdc52e30..da641e920c 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -343,23 +343,36 @@ class WindowsManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") + llbasedir = os.path.join(pkgdir, "VMP") if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) + # include the compiled launcher scripts so that it gets included in the file_list self.path(src='%s/apply_update.exe' % vmpdir, dst="apply_update.exe") self.path(src='%s/download_update.exe' % vmpdir, dst="download_update.exe") self.path(src='%s/SL_Launcher.exe' % vmpdir, dst="SL_Launcher.exe") self.path(src='%s/update_manager.exe' % vmpdir, dst="update_manager.exe") + #IUM is not normally executed directly, just imported. No exe needed. self.path2basename(vmpdir,"InstallerUserMessage.py") + #VMP Tkinter icons if self.prefix("vmp_icons"): self.path("*.png") self.path("*.gif") self.end_prefix("vmp_icons") + #before, we only needed llbase at build time. With VMP, we need it at run time. + llbase_path = os.path.join(self.get_dst_prefix(),'llbase') + if not os.path.exists(llbase_path): + os.makedirs(llbase_path) + if self.prefix(dst="llbase"): + self.path2basename(llbasedir,"*.py") + self.path2basename(llbasedir,"_cllsd.so") + self.end_prefix() + # Plugin host application self.path2basename(os.path.join(os.pardir, 'llplugin', 'slplugin', self.args['configuration']), From 8cbaaa364f6bfd01aeb4280689e2f883a5ffed53 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 10 Mar 2017 09:23:35 -0800 Subject: [PATCH 056/183] SL-321: add new VMP package, fix llbase path --- autobuild.xml | 8 ++++---- indra/newview/viewer_manifest.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 2f7ad05ecd..3b204f6778 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - b7a7d155a70413bce9a7a25ad54c37e7 + 7a3628c40ece889413cc6991d31752ab url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3073/7235/viewer_manager-1.0-darwin64-503061.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3208/7750/viewer_manager-1.0-darwin64-503197.tar.bz2 name darwin64 @@ -3054,9 +3054,9 @@ archive hash - 0c1a369a3e5ed6363a306e6135797851 + 607b45e6d5e206594fcf8e7ed5783d49 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3074/7241/viewer_manager-1.0-windows-503061.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3209/7756/viewer_manager-1.0-windows-503197.tar.bz2 name windows diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index da641e920c..60ee7728ab 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -343,7 +343,7 @@ class WindowsManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - llbasedir = os.path.join(pkgdir, "VMP") + llbasedir = os.path.join(pkgdir, "llbase") if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. @@ -743,7 +743,7 @@ class DarwinManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - llbasedir = os.path.join(pkgdir, "VMP") + llbasedir = os.path.join(pkgdir, "llbase") if self.prefix(src="", dst="Contents"): # everything goes in Contents self.path("Info.plist", dst="Info.plist") From faa36236ed7600108af1e4f01f313fcac8f0bca2 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 13 Mar 2017 20:23:31 -0700 Subject: [PATCH 057/183] SL-361: update VMP package --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3b204f6778..ea690837ae 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - 7a3628c40ece889413cc6991d31752ab + 62d55bc21b56dbd7a7f06429d008b81f url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3208/7750/viewer_manager-1.0-darwin64-503197.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3341/8290/viewer_manager-1.0-darwin64-503329.tar.bz2 name darwin64 @@ -3054,9 +3054,9 @@ archive hash - 607b45e6d5e206594fcf8e7ed5783d49 + b97eb0662b558be20df9b11031d38274 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3209/7756/viewer_manager-1.0-windows-503197.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3340/8284/viewer_manager-1.0-windows-503329.tar.bz2 name windows From 3052fa4241e2eba08ab7a68479d979726f6ccd8e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 13 Mar 2017 23:26:15 -0700 Subject: [PATCH 058/183] SL-361: update VMP package --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ea690837ae..30de9a674e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - 62d55bc21b56dbd7a7f06429d008b81f + 0a1efab5a2b620af2490bebaf634af44 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3341/8290/viewer_manager-1.0-darwin64-503329.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3347/8316/viewer_manager-1.0-darwin64-503336.tar.bz2 name darwin64 @@ -3054,9 +3054,9 @@ archive hash - b97eb0662b558be20df9b11031d38274 + 816d310423874dc7c2efd1001b651a42 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3340/8284/viewer_manager-1.0-windows-503329.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3349/8322/viewer_manager-1.0-windows-503336.tar.bz2 name windows From 07ef9137c89bb2d1a8535553f30f6cd3a3526a60 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 14 Mar 2017 15:36:20 -0700 Subject: [PATCH 059/183] SL-321: add new VMP package --- autobuild.xml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 30de9a674e..b81988b938 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,21 +3042,33 @@ archive hash - 0a1efab5a2b620af2490bebaf634af44 + a052f61016dba6afce7d50fc9babd0d8 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3347/8316/viewer_manager-1.0-darwin64-503336.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3412/8596/viewer_manager-1.0-darwin64-503400.tar.bz2 name darwin64 + linux + + archive + + hash + 05ae56a3713705187ffe7307559e0a03 + url + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3411/8590/viewer_manager-1.0-linux-503400.tar.bz2 + + name + linux + windows archive hash - 816d310423874dc7c2efd1001b651a42 + 8c84007e7bd10e39c091a529a39340a9 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3349/8322/viewer_manager-1.0-windows-503336.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3413/8602/viewer_manager-1.0-windows-503400.tar.bz2 name windows From 96790c80566c3ddfb4f6ca6817bd5691e6a7186e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 14 Mar 2017 17:40:23 -0700 Subject: [PATCH 060/183] SL-321: add new VMP package 503410 --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b81988b938..4387740ebd 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - a052f61016dba6afce7d50fc9babd0d8 + e0375687eb78f0b3b4d30194583a871a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3412/8596/viewer_manager-1.0-darwin64-503400.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3422/8654/viewer_manager-1.0-darwin64-503410.tar.bz2 name darwin64 @@ -3054,9 +3054,9 @@ archive hash - 05ae56a3713705187ffe7307559e0a03 + 8795127b83ead8bc99168df4a42830da url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3411/8590/viewer_manager-1.0-linux-503400.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3421/8648/viewer_manager-1.0-linux-503410.tar.bz2 name linux @@ -3066,9 +3066,9 @@ archive hash - 8c84007e7bd10e39c091a529a39340a9 + 28f00eea2162c1094408d284a4c35efa url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3413/8602/viewer_manager-1.0-windows-503400.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3423/8660/viewer_manager-1.0-windows-503410.tar.bz2 name windows From ca9935f1306d33382cc2cabc747a561d96692b61 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 14 Mar 2017 20:49:33 -0700 Subject: [PATCH 061/183] SL-321: add new VMP package 503417 --- autobuild.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4387740ebd..63fac36752 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - e0375687eb78f0b3b4d30194583a871a + 1fd8b5e57be0677d28383b95ea559223 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3422/8654/viewer_manager-1.0-darwin64-503410.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3429/8692/viewer_manager-1.0-darwin64-503417.tar.bz2 name darwin64 @@ -3054,9 +3054,9 @@ archive hash - 8795127b83ead8bc99168df4a42830da + 8c7f32f85850248809ae811ba8e47d81 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3421/8648/viewer_manager-1.0-linux-503410.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3428/8686/viewer_manager-1.0-linux-503417.tar.bz2 name linux @@ -3066,9 +3066,9 @@ archive hash - 28f00eea2162c1094408d284a4c35efa + 692da90cb43d1fdc21c534facc017b81 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3423/8660/viewer_manager-1.0-windows-503410.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3430/8698/viewer_manager-1.0-windows-503417.tar.bz2 name windows From 455412c3958f85b202c9f2662695543da39e7db5 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 15 Mar 2017 09:41:13 -0700 Subject: [PATCH 062/183] SL-321: add new VMP package 503461 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 63fac36752..e226c452dd 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - 1fd8b5e57be0677d28383b95ea559223 + 786dc981a37eefa403ac5ad02d2700e1 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3429/8692/viewer_manager-1.0-darwin64-503417.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3473/8879/viewer_manager-1.0-darwin64-503461.tar.bz2 name darwin64 @@ -3066,9 +3066,9 @@ archive hash - 692da90cb43d1fdc21c534facc017b81 + 5fbb43e8f6aaf4dbf18d1cf501cb28b3 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3430/8698/viewer_manager-1.0-windows-503417.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3474/8885/viewer_manager-1.0-windows-503461.tar.bz2 name windows From ed5fda3271acf7917ea3ccc3aedab6f5a9401953 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 15 Mar 2017 18:49:24 -0700 Subject: [PATCH 063/183] SL-321: add new VMP package 50513 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e226c452dd..59fdea21b8 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3042,9 +3042,9 @@ archive hash - 786dc981a37eefa403ac5ad02d2700e1 + db1da9e5c06338c2f37d781b42d41e54 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3473/8879/viewer_manager-1.0-darwin64-503461.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3525/9029/viewer_manager-1.0-darwin64-503513.tar.bz2 name darwin64 @@ -3066,9 +3066,9 @@ archive hash - 5fbb43e8f6aaf4dbf18d1cf501cb28b3 + a431b47b3d6fd8798ae6f99867d8f058 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3474/8885/viewer_manager-1.0-windows-503461.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3526/9035/viewer_manager-1.0-windows-503513.tar.bz2 name windows From 4992654682255a6cace1c5ee86b4b8bf28fde15d Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 16 Mar 2017 15:45:52 -0700 Subject: [PATCH 064/183] merge cleanup --- indra/newview/llappviewer.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 242266eac5..b4cb094877 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5500,20 +5500,6 @@ void LLAppViewer::handleLoginComplete() mSavePerAccountSettings=true; } -/** -* Check if user is running a new version of the viewer. -* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting. -*/ -void LLAppViewer::showReleaseNotesIfRequired() -{ - if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion - && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") - && !gSavedSettings.getBOOL("FirstLoginThisInstall")) - { - LLSD info(getViewerInfo()); - LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]); - } -} //virtual void LLAppViewer::setMasterSystemAudioMute(bool mute) { From f9a7960d181e2a800b79d08a523534b6ca044e7a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 21 Mar 2017 07:43:36 -0700 Subject: [PATCH 065/183] update VMP package 503604 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 350e6831cc..e480716b38 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3026,9 +3026,9 @@ archive hash - db1da9e5c06338c2f37d781b42d41e54 + 9be0f78616ad2be08fc62dfe6c399839 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3525/9029/viewer_manager-1.0-darwin64-503513.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3616/9365/viewer_manager-1.0-darwin64-503604.tar.bz2 name darwin64 @@ -3050,9 +3050,9 @@ archive hash - a431b47b3d6fd8798ae6f99867d8f058 + 27166e0af5ee896e2efbd97bd5bb8b3e url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3526/9035/viewer_manager-1.0-windows-503513.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3617/9371/viewer_manager-1.0-windows-503604.tar.bz2 name windows From 5cb34738574f6dff15a51258dbf4fc43b57099ae Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 21 Mar 2017 13:58:22 -0700 Subject: [PATCH 066/183] SL-321 MAINT-7192: add viewer bitness VMM fetch logic to VMP, including HD Graphcis test --- indra/newview/viewer_manifest.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index af97bb4728..770567f13d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -121,6 +121,24 @@ class ViewerManifest(LLManifest): settings_install['CmdLineGridChoice']['Value'] = self.grid() print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid() + #do not need to test for existence. If no platform is passed, llmanifest computes a default in get_default_platform + #the choice of value names (lnx, mac, win32, win) is dictated by the VMM API + summary_json_platform = "" + if 'linux' in self.args['platform']: + summary_json_platform = 'lnx' + elif 'darwin' in self.args['platform']: + summary_json_platform = 'mac' + elif 'windows' in self.args['platform']: + #default case + summary_json_platform = 'win' + if 'arch' in self.args and self.args['arch']: + if 'i686' in self.args['arch']: + summary_json_platform = 'win32' + #we really shouldn't be here, something is very wrong at this point + else: + summary_json_platform = 'None' + + # put_in_file(src=) need not be an actual pathname; it # only needs to be non-empty self.put_in_file(llsd.format_pretty_xml(settings_install), @@ -184,7 +202,10 @@ class ViewerManifest(LLManifest): self.path("gpu_table.txt") #summary.json. Standard with exception handling is fine. If we can't open a new file for writing, we have worse problems - summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']),"Channel":self.channel_with_pkg_suffix()} + #platform is computed above with other arg parsing + summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']), + "Channel":self.channel_with_pkg_suffix(), + "Platform":summary_json_platform} with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle: json.dump(summary_dict,summary_handle) From 43f5297dfaea24360b2fe11beb1e9913724ea871 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 21 Mar 2017 14:48:45 -0700 Subject: [PATCH 067/183] update VMP package 503633 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e480716b38..1aebbf2b53 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3026,9 +3026,9 @@ archive hash - 9be0f78616ad2be08fc62dfe6c399839 + 519bbd83a77bfeda499b45b8a84092b3 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3616/9365/viewer_manager-1.0-darwin64-503604.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3645/9477/viewer_manager-1.0-darwin64-503633.tar.bz2 name darwin64 @@ -3050,9 +3050,9 @@ archive hash - 27166e0af5ee896e2efbd97bd5bb8b3e + b0d9c7c04078a923a6b6f47286c42d7c url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3617/9371/viewer_manager-1.0-windows-503604.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3646/9483/viewer_manager-1.0-windows-503633.tar.bz2 name windows From 59a4eacb425bbae34d7213e6293c76b6861b97e3 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 22 Mar 2017 12:13:36 -0700 Subject: [PATCH 068/183] SL-321: upgrade to VMP package 503622 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1aebbf2b53..9f9bdc677e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3026,9 +3026,9 @@ archive hash - 519bbd83a77bfeda499b45b8a84092b3 + 348e055c13ce6171cba40ac2733eaa49 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3645/9477/viewer_manager-1.0-darwin64-503633.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3674/9596/viewer_manager-1.0-darwin64-503662.tar.bz2 name darwin64 @@ -3050,9 +3050,9 @@ archive hash - b0d9c7c04078a923a6b6f47286c42d7c + b4ba150897c71af585a2dd9aee61101a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3646/9483/viewer_manager-1.0-windows-503633.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3675/9602/viewer_manager-1.0-windows-503662.tar.bz2 name windows From 7107eb8db4f703fa64a2a01392ba8ca843d9be95 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 22 Mar 2017 14:52:30 -0700 Subject: [PATCH 069/183] remove stray debug message --- indra/newview/llversioninfo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index bf9d98ee91..375dce485d 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -64,7 +64,6 @@ S32 LLVersionInfo::getPatch() //static S32 LLVersionInfo::getBuild() { - std::cout << "What we have IN llversioninfo: " << LL_VIEWER_VERSION_BUILD << std::endl; return LL_VIEWER_VERSION_BUILD; } From d320d3501791bd66b7949b9650db447656e817f1 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 24 Mar 2017 13:32:57 -0700 Subject: [PATCH 070/183] SL-321: upgrade VMP package 503733 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9f9bdc677e..84aed54b0e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3026,9 +3026,9 @@ archive hash - 348e055c13ce6171cba40ac2733eaa49 + 62e8464a3d020075266e3f8dbb4e89be url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3674/9596/viewer_manager-1.0-darwin64-503662.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3745/9922/viewer_manager-1.0-darwin64-503733.tar.bz2 name darwin64 @@ -3050,9 +3050,9 @@ archive hash - b4ba150897c71af585a2dd9aee61101a + 1e5cd892526b78ba174feb65b0653d4b url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3675/9602/viewer_manager-1.0-windows-503662.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3746/9929/viewer_manager-1.0-windows-503733.tar.bz2 name windows From 7ad8cd7979f591c802a8dfcc1f5d936558dd665c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 28 Mar 2017 09:40:29 -0700 Subject: [PATCH 071/183] dummy commit to bump build --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 6eddb9aa9e..b80277370a 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,3 @@ To download the current default version, visit [the download page](https://secondlife.com/support/downloads). For even newer versions try [the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers) - From bf121a1e55a0475c4614946b9c87d1d0af586e2b Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 29 Mar 2017 08:25:46 -0700 Subject: [PATCH 072/183] dummy commit to bump build --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b80277370a..6eddb9aa9e 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,4 @@ To download the current default version, visit [the download page](https://secondlife.com/support/downloads). For even newer versions try [the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers) + From 94924e4bc5b89e235122d0c1fcdf917d04374b5a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 29 Mar 2017 11:45:28 -0700 Subject: [PATCH 073/183] dummy commit to bump build (pyinstaller dev tip now in both 32 and 64) --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 6eddb9aa9e..b80277370a 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,3 @@ To download the current default version, visit [the download page](https://secondlife.com/support/downloads). For even newer versions try [the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers) - From c417b2637a866fb4f47bd60c201cdf24d060251e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 29 Mar 2017 13:13:26 -0700 Subject: [PATCH 074/183] SL-323: cherry pick menu changes lost in v64 merge, viewer-management-process-sl-321 rev 36267 --- indra/newview/llfloaterabout.cpp | 96 +++++++++++++++++++ .../skins/default/xui/en/notifications.xml | 5 +- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index de2d595fb1..1b85f645e8 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -62,6 +62,7 @@ #include "llsdutil_math.h" #include "lleventapi.h" #include "llcorehttputil.h" +#include "lldir.h" #if LL_WINDOWS #include "lldxhardware.h" @@ -89,6 +90,7 @@ public: static LLSD getInfo(); void onClickCopyToClipboard(); void onClickUpdateCheck(); + void setUpdateListener(); private: void setSupportText(const std::string& server_release_notes_url); @@ -98,6 +100,9 @@ private: // callback method for manual checks static bool callbackCheckUpdate(LLSD const & event); + + // listener name for update checks + static const std::string sCheckUpdateListenerName; static void startFetchServerReleaseNotes(); static void fetchServerReleaseNotesCoro(const std::string& cap_url); @@ -131,6 +136,9 @@ BOOL LLFloaterAbout::postBuild() getChild("copy_btn")->setCommitCallback( boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this)); + + getChild("update_btn")->setCommitCallback( + boost::bind(&LLFloaterAbout::setUpdateListener, this)); static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor"); @@ -326,6 +334,94 @@ void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url) FALSE, LLStyle::Params() .color(about_color)); } +//This is bound as a callback in postBuild() +void LLFloaterAbout::setUpdateListener() +{ + typedef std::vector vec; + + //There are four possibilities: + //no downloads directory or version directory in "getOSUserAppDir()/downloads" + // => no update + //version directory exists and .done file is not present + // => download in progress + //version directory exists and .done file exists + // => update ready for install + //version directory, .done file and either .skip or .next file exists + // => update deferred + BOOL downloads = false; + std::string downloadDir = ""; + BOOL done = false; + BOOL next = false; + BOOL skip = false; + + LLSD info(LLFloaterAbout::getInfo()); + std::string version = info["VIEWER_VERSION_STR"].asString(); + std::string appDir = gDirUtilp->getOSUserAppDir(); + + //drop down two directory levels so we aren't searching for markers among the log files and crash dumps + //or among other possible viewer upgrade directories if the resident is running multiple viewer versions + //we should end up with a path like ../downloads/1.2.3.456789 + vec file_vec = gDirUtilp->getFilesInDir(appDir); + + for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) + { + if ( (iter->rfind("downloads") ) ) + { + vec dir_vec = gDirUtilp->getFilesInDir(*iter); + for(vec::const_iterator dir_iter=dir_vec.begin(); dir_iter!=dir_vec.end(); ++dir_iter) + { + if ( (dir_iter->rfind(version))) + { + downloads = true; + downloadDir = *dir_iter; + } + } + } + } + + if ( downloads ) + { + for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter) + { + if ( (iter->rfind(version))) + { + if ( (iter->rfind(".done") ) ) + { + done = true; + } + else if ( (iter->rfind(".next") ) ) + { + next = true; + } + else if ( (iter->rfind(".skip") ) ) + { + skip = true; + } + } + } + } + + if ( ! downloads) + { + LLNotificationsUtil::add("UpdateViewerUpToDate"); + } + else + { + if ( ! done ) + { + LLNotificationsUtil::add("UpdateDownloadInProgress"); + } + else if ( !next and !skip ) + { + LLNotificationsUtil::add("UpdateDownloadComplete"); + } + else //done and there is a next or skip + { + LLNotificationsUtil::add("UpdateDeferred"); + } + } +} + ///---------------------------------------------------------------------------- /// LLFloaterAboutUtil ///---------------------------------------------------------------------------- diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index c4190a4940..2a320c84fb 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4029,10 +4029,9 @@ An update was downloaded. It will be installed during restart. -An error occurred while checking for update. -Please try again later. +An update was downloaded that you previously chose to skip or defer to the next start up. confirm Date: Wed, 2 Nov 2016 18:05:32 +0100 Subject: [PATCH 075/183] SL-323: activate viewer menu and floater checks for updates via VMP --- indra/newview/llfloaterabout.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 1b85f645e8..171858e472 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -90,7 +90,7 @@ public: static LLSD getInfo(); void onClickCopyToClipboard(); void onClickUpdateCheck(); - void setUpdateListener(); + static void setUpdateListener(); private: void setSupportText(const std::string& server_release_notes_url); @@ -138,7 +138,7 @@ BOOL LLFloaterAbout::postBuild() boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this)); getChild("update_btn")->setCommitCallback( - boost::bind(&LLFloaterAbout::setUpdateListener, this)); + boost::bind(&LLFloaterAbout::onClickUpdateCheck, this)); static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor"); @@ -314,6 +314,11 @@ void LLFloaterAbout::onClickCopyToClipboard() support_widget->deselect(); } +void LLFloaterAbout::onClickUpdateCheck() +{ + setUpdateListener(); +} + void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url) { #if LL_WINDOWS @@ -401,17 +406,17 @@ void LLFloaterAbout::setUpdateListener() } } - if ( ! downloads) + if ( !downloads ) { LLNotificationsUtil::add("UpdateViewerUpToDate"); } else { - if ( ! done ) + if ( !done ) { LLNotificationsUtil::add("UpdateDownloadInProgress"); } - else if ( !next and !skip ) + else if ( (!next) && (!skip) ) { LLNotificationsUtil::add("UpdateDownloadComplete"); } @@ -429,6 +434,10 @@ void LLFloaterAboutUtil::registerFloater() { LLFloaterReg::add("sl_about", "floater_about.xml", &LLFloaterReg::build); - +} + +void LLFloaterAboutUtil::checkUpdatesAndNotify() +{ + LLFloaterAbout::setUpdateListener(); } From e6c11693c7142ca11f5ce66185e318dcfe53dc75 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 30 Mar 2017 13:28:53 -0700 Subject: [PATCH 076/183] SL-321: upgrade VMP package 503815 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 84aed54b0e..c01685ef50 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3026,9 +3026,9 @@ archive hash - 62e8464a3d020075266e3f8dbb4e89be + 200cc138491dc913fcbb7b173bab4f58 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3745/9922/viewer_manager-1.0-darwin64-503733.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3826/10314/viewer_manager-1.0-darwin64-503815.tar.bz2 name darwin64 @@ -3050,9 +3050,9 @@ archive hash - 1e5cd892526b78ba174feb65b0653d4b + f516b8cdb5f67f86250a927b8dc6f67d url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3746/9929/viewer_manager-1.0-windows-503733.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3828/10320/viewer_manager-1.0-windows-503815.tar.bz2 name windows From 8adca0e9f920c7232c5f29df43210a09e4d7da97 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 30 Mar 2017 15:31:39 -0700 Subject: [PATCH 077/183] dummy commit to bump build (target for upgrade) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b80277370a..6eddb9aa9e 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,4 @@ To download the current default version, visit [the download page](https://secondlife.com/support/downloads). For even newer versions try [the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers) + From 97c43e6397299620bd3018ae3221ec468cce7962 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 31 Mar 2017 12:38:37 -0700 Subject: [PATCH 078/183] SL-321: sign *before* nsis grabs the EXEs --- indra/newview/viewer_manifest.py | 45 ++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 770567f13d..81711c717e 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -699,6 +699,29 @@ class WindowsManifest(ViewerManifest): "%%ENGAGEREGISTRY%%":engage_registry, "%%DELETE_FILES%%":self.nsi_file_commands(False)}) + # If we're on a build machine, sign the code using our Authenticode certificate. JC + # note that the enclosing setup exe is signed later, after the makensis makes it. + sign_py = os.path.expandvars("${SIGN}") + if not sign_py or sign_py == "${SIGN}": + sign_py = 'C:\\buildscripts\\code-signing\\sign.py' + else: + sign_py = sign_py.replace('\\', '\\\\\\\\') + python = os.path.expandvars("${PYTHON}") + if not python or python == "${PYTHON}": + python = 'python' + if os.path.exists(sign_py): + #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. + print "about to run signing of: ", self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\'))) + print "about to run signing of: ", self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\') + self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\'))) + else: + print "Skipping code signing of vmp executables,", sign_py, "does not exist" + # We use the Unicode version of NSIS, available from # http://www.scratchpaper.com/ # Check two paths, one for Program Files, and one for Program Files (x86). @@ -722,30 +745,12 @@ class WindowsManifest(ViewerManifest): else: print >> sys.stderr, "Maximum nsis attempts exceeded; giving up" raise - # self.remove(self.dst_path_of(tempfile)) - # If we're on a build machine, sign the code using our Authenticode certificate. JC - sign_py = os.path.expandvars("${SIGN}") - if not sign_py or sign_py == "${SIGN}": - sign_py = 'C:\\buildscripts\\code-signing\\sign.py' - else: - sign_py = sign_py.replace('\\', '\\\\\\\\') - python = os.path.expandvars("${PYTHON}") - if not python or python == "${PYTHON}": - python = 'python' + if os.path.exists(sign_py): print "about to run signing of: ", self.dst_path_of(installer_file).replace('\\', '\\\\\\\\') self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of(installer_file).replace('\\', '\\\\\\\\'))) - #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. - print "about to run signing of: ", self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\'))) else: - print "Skipping code signing,", sign_py, "does not exist" + print "Skipping code signing of setup executable,", sign_py, "does not exist" self.created_path(self.dst_path_of(installer_file)) self.package_file = installer_file From d2db8239c21298f55a468100d0b3b06d2623bf67 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 5 Apr 2017 16:50:47 -0700 Subject: [PATCH 079/183] MAINT-6928: update VMP package 503733, add requests package 504010, associated viewer-manifest changes for new files --- autobuild.xml | 54 +++++++++++++++++++++++++++++--- indra/newview/viewer_manifest.py | 26 ++++++++++----- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c01685ef50..0edecf0934 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2797,6 +2797,52 @@ version 8.35.500898 + requests + + copyright + Kenneth Reitz + description + Python HTTP Library + license + Apache + license_file + LICENSE + name + requests + platforms + + darwin64 + + archive + + hash + 14a3c749f78e8489c7291c35fe997f2e + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4022/11166/requests-1.0-darwin64-504010.tar.bz2 + + name + darwin64 + + linux64 + + archive + + hash + 7b7f5985cad7917451f9482d0727b380 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4021/11161/requests-1.0-linux64-504010.tar.bz2 + + name + linux64 + + + source + https://bitbucket.org/lindenlab/p64_python-requests + source_type + hg + version + 1.0 + slvoice copyright @@ -3026,9 +3072,9 @@ archive hash - 200cc138491dc913fcbb7b173bab4f58 + 62e8464a3d020075266e3f8dbb4e89be url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3826/10314/viewer_manager-1.0-darwin64-503815.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3745/9922/viewer_manager-1.0-darwin64-503733.tar.bz2 name darwin64 @@ -3050,9 +3096,9 @@ archive hash - f516b8cdb5f67f86250a927b8dc6f67d + 1e5cd892526b78ba174feb65b0653d4b url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3828/10320/viewer_manager-1.0-windows-503815.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3746/9929/viewer_manager-1.0-windows-503733.tar.bz2 name windows diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 81711c717e..512a1e870d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -436,15 +436,15 @@ class WindowsManifest(ViewerManifest): # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx if self.args['configuration'].lower() == 'debug': - self.path("msvcr120d.dll") - self.path("msvcp120d.dll") - self.path("msvcr100d.dll") - self.path("msvcp100d.dll") + self.path("msvcr120d.dll") + self.path("msvcp120d.dll") + self.path("msvcr100d.dll") + self.path("msvcp100d.dll") else: - self.path("msvcr120.dll") - self.path("msvcp120.dll") - self.path("msvcr100.dll") - self.path("msvcp100.dll") + self.path("msvcr120.dll") + self.path("msvcp120.dll") + self.path("msvcr100.dll") + self.path("msvcp100.dll") # Vivox runtimes self.path("SLVoice.exe") @@ -778,7 +778,9 @@ class DarwinManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") + vmp266dir = os.path.join(vmpdir, "2.6") llbasedir = os.path.join(pkgdir, "llbase") + requestsdir = os.path.join(pkgdir, "requests") if self.prefix(src="", dst="Contents"): # everything goes in Contents self.path("Info.plist", dst="Info.plist") @@ -799,6 +801,14 @@ class DarwinManifest(ViewerManifest): self.path2basename(llbasedir,"*.py") self.path2basename(llbasedir,"_cllsd.so") self.end_prefix() + #requests module needed by llbase/llrest.py + #this is only needed on POSIX, because in Windows we compile it into the EXE + requests_path = os.path.join(self.get_dst_prefix(),'requests') + if not os.path.exists(requests_path): + os.makedirs(requests_path) + if self.prefix(dst="requests"): + self.path2basename(requestsdir,"*") + self.end_prefix() self.end_prefix() # most everything goes in the Resources directory From 9770519a6e7f542cdfb95c996897f274933ad08f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 6 Apr 2017 14:06:49 -0700 Subject: [PATCH 080/183] SL-321: add Requests lib cmake file --- indra/cmake/Requests.cmake | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 indra/cmake/Requests.cmake diff --git a/indra/cmake/Requests.cmake b/indra/cmake/Requests.cmake new file mode 100644 index 0000000000..b8fcaf4764 --- /dev/null +++ b/indra/cmake/Requests.cmake @@ -0,0 +1,2 @@ +include (Prebuilt) +use_prebuilt_binary(requests) From 5ae67d8dcd05f2b9bb82ddc07a26e492946da420 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 7 Apr 2017 11:51:10 -0700 Subject: [PATCH 081/183] MAINT-7282: add requests module and associated build machinery --- autobuild.xml | 10 +++++----- indra/cmake/Requests.cmake | 6 ++++-- indra/newview/CMakeLists.txt | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 5ad0b66336..b6a494f515 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2806,7 +2806,7 @@ license Apache license_file - LICENSE + requests.txt name requests platforms @@ -2816,9 +2816,9 @@ archive hash - 14a3c749f78e8489c7291c35fe997f2e + 20a84252b40223d5c08a6c1575b3333b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4022/11166/requests-1.0-darwin64-504010.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4106/11536/requests-1.0-darwin64-504094.tar.bz2 name darwin64 @@ -2828,9 +2828,9 @@ archive hash - 7b7f5985cad7917451f9482d0727b380 + a92f2235991871c3d601a73cfef9b2af url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4021/11161/requests-1.0-linux64-504010.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4105/11530/requests-1.0-linux64-504094.tar.bz2 name linux64 diff --git a/indra/cmake/Requests.cmake b/indra/cmake/Requests.cmake index b8fcaf4764..84ee070813 100644 --- a/indra/cmake/Requests.cmake +++ b/indra/cmake/Requests.cmake @@ -1,2 +1,4 @@ -include (Prebuilt) -use_prebuilt_binary(requests) +if (DARWIN) + include (Prebuilt) + use_prebuilt_binary(requests) +endif (DARWIN) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7a62d8baec..fa53b5a45d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -43,6 +43,7 @@ include(OPENAL) include(OpenGL) include(OpenSSL) include(PNG) +include(Requests) include(TemplateCheck) include(UI) include(UnixInstall) From 127ffc33df7f810ccfc8f23fdd700407cdd3b158 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 7 Apr 2017 13:48:00 -0700 Subject: [PATCH 082/183] SL-321: upgrade VMP package to 504101 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b6a494f515..3b4a10fc56 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 62e8464a3d020075266e3f8dbb4e89be + a5fdf96ad417880108ec7bbdb20843ec url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3745/9922/viewer_manager-1.0-darwin64-503733.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4113/11555/viewer_manager-1.0-darwin64-504101.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 1e5cd892526b78ba174feb65b0653d4b + 1a98826c4ac200fd1f2ad05f8e98c4cf url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3746/9929/viewer_manager-1.0-windows-503733.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4114/11561/viewer_manager-1.0-windows-504101.tar.bz2 name windows From 6a393ada3e1d2cf0543f80dfd522436554d5bb95 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 10 Apr 2017 13:33:55 -0700 Subject: [PATCH 083/183] MAINT-6928: Add in Python 2.6.6 modules --- indra/CMakeLists.txt | 3 --- indra/newview/viewer_manifest.py | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 84c2a14c6e..39f8697e8c 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -75,9 +75,6 @@ elseif (WINDOWS) endif (EXISTS ${VIEWER_DIR}win_setup) # add_dependencies(viewer windows-setup windows-crash-logger) add_dependencies(viewer windows-crash-logger) -elseif (SOLARIS) - add_subdirectory(solaris_crash_logger) - add_dependencies(viewer solaris-crash-logger) endif (LINUX) add_subdirectory(${VIEWER_PREFIX}newview) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 512a1e870d..7c1db31f04 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -790,7 +790,7 @@ class DarwinManifest(ViewerManifest): self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") if self.prefix(dst="MacOS"): - #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 + #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 and MAINT-6928 self.path2basename(vmpdir,"SL_Launcher") self.path2basename(vmpdir,"*.py") llbase_path = os.path.join(self.get_dst_prefix(),'llbase') @@ -808,6 +808,14 @@ class DarwinManifest(ViewerManifest): os.makedirs(requests_path) if self.prefix(dst="requests"): self.path2basename(requestsdir,"*") + self.end_prefix() + #these supplemental files are in case the user still has 2.6 as their default python + #https://jira.secondlife.com/browse/MAINT-6928 + p266_path = os.path.join(self.get_dst_prefix(),'2.6') + if not os.path.exists(p266_path): + os.makedirs(p266_path) + if self.prefix(dst="2.6"): + self.path2basename(vmp266dir,"*.py") self.end_prefix() self.end_prefix() @@ -903,7 +911,7 @@ class DarwinManifest(ViewerManifest): 'ca-bundle.crt', 'SLVoice', ): - self.path2basename(relpkgdir, libfile) + self.path2basename(relpkgdir, libfile) # dylibs that vary based on configuration if self.args['configuration'].lower() == 'debug': From 5a1135e364142c173a75ed0002ff336a31745019 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 11 Apr 2017 09:08:48 -0700 Subject: [PATCH 084/183] MAINT-6928: upgrade to VMP package 504140, use renamed directory to walk around codesign bug; fix dullahan file copy code --- autobuild.xml | 8 ++++---- indra/newview/viewer_manifest.py | 12 ++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 3b4a10fc56..04d3856103 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - a5fdf96ad417880108ec7bbdb20843ec + e389ce7a6732c9c9e71da4b12d5d6aa3 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4113/11555/viewer_manager-1.0-darwin64-504101.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4151/11742/viewer_manager-1.0-darwin64-504140.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 1a98826c4ac200fd1f2ad05f8e98c4cf + 0c28cb0a9fdeecd138c33166c102c70b url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4114/11561/viewer_manager-1.0-windows-504101.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4153/11755/viewer_manager-1.0-windows-504140.tar.bz2 name windows diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 7c1db31f04..4fb40061c2 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -779,6 +779,8 @@ class DarwinManifest(ViewerManifest): debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") vmp266dir = os.path.join(vmpdir, "2.6") + #apparently the codesign tool has a problem with dir names with dots in them + vmp266nodotdir = os.path.join(vmpdir, "python26") llbasedir = os.path.join(pkgdir, "llbase") requestsdir = os.path.join(pkgdir, "requests") @@ -818,6 +820,12 @@ class DarwinManifest(ViewerManifest): self.path2basename(vmp266dir,"*.py") self.end_prefix() self.end_prefix() + if os.path.exists(vmp266dir): + try: + os.rename(vmp266dir, vmp266nodotdir) + except Exception, e: + print "Failed to rename python 2.6 supplemental directory with error %s" % repr(e) + raise # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): @@ -948,8 +956,8 @@ class DarwinManifest(ViewerManifest): # Dullahan helper apps go inside SLPlugin.app if self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"): - for helperappfile in ('DullahanHelper.app'): - self.path2basename(relpkgdir, helperappfile) + helperappfile = 'DullahanHelper.app' + self.path2basename(relpkgdir, helperappfile) pluginframeworkpath = self.dst_path_of('Chromium Embedded Framework.framework'); # Putting a Frameworks directory under Contents/MacOS From e082edf5961ead47b39a317909a1b362fea8785f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 11 Apr 2017 12:14:21 -0700 Subject: [PATCH 085/183] MAINT-6928: os,rename is retarded, use shutil.move instead --- indra/newview/viewer_manifest.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 4fb40061c2..9a084da1be 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -779,8 +779,6 @@ class DarwinManifest(ViewerManifest): debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") vmp266dir = os.path.join(vmpdir, "2.6") - #apparently the codesign tool has a problem with dir names with dots in them - vmp266nodotdir = os.path.join(vmpdir, "python26") llbasedir = os.path.join(pkgdir, "llbase") requestsdir = os.path.join(pkgdir, "requests") @@ -792,6 +790,8 @@ class DarwinManifest(ViewerManifest): self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") if self.prefix(dst="MacOS"): + #apparently the codesign tool has a problem with dir names with dots in them + vmp266nodotdir = os.path.join(self.get_dst_prefix(), "python26") #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 and MAINT-6928 self.path2basename(vmpdir,"SL_Launcher") self.path2basename(vmpdir,"*.py") @@ -819,10 +819,11 @@ class DarwinManifest(ViewerManifest): if self.prefix(dst="2.6"): self.path2basename(vmp266dir,"*.py") self.end_prefix() - self.end_prefix() - if os.path.exists(vmp266dir): + self.end_prefix() + if os.path.exists(p266_path): try: - os.rename(vmp266dir, vmp266nodotdir) + print "renaming python 2.6 directory %s to %s " % (p266_path, vmp266nodotdir) + shutil.move(p266_path, vmp266nodotdir) except Exception, e: print "Failed to rename python 2.6 supplemental directory with error %s" % repr(e) raise From 7de21de71f16ffe6ae9d7d72133b32041a4dfcac Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 11 Apr 2017 12:57:09 -0700 Subject: [PATCH 086/183] MAINT-6928: guard shutil.move against retry --- indra/newview/viewer_manifest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 9a084da1be..d038392ba0 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -823,7 +823,8 @@ class DarwinManifest(ViewerManifest): if os.path.exists(p266_path): try: print "renaming python 2.6 directory %s to %s " % (p266_path, vmp266nodotdir) - shutil.move(p266_path, vmp266nodotdir) + if not os.path.exists(vmp266nodotdir): + shutil.move(p266_path, vmp266nodotdir) except Exception, e: print "Failed to rename python 2.6 supplemental directory with error %s" % repr(e) raise From e26b66cc6d48b6f98a941090f644807f4f14affb Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 11 Apr 2017 16:18:01 -0700 Subject: [PATCH 087/183] MAINT-6928: revert previous post-move strategy, rename via self.path instead --- indra/newview/viewer_manifest.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index d038392ba0..f6bbe7365a 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -778,7 +778,7 @@ class DarwinManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - vmp266dir = os.path.join(vmpdir, "2.6") + vmp266dir = os.path.join(vmpdir, "python26") llbasedir = os.path.join(pkgdir, "llbase") requestsdir = os.path.join(pkgdir, "requests") @@ -791,7 +791,7 @@ class DarwinManifest(ViewerManifest): if self.prefix(dst="MacOS"): #apparently the codesign tool has a problem with dir names with dots in them - vmp266nodotdir = os.path.join(self.get_dst_prefix(), "python26") + """vmp266nodotdir = os.path.join(self.get_dst_prefix(), "python26")""" #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 and MAINT-6928 self.path2basename(vmpdir,"SL_Launcher") self.path2basename(vmpdir,"*.py") @@ -813,21 +813,13 @@ class DarwinManifest(ViewerManifest): self.end_prefix() #these supplemental files are in case the user still has 2.6 as their default python #https://jira.secondlife.com/browse/MAINT-6928 - p266_path = os.path.join(self.get_dst_prefix(),'2.6') + p266_path = os.path.join(self.get_dst_prefix(),'python26') if not os.path.exists(p266_path): os.makedirs(p266_path) - if self.prefix(dst="2.6"): + if self.prefix("python26"): self.path2basename(vmp266dir,"*.py") self.end_prefix() - self.end_prefix() - if os.path.exists(p266_path): - try: - print "renaming python 2.6 directory %s to %s " % (p266_path, vmp266nodotdir) - if not os.path.exists(vmp266nodotdir): - shutil.move(p266_path, vmp266nodotdir) - except Exception, e: - print "Failed to rename python 2.6 supplemental directory with error %s" % repr(e) - raise + self.end_prefix() # most everything goes in the Resources directory if self.prefix(src="", dst="Resources"): From dafdeb95c247ceab2766a141070ff8758b1e174c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 12 Apr 2017 12:43:02 -0700 Subject: [PATCH 088/183] MAINT-6928: upgrade to VMP package 504232 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 04d3856103..f68f7b77c9 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - e389ce7a6732c9c9e71da4b12d5d6aa3 + bc59c4632795d4c896eed4657883a55b url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4151/11742/viewer_manager-1.0-darwin64-504140.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4243/12165/viewer_manager-1.0-darwin64-504232.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 0c28cb0a9fdeecd138c33166c102c70b + 1e8f5b241bb05bbbdd35ba4453d44c7c url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4153/11755/viewer_manager-1.0-windows-504140.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4244/12171/viewer_manager-1.0-windows-504232.tar.bz2 name windows From eeae193bd16a4f4de375d862580a6594f66f0387 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Sat, 15 Apr 2017 17:12:54 -0700 Subject: [PATCH 089/183] MAINT-6928: upgrade to VMP package 504240 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f68f7b77c9..78a01bf48c 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - bc59c4632795d4c896eed4657883a55b + 3812156950f0f80d178f224d80fcef1c url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4243/12165/viewer_manager-1.0-darwin64-504232.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4251/12224/viewer_manager-1.0-darwin64-504240.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 1e8f5b241bb05bbbdd35ba4453d44c7c + 4a82450f13e4ed4c21d35ef73b836c73 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4244/12171/viewer_manager-1.0-windows-504232.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4252/12230/viewer_manager-1.0-windows-504240.tar.bz2 name windows From 778a35d9bcfc254490dcbc118701b5081b22f848 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 17 Apr 2017 11:42:36 -0700 Subject: [PATCH 090/183] SL-617: upgrade VMP package to 504287 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 78a01bf48c..42c164e361 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 3812156950f0f80d178f224d80fcef1c + 077de083ecc816509d08db03d45de2c5 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4251/12224/viewer_manager-1.0-darwin64-504240.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4298/12539/viewer_manager-1.0-darwin64-504287.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 4a82450f13e4ed4c21d35ef73b836c73 + 7a1d8e797afa953869ccedc3c398c7b8 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4252/12230/viewer_manager-1.0-windows-504240.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4299/12545/viewer_manager-1.0-windows-504287.tar.bz2 name windows From 869771f7c9b6ef30d01120b68b3759aeac74fea5 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 17 Apr 2017 13:09:19 -0700 Subject: [PATCH 091/183] SL-617: alter viewer manifest to write exe name to summary.json, upgrade VMP package to 504292 to read it --- autobuild.xml | 8 ++++---- indra/newview/viewer_manifest.py | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 42c164e361..f7ee8cd6d8 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 077de083ecc816509d08db03d45de2c5 + ba331acee4f295a62b785b1cf80f3584 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4298/12539/viewer_manager-1.0-darwin64-504287.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4303/12557/viewer_manager-1.0-darwin64-504292.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 7a1d8e797afa953869ccedc3c398c7b8 + 4319d4db1e765b2773251f3bdf553034 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4299/12545/viewer_manager-1.0-windows-504287.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4304/12563/viewer_manager-1.0-windows-504292.tar.bz2 name windows diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f6bbe7365a..bac80d8c13 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -206,6 +206,9 @@ class ViewerManifest(LLManifest): summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']), "Channel":self.channel_with_pkg_suffix(), "Platform":summary_json_platform} + #MAINT-7294: Windows exe names depend on channel name, so write that in also + if summary_json_platform.startswith('win'): + summary_dict.update({'Executable':self.channel_with_pkg_suffix().replace(' ', '')+'.exe'}) with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle: json.dump(summary_dict,summary_handle) From 315045dd67547302cab7e96b86910b1c2355c625 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 17 Apr 2017 16:00:50 -0700 Subject: [PATCH 092/183] SL-617: upgrade VMP package to 504305 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f7ee8cd6d8..abb23a3086 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - ba331acee4f295a62b785b1cf80f3584 + dff51c732bfe920d9b64c54e53dfed30 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4303/12557/viewer_manager-1.0-darwin64-504292.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4316/12634/viewer_manager-1.0-darwin64-504305.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 4319d4db1e765b2773251f3bdf553034 + 00f04af17ed799b399b03816d57df05b url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4304/12563/viewer_manager-1.0-windows-504292.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4317/12640/viewer_manager-1.0-windows-504305.tar.bz2 name windows From 91158bf87cc5603a42ada3a29b1e716d08bed4a3 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 17 Apr 2017 17:39:26 -0700 Subject: [PATCH 093/183] MAINT-6928: upgrade VMP package to 504317 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index abb23a3086..688cb9e21a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - dff51c732bfe920d9b64c54e53dfed30 + b89a240a034cd55e72628a00c12148d4 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4316/12634/viewer_manager-1.0-darwin64-504305.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4331/12670/viewer_manager-1.0-darwin64-504317.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 00f04af17ed799b399b03816d57df05b + 501020737bde2fd513dcfed1d9181cd8 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4317/12640/viewer_manager-1.0-windows-504305.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4328/12655/viewer_manager-1.0-windows-504317.tar.bz2 name windows From 305f4d41995a044d109dd9adb2d3c29501eca0f5 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 18 Apr 2017 11:57:30 -0700 Subject: [PATCH 094/183] MAINT-6928: upgrade VMP package to 504332 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 688cb9e21a..5423397302 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - b89a240a034cd55e72628a00c12148d4 + 6787838a6268f3a5f8cd214189e8b29a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4331/12670/viewer_manager-1.0-darwin64-504317.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4343/12783/viewer_manager-1.0-darwin64-504332.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 501020737bde2fd513dcfed1d9181cd8 + 1a72b2adf17ab25510c5f915437bf0a2 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4328/12655/viewer_manager-1.0-windows-504317.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4344/12789/viewer_manager-1.0-windows-504332.tar.bz2 name windows From a3acaaa61b2144af1f76dd8a7bc2b48b9ced00d3 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 24 Apr 2017 16:13:56 -0700 Subject: [PATCH 095/183] MAINT-6928: upgrade VMP package to 504558 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 5423397302..378fdf5619 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 6787838a6268f3a5f8cd214189e8b29a + 7c1aaebbb4e34512a1489b3c67f520f2 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4343/12783/viewer_manager-1.0-darwin64-504332.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4569/13796/viewer_manager-1.0-darwin64-504558.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 1a72b2adf17ab25510c5f915437bf0a2 + 360e630b43446b6a8dc35384aa4dbd5c url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4344/12789/viewer_manager-1.0-windows-504332.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4571/13808/viewer_manager-1.0-windows-504558.tar.bz2 name windows From 24b4d3c13f15917f8c775d5b4211d213af9309c0 Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC" Date: Fri, 28 Apr 2017 01:09:14 +0100 Subject: [PATCH 096/183] SL-671: make icon point to launcher, not viewer --- indra/newview/installers/windows/installer_template.nsi | 4 ++++ indra/newview/viewer_manifest.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index fe1b35767e..4396a576cc 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -337,6 +337,10 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$ # URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks. WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"' +# Only allow Launcher to be the icon +WriteRegStr HKEY_CLASSES_ROOT "Applications" "$INSTEXE" "IsHostApp" +WriteRegStr HKEY_CLASSES_ROOT "Applications" "$VIEWER_EXE" "NoStartPage" + # Write out uninstaller WriteUninstaller "$INSTDIR\uninst.exe" diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bac80d8c13..78dc830c1b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -654,6 +654,7 @@ class WindowsManifest(ViewerManifest): 'version' : '.'.join(self.args['version']), 'version_short' : '.'.join(self.args['version'][:-1]), 'version_dashes' : '-'.join(self.args['version']), + 'viewer_exe' : self.channel_with_pkg_suffix().replace(' ', '')+'.exe', 'final_exe' : self.final_exe(), 'flags':'', 'app_name':self.app_name(), @@ -668,6 +669,7 @@ class WindowsManifest(ViewerManifest): !define VERSION "%(version_short)s" !define VERSION_LONG "%(version)s" !define VERSION_DASHES "%(version_dashes)s" + !define VIEWER_EXE "%(viewer_exe)%s" """ % substitution_strings if self.channel_type() == 'release': From b6e1419007e0bc768302d594649a262952e5fce6 Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC" Date: Fri, 28 Apr 2017 17:05:58 +0100 Subject: [PATCH 097/183] SL-671: fix string substitution --- indra/newview/viewer_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 78dc830c1b..2e3e4d6a07 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -669,7 +669,7 @@ class WindowsManifest(ViewerManifest): !define VERSION "%(version_short)s" !define VERSION_LONG "%(version)s" !define VERSION_DASHES "%(version_dashes)s" - !define VIEWER_EXE "%(viewer_exe)%s" + !define VIEWER_EXE "%(viewer_exe)s%" """ % substitution_strings if self.channel_type() == 'release': From a67d449813a9b6c6198ed15ad15d30535344051e Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC" Date: Fri, 28 Apr 2017 20:04:32 +0100 Subject: [PATCH 098/183] SL-617: pass final_exe from viewer manifest to NSIS as VIEWER_EXE --- indra/newview/installers/windows/installer_template.nsi | 1 + indra/newview/viewer_manifest.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 4396a576cc..682c37971c 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -102,6 +102,7 @@ Page instfiles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Var INSTPROG Var INSTEXE +Var VIEWER_EXE Var INSTSHORTCUT Var COMMANDLINE # Command line passed to this installer, set in .onInit Var SHORTCUT_LANG_PARAM # "--set InstallLanguage de", Passes language to viewer diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2e3e4d6a07..b289db9b8f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -654,7 +654,6 @@ class WindowsManifest(ViewerManifest): 'version' : '.'.join(self.args['version']), 'version_short' : '.'.join(self.args['version'][:-1]), 'version_dashes' : '-'.join(self.args['version']), - 'viewer_exe' : self.channel_with_pkg_suffix().replace(' ', '')+'.exe', 'final_exe' : self.final_exe(), 'flags':'', 'app_name':self.app_name(), @@ -669,7 +668,7 @@ class WindowsManifest(ViewerManifest): !define VERSION "%(version_short)s" !define VERSION_LONG "%(version)s" !define VERSION_DASHES "%(version_dashes)s" - !define VIEWER_EXE "%(viewer_exe)s%" + !define VIEWER_EXE "%(final_exe)s" """ % substitution_strings if self.channel_type() == 'release': From b7b07b04148dfc0ef555a6bf6148d982ea671ecc Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC.hsd1.ca.comcast.net" Date: Mon, 1 May 2017 18:57:06 +0100 Subject: [PATCH 099/183] SL-617: fix registry path --- indra/newview/installers/windows/installer_template.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 682c37971c..c8c2d49ecb 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -339,8 +339,8 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$ WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"' # Only allow Launcher to be the icon -WriteRegStr HKEY_CLASSES_ROOT "Applications" "$INSTEXE" "IsHostApp" -WriteRegStr HKEY_CLASSES_ROOT "Applications" "$VIEWER_EXE" "NoStartPage" +WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" "" +WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage" "" # Write out uninstaller WriteUninstaller "$INSTDIR\uninst.exe" From e1253f1a8c28409834c1ddaf69b24dc02a3551ce Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC.hsd1.ca.comcast.net" Date: Tue, 2 May 2017 21:18:57 +0100 Subject: [PATCH 100/183] SL-617: use the braces, Luke! --- indra/newview/installers/windows/installer_template.nsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index c8c2d49ecb..bb7e15bcf6 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -340,7 +340,7 @@ WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" # Only allow Launcher to be the icon WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" "" -WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage" "" +WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" "" # Write out uninstaller WriteUninstaller "$INSTDIR\uninst.exe" From 81c5f03013ca53402abc1df31cac28d47dc8aa46 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 3 May 2017 11:06:12 -0700 Subject: [PATCH 101/183] MAINT-6928: upgrade VMP package to 504920 and rip out viewer-manifest changes for 2.6 --- autobuild.xml | 8 ++++---- indra/newview/viewer_manifest.py | 17 +++-------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 378fdf5619..b288d11388 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 7c1aaebbb4e34512a1489b3c67f520f2 + de64c8bff972568900e4888cb4e23a26 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4569/13796/viewer_manager-1.0-darwin64-504558.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4931/15927/viewer_manager-1.0-darwin64-504920.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 360e630b43446b6a8dc35384aa4dbd5c + 7c04f899e34f486d98b1e08832c6c940 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4571/13808/viewer_manager-1.0-windows-504558.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4936/15939/viewer_manager-1.0-windows-504920.tar.bz2 name windows diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index b289db9b8f..fced30370c 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -782,7 +782,6 @@ class DarwinManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - vmp266dir = os.path.join(vmpdir, "python26") llbasedir = os.path.join(pkgdir, "llbase") requestsdir = os.path.join(pkgdir, "requests") @@ -793,10 +792,8 @@ class DarwinManifest(ViewerManifest): self.path(os.path.join(relpkgdir, "libndofdev.dylib"), dst="Resources/libndofdev.dylib") self.path(os.path.join(relpkgdir, "libhunspell-1.3.0.dylib"), dst="Resources/libhunspell-1.3.0.dylib") - if self.prefix(dst="MacOS"): - #apparently the codesign tool has a problem with dir names with dots in them - """vmp266nodotdir = os.path.join(self.get_dst_prefix(), "python26")""" - #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 and MAINT-6928 + if self.prefix(dst="MacOS"): + #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 self.path2basename(vmpdir,"SL_Launcher") self.path2basename(vmpdir,"*.py") llbase_path = os.path.join(self.get_dst_prefix(),'llbase') @@ -814,15 +811,7 @@ class DarwinManifest(ViewerManifest): os.makedirs(requests_path) if self.prefix(dst="requests"): self.path2basename(requestsdir,"*") - self.end_prefix() - #these supplemental files are in case the user still has 2.6 as their default python - #https://jira.secondlife.com/browse/MAINT-6928 - p266_path = os.path.join(self.get_dst_prefix(),'python26') - if not os.path.exists(p266_path): - os.makedirs(p266_path) - if self.prefix("python26"): - self.path2basename(vmp266dir,"*.py") - self.end_prefix() + self.end_prefix() self.end_prefix() # most everything goes in the Resources directory From 54d5658186b0ac21488f656a87bd4b374a7b27ed Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 3 May 2017 15:33:29 -0700 Subject: [PATCH 102/183] MAINT-6928: upgrade VMP package to 504954 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b288d11388..46c149dc81 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - de64c8bff972568900e4888cb4e23a26 + 2b798df7ce4a7d06474e30886d4c7c8e url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4931/15927/viewer_manager-1.0-darwin64-504920.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4966/16047/viewer_manager-1.0-darwin64-504954.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 7c04f899e34f486d98b1e08832c6c940 + 340b7f261bf8be7a247d17fbe5add7ec url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4936/15939/viewer_manager-1.0-windows-504920.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4965/16053/viewer_manager-1.0-windows-504954.tar.bz2 name windows From 6d425401c11264e4dd77d0f60d8fd452fbce0020 Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC.hsd1.ca.comcast.net" Date: Thu, 4 May 2017 18:59:01 +0100 Subject: [PATCH 103/183] SL-617: use final_exe to create exe name in summary.json --- indra/newview/viewer_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index fced30370c..06ac62d353 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -208,7 +208,7 @@ class ViewerManifest(LLManifest): "Platform":summary_json_platform} #MAINT-7294: Windows exe names depend on channel name, so write that in also if summary_json_platform.startswith('win'): - summary_dict.update({'Executable':self.channel_with_pkg_suffix().replace(' ', '')+'.exe'}) + summary_dict.update({'Executable':self.final_exe()}) with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle: json.dump(summary_dict,summary_handle) From 50bb2317b2b753542abeb79cdecdbb8d33d34f37 Mon Sep 17 00:00:00 2001 From: "coyot@coyot-sager-PC.hsd1.ca.comcast.net" Date: Thu, 4 May 2017 19:10:36 +0100 Subject: [PATCH 104/183] SL-617: upgrade to VMP package 504984 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 46c149dc81..bf0d5c6037 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 2b798df7ce4a7d06474e30886d4c7c8e + 1f0dd825ec149fe8cdd36baaa8021b6a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4966/16047/viewer_manager-1.0-darwin64-504954.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4995/16233/viewer_manager-1.0-darwin64-504984.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 340b7f261bf8be7a247d17fbe5add7ec + efe3acb53bfe3fa41ee18df4092d7c1a url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4965/16053/viewer_manager-1.0-windows-504954.tar.bz2 + http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4996/16239/viewer_manager-1.0-windows-504984.tar.bz2 name windows From c187f671408b37ef4667b0e05cc107be0b90fa06 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 4 May 2017 16:35:19 -0400 Subject: [PATCH 105/183] add SL-standard format logging --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index bf0d5c6037..19300071b1 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 1f0dd825ec149fe8cdd36baaa8021b6a + c90f3a3946279851172df561bc766cb0 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4995/16233/viewer_manager-1.0-darwin64-504984.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5014/16320/viewer_manager-1.0-darwin64-505002.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - efe3acb53bfe3fa41ee18df4092d7c1a + 834587b81afe3f8541a6ea1ca43bf610 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4996/16239/viewer_manager-1.0-windows-504984.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5013/16328/viewer_manager-1.0-windows-505002.tar.bz2 name windows From ab3742a2a944ee8535e314ebfad52a980e079a70 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 5 May 2017 09:21:48 -0400 Subject: [PATCH 106/183] update to clarified log content messages in the VMP logs --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 19300071b1..e8f418228e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - c90f3a3946279851172df561bc766cb0 + 795f08f3435e9516723fd4efdc3c07de url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5014/16320/viewer_manager-1.0-darwin64-505002.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5041/16562/viewer_manager-1.0-darwin64-505030.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 834587b81afe3f8541a6ea1ca43bf610 + 680c7c455e893345af9138a0f857af22 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5013/16328/viewer_manager-1.0-windows-505002.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5042/16568/viewer_manager-1.0-windows-505030.tar.bz2 name windows From c15ffb40458184002ade41ff652fab3d9ffbb761 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 5 May 2017 09:26:56 -0700 Subject: [PATCH 107/183] upgrade to VMP package 505035, include Oz's logging changes --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index bf0d5c6037..ce556357ce 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 1f0dd825ec149fe8cdd36baaa8021b6a + 279a96cb0a8bd0127cc78a26266d956c url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4995/16233/viewer_manager-1.0-darwin64-504984.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5046/16594/viewer_manager-1.0-darwin64-505035.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - efe3acb53bfe3fa41ee18df4092d7c1a + 528d277b927d7787bdcb3f94e0058ea6 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4996/16239/viewer_manager-1.0-windows-504984.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5047/16600/viewer_manager-1.0-windows-505035.tar.bz2 name windows From 4ca5dec699045ce038713ab64d54af55c9c110e0 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 5 May 2017 16:17:24 -0700 Subject: [PATCH 108/183] upgrade to VMP package 505055 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index a854a45e84..9f6f5d2cef 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 279a96cb0a8bd0127cc78a26266d956c + f388941fcc152d765ab84973c6f5bd73 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5046/16594/viewer_manager-1.0-darwin64-505035.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5066/16659/viewer_manager-1.0-darwin64-505055.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 528d277b927d7787bdcb3f94e0058ea6 + ea41c06527bff041ba272b6424832750 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5047/16600/viewer_manager-1.0-windows-505035.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5067/16665/viewer_manager-1.0-windows-505055.tar.bz2 name windows From b6f0cbdb3911a6120e6bf5b0ba05e6039ca5bcea Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 9 May 2017 16:36:24 -0700 Subject: [PATCH 109/183] upgrade to VMP package 505113 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9f6f5d2cef..73c27dabcf 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - f388941fcc152d765ab84973c6f5bd73 + fbafe3989c5d6e2358f1f0ffd64f5d9e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5066/16659/viewer_manager-1.0-darwin64-505055.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5124/16951/viewer_manager-1.0-darwin64-505113.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - ea41c06527bff041ba272b6424832750 + d30593d32ccfe1017cfe1fd331cb0bf4 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5067/16665/viewer_manager-1.0-windows-505055.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5126/16972/viewer_manager-1.0-windows-505113.tar.bz2 name windows From 6f215d1608f58f241146da6fd060022301dee4e9 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 10 May 2017 07:18:55 -0700 Subject: [PATCH 110/183] dummy commit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b80277370a..16e3932fd9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Second Life Viewer ==================== - + This project manages the source code for the [Second Life](https://www.secondlife.com) Viewer. From 1dcc9e3e1163b93d7654fc776d8e81252f15a6e1 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 10 May 2017 15:35:49 -0700 Subject: [PATCH 111/183] upgrade to VMP package 505153 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 73c27dabcf..fa8262977f 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - fbafe3989c5d6e2358f1f0ffd64f5d9e + 277d83d9f82acc6493da897bb60af856 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5124/16951/viewer_manager-1.0-darwin64-505113.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5164/17167/viewer_manager-1.0-darwin64-505153.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - d30593d32ccfe1017cfe1fd331cb0bf4 + 533ecf8fe06da82770fdd63ccc6ffc2d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5126/16972/viewer_manager-1.0-windows-505113.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5165/17173/viewer_manager-1.0-windows-505153.tar.bz2 name windows From dca547858d69bd2311c1c28f01992d0ba638ad01 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 08:45:10 -0700 Subject: [PATCH 112/183] update vmp package to 505307 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index fa8262977f..70ccc0cf7a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 277d83d9f82acc6493da897bb60af856 + fb93ad2d5f65b3b71d544915fc31d274 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5164/17167/viewer_manager-1.0-darwin64-505153.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5318/17851/viewer_manager-1.0-darwin64-505307.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 533ecf8fe06da82770fdd63ccc6ffc2d + 668662ec5a618b4d38c17f9907e5997c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5165/17173/viewer_manager-1.0-windows-505153.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5319/17857/viewer_manager-1.0-windows-505307.tar.bz2 name windows From 7bc1b9d70eafc8b5198fe0eb8e0cffb788ddfa71 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 11:30:53 -0700 Subject: [PATCH 113/183] update vmp package to 505320 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 70ccc0cf7a..d17ea7908b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - fb93ad2d5f65b3b71d544915fc31d274 + 381b00f74a22001ba76a922f74c379fe url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5318/17851/viewer_manager-1.0-darwin64-505307.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5331/17940/viewer_manager-1.0-darwin64-505320.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 668662ec5a618b4d38c17f9907e5997c + 93a92797bc8a0d46a25010d1dc72dfe0 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5319/17857/viewer_manager-1.0-windows-505307.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5332/17946/viewer_manager-1.0-windows-505320.tar.bz2 name windows From 2150e038e8a2444bb108f9f48a95b3aef8c93bfa Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 14:01:53 -0700 Subject: [PATCH 114/183] update vmp package to 505332 --- autobuild.xml | 8 ++++---- indra/cmake/ViewerManager.cmake | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index d17ea7908b..4b063a0732 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 381b00f74a22001ba76a922f74c379fe + c02caa4eeb280e813dc4efacbbd4c3a8 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5331/17940/viewer_manager-1.0-darwin64-505320.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5343/18006/viewer_manager-1.0-darwin64-505332.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 93a92797bc8a0d46a25010d1dc72dfe0 + 127697b31f26f49ea2bfd631317b3284 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5332/17946/viewer_manager-1.0-windows-505320.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5344/18012/viewer_manager-1.0-windows-505332.tar.bz2 name windows diff --git a/indra/cmake/ViewerManager.cmake b/indra/cmake/ViewerManager.cmake index 793ed78b6c..7150ffc4d1 100644 --- a/indra/cmake/ViewerManager.cmake +++ b/indra/cmake/ViewerManager.cmake @@ -1,2 +1,3 @@ include (Prebuilt) -use_prebuilt_binary(viewer-manager) \ No newline at end of file +use_prebuilt_binary(viewer-manager) + From a31aecc730733b3f20eac4a6ae18b27e6676afe0 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 16:12:18 -0700 Subject: [PATCH 115/183] nerf launch from NSIS --- .../installers/windows/installer_template.nsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 1377cd7f21..0481c029ac 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -727,15 +727,15 @@ FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; After install completes, launch app ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function .onInstSuccess -Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch. - Push $R0 # Option value, unused - StrCmp $SKIP_AUTORUN "true" +2; +# Function .onInstSuccess +# Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch. +# Push $R0 # Option value, unused# +# StrCmp $SKIP_AUTORUN "true" +2; # Assumes SetOutPath $INSTDIR - Exec '"$WINDIR\explorer.exe" "$INSTDIR\autorun.bat"' - Pop $R0 - -FunctionEnd +# Exec '"$WINDIR\explorer.exe" "$INSTDIR\autorun.bat"' +# Pop $R0 +# +# FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Recommend Upgrading to Service Pack 1 for Windows 7, if not present From 52687641b235e83bf4a74aac3a799db166caa502 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 16:18:58 -0700 Subject: [PATCH 116/183] update vmp package to 505345 --- autobuild.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4b063a0732..ac72e53ab4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - c02caa4eeb280e813dc4efacbbd4c3a8 + 3d2fd950728cc0ff0e5e5b42eca43a1e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5343/18006/viewer_manager-1.0-darwin64-505332.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5356/18078/viewer_manager-1.0-darwin64-505345.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 127697b31f26f49ea2bfd631317b3284 + fc4433c744fd870af8bdbbc784d42aa9 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5344/18012/viewer_manager-1.0-windows-505332.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5357/18084/viewer_manager-1.0-windows-505345.tar.bz2 name windows From 4bf1f1d618d61f0cc2ec0dd22cea7d1c5b909b8f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 17 May 2017 18:10:43 -0700 Subject: [PATCH 117/183] dummy checkin to build an upgrade target --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16e3932fd9..781501178a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Second Life Viewer ==================== - + This project manages the source code for the [Second Life](https://www.secondlife.com) Viewer. From d0549dea002d348472714f11e42bc7a73955c90f Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 19 May 2017 09:54:59 -0400 Subject: [PATCH 118/183] upgrade to viewer-manager that supports setting update server via SL_UPDATE_SERVICE --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ac72e53ab4..1448e5b6f6 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 3d2fd950728cc0ff0e5e5b42eca43a1e + 0850b8395cc3bf83d15a766120d97229 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5356/18078/viewer_manager-1.0-darwin64-505345.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5386/18225/viewer_manager-1.0.505374-darwin64-505374.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - fc4433c744fd870af8bdbbc784d42aa9 + 89873bae7a90c84a3383ce8ec1d444a5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5357/18084/viewer_manager-1.0-windows-505345.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5385/18219/viewer_manager-1.0.505374-windows-505374.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0 + 1.0.505374 vlc-bin From 79c6b5f53ed9962b82f03e4729bbf063b167f999 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 23 May 2017 13:27:24 -0400 Subject: [PATCH 119/183] update viewer-manager to solve service url problem --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1448e5b6f6..b24e26e943 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 0850b8395cc3bf83d15a766120d97229 + 0d00f5e1bc993eefb61ef18c0142b178 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5386/18225/viewer_manager-1.0.505374-darwin64-505374.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5470/18542/viewer_manager-1.0.505459-darwin64-505459.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 89873bae7a90c84a3383ce8ec1d444a5 + cd6e91143eff8f24029d79aa08fd8395 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5385/18219/viewer_manager-1.0.505374-windows-505374.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5471/18548/viewer_manager-1.0.505459-windows-505459.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505374 + 1.0.505459 vlc-bin From c36df7c76d759d0e87180492679f5a418e7c6409 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 23 May 2017 13:34:54 -0700 Subject: [PATCH 120/183] upgrade to VMP package 505471 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1448e5b6f6..65c66bbf3f 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 0850b8395cc3bf83d15a766120d97229 + 4db1f59053202942ef3c6484d4bebf42 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5386/18225/viewer_manager-1.0.505374-darwin64-505374.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5482/18635/viewer_manager-1.0.505471-darwin64-505471.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 89873bae7a90c84a3383ce8ec1d444a5 + 496467d2751471bf74c727952d7ffb8e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5385/18219/viewer_manager-1.0.505374-windows-505374.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5483/18641/viewer_manager-1.0.505471-windows-505471.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505374 + 1.0.505471 vlc-bin From e044902aaf1aa963d41a30a249b564e1b8910de7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 24 May 2017 09:41:44 -0400 Subject: [PATCH 121/183] SL-702: refactor to make the viewer-manager easier for TPVs to integrate --- autobuild.xml | 10 +++---- indra/lib/python/indra/util/llmanifest.py | 3 ++ indra/newview/CMakeLists.txt | 3 +- indra/newview/viewer_manifest.py | 35 +++++++++++++---------- indra/viewer_components/Resources/README | 2 +- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index b24e26e943..b839bfa67a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 0d00f5e1bc993eefb61ef18c0142b178 + 57668d6519adf7a7bbdbed98240e7470 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5470/18542/viewer_manager-1.0.505459-darwin64-505459.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5525/18802/viewer_manager-1.0.505514-darwin64-505514.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - cd6e91143eff8f24029d79aa08fd8395 + 818860f12da07d1451ef4870f2143e9b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5471/18548/viewer_manager-1.0.505459-windows-505459.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5526/18808/viewer_manager-1.0.505514-windows-505514.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505459 + 1.0.505514 vlc-bin diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 62bd09471a..0a39db2b21 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -143,6 +143,9 @@ ARGUMENTS=[ default=None), dict(name='versionfile', description="""The name of a file containing the full version number."""), + dict(name='bundleid', + description="""The Mac OS X Bundle identifier.""", + default="com.secondlife.indra.viewer"), dict(name='signature', description="""This specifies an identity to sign the viewer with, if any. If no value is supplied, the default signature will be used, if any. Currently diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 8d36214506..266de7277d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1331,7 +1331,7 @@ set(viewer_HEADER_FILES source_group("CMake Rules" FILES ViewerInstall.cmake) -#summary.json creation moved to viewer_manifest.py MAINT-6413 +#build_data.json creation moved to viewer_manifest.py MAINT-6413 # the viewer_version.txt file created here is for passing to viewer_manifest and autobuild file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}\n") @@ -2073,6 +2073,7 @@ if (DARWIN) --grid=${GRID} "--channel=${VIEWER_CHANNEL}" --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt + --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} --source=${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${VIEWER_BINARY_NAME} diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index e806a4fdad..d9fef022e5 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -123,20 +123,20 @@ class ViewerManifest(LLManifest): #do not need to test for existence. If no platform is passed, llmanifest computes a default in get_default_platform #the choice of value names (lnx, mac, win32, win) is dictated by the VMM API - summary_json_platform = "" + build_data_json_platform = "" if 'linux' in self.args['platform']: - summary_json_platform = 'lnx' + build_data_json_platform = 'lnx' elif 'darwin' in self.args['platform']: - summary_json_platform = 'mac' + build_data_json_platform = 'mac' elif 'windows' in self.args['platform']: #default case - summary_json_platform = 'win' + build_data_json_platform = 'win' if 'arch' in self.args and self.args['arch']: if 'i686' in self.args['arch']: - summary_json_platform = 'win32' + build_data_json_platform = 'win32' #we really shouldn't be here, something is very wrong at this point else: - summary_json_platform = 'None' + build_data_json_platform = 'None' # put_in_file(src=) need not be an actual pathname; it @@ -201,21 +201,26 @@ class ViewerManifest(LLManifest): # File in the newview/ directory self.path("gpu_table.txt") - #summary.json. Standard with exception handling is fine. If we can't open a new file for writing, we have worse problems + #build_data.json. Standard with exception handling is fine. If we can't open a new file for writing, we have worse problems #platform is computed above with other arg parsing - summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']), + build_data_dict = {"Type":"viewer","Version":'.'.join(self.args['version']), + "Channel Base": CHANNEL_VENDOR_BASE, "Channel":self.channel_with_pkg_suffix(), - "Platform":summary_json_platform} + "Platform":build_data_json_platform, + "Update Service":"https://update.secondlife.com/update/", + } #MAINT-7294: Windows exe names depend on channel name, so write that in also - if summary_json_platform.startswith('win'): - summary_dict.update({'Executable':self.final_exe()}) - with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle: - json.dump(summary_dict,summary_handle) + if build_data_json_platform.startswith('win'): + build_data_dict.update({'Executable':self.final_exe()}) + if build_data_json_platform.startswith('mac'): + build_data_dict.update({'Bundle Id':self.args['bundleid']}) + with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle: + json.dump(build_data_dict,build_data_handle) #we likely no longer need the test, since we will throw an exception above, but belt and suspenders and we get the #return code for free. - if not self.path2basename(os.pardir, "summary.json"): - print "No summary.json file" + if not self.path2basename(os.pardir, "build_data.json"): + print "No build_data.json file" def grid(self): return self.args['grid'] diff --git a/indra/viewer_components/Resources/README b/indra/viewer_components/Resources/README index e1b35730d4..b0863a7f25 100644 --- a/indra/viewer_components/Resources/README +++ b/indra/viewer_components/Resources/README @@ -1,4 +1,4 @@ -This directory only exists as a place for the summary.json file to exist when the unit tests are run on a Mac, where the file goes to a sibling directory of the scripts dir. In Linux and Windows, the JSON file goes into the same directory as the script. +This directory only exists as a place for the build_data.json file to exist when the unit tests are run on a Mac, where the file goes to a sibling directory of the scripts dir. In Linux and Windows, the JSON file goes into the same directory as the script. See: From 9f7905c850979c4c8f56f053a77339c445d6be94 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 30 May 2017 10:53:07 -0400 Subject: [PATCH 122/183] update SL-702 changes based on code review --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 65c66bbf3f..f066061c97 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 4db1f59053202942ef3c6484d4bebf42 + 6ea766dde7bd2527b3fc719d00f478b0 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5482/18635/viewer_manager-1.0.505471-darwin64-505471.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5674/19403/viewer_manager-1.0.505663-darwin64-505663.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 496467d2751471bf74c727952d7ffb8e + 34aa8d53297cb0f9e4925417e4b7585e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5483/18641/viewer_manager-1.0.505471-windows-505471.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5675/19409/viewer_manager-1.0.505663-windows-505663.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505471 + 1.0.505663 vlc-bin From 2307a7d09bd77e758cbdf34c64e76f119d60e2f9 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Thu, 1 Jun 2017 16:55:59 -0400 Subject: [PATCH 123/183] update viewer-manager --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f066061c97..b345d77c71 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 6ea766dde7bd2527b3fc719d00f478b0 + b4ea4a814487e321342976f526b013d8 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5674/19403/viewer_manager-1.0.505663-darwin64-505663.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5849/20379/viewer_manager-1.0.505838-darwin64-505838.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 34aa8d53297cb0f9e4925417e4b7585e + 48157bdfdf4813464497c66cbd1ce3da url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5675/19409/viewer_manager-1.0.505663-windows-505663.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5850/20385/viewer_manager-1.0.505838-windows-505838.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505663 + 1.0.505838 vlc-bin From abb6d87fbf14d4107219ce724bff356e1e1a722c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 1 Jun 2017 15:23:23 -0700 Subject: [PATCH 124/183] upgrade to vmp package 505843, oz tpv fixes --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 65c66bbf3f..cb16375b18 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 4db1f59053202942ef3c6484d4bebf42 + 8ee1f75b6d0bc49bdeaab87df26d7dbe url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5482/18635/viewer_manager-1.0.505471-darwin64-505471.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5854/20391/viewer_manager-1.0.505843-darwin64-505843.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - 496467d2751471bf74c727952d7ffb8e + a7aad3e742e52631ba496dbcad904199 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5483/18641/viewer_manager-1.0.505471-windows-505471.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5855/20397/viewer_manager-1.0.505843-windows-505843.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505471 + 1.0.505843 vlc-bin From 96dc7387e4405676c83aededd9917da93124990a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 5 Jun 2017 15:22:21 -0700 Subject: [PATCH 125/183] MAINT-7192: upgrade to VMP package 505928 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index cb16375b18..34f1ed435a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 8ee1f75b6d0bc49bdeaab87df26d7dbe + 1267a1cd4c7a1a25631c7cf58113ca8e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5854/20391/viewer_manager-1.0.505843-darwin64-505843.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5939/20683/viewer_manager-1.0.505928-darwin64-505928.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - a7aad3e742e52631ba496dbcad904199 + f9e454883e94e31e2d52809ea672c90b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5855/20397/viewer_manager-1.0.505843-windows-505843.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5940/20694/viewer_manager-1.0.505928-windows-505928.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505843 + 1.0.505928 vlc-bin From 16666433a95d240f65d5f29188b75a7dfcb2ec89 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 6 Jun 2017 10:33:01 -0700 Subject: [PATCH 126/183] add unit test case, upgrade to VMP package 506059 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 34f1ed435a..4db3018c39 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 1267a1cd4c7a1a25631c7cf58113ca8e + 3e48bc03e0addce3b89a5b3dfcd2a720 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5939/20683/viewer_manager-1.0.505928-darwin64-505928.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6070/21122/viewer_manager-1.0.506059-darwin64-506059.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - f9e454883e94e31e2d52809ea672c90b + d17d5da63ae2e83bf2f9908591435e2b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/5940/20694/viewer_manager-1.0.505928-windows-505928.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6071/21128/viewer_manager-1.0.506059-windows-506059.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.505928 + 1.0.506059 vlc-bin From 8d36da00c885f31739ce6bf6dbc162a6ef3a15a1 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 7 Jun 2017 15:54:29 -0700 Subject: [PATCH 127/183] Pull in new version of 3p-Dullahan that was build against CEF 3.021 (Chrome 59) for Windows 32/64 and macOS 64 --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7f81064379..ebf24a051c 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -526,9 +526,9 @@ archive hash - da5c705fa4fae169cba26fba92dba1ef + 95a6d7d1ff2ffc8679601d9408533663 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4835/15404/dullahan-1.1.800_3.3029.1611.g44e39a8-darwin64-504824.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6185/21567/dullahan-1.1.800_3.3071.1637.gcb6cf75-darwin64-506174.tar.bz2 name darwin64 @@ -538,9 +538,9 @@ archive hash - 17cd8f6e8f95df877d0c9c234f860324 + c14caa52a6ab343c35e6e76af840257f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4836/15410/dullahan-1.1.800_3.3029.1611.g44e39a8-windows-504824.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6187/21579/dullahan-1.1.800_3.3071.1634.g9cc59c8-windows-506174.tar.bz2 name windows @@ -550,16 +550,16 @@ archive hash - 7a478f8f0e13f5f81cab657a8c351186 + ff4d59eb23011198ccd0aa4f5875bbd1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4837/15415/dullahan-1.1.800_3.3029.1611.g44e39a8-windows64-504824.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6186/21573/dullahan-1.1.800_3.3071.1634.g9cc59c8-windows64-506174.tar.bz2 name windows64 version - 1.1.800_3.3029.1611.g44e39a8 + 1.1.800_3.3071.1634.g9cc59c8 elfio From 5134805c66fcb0fe944691db168c75af106db14c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 12 Jun 2017 13:26:19 -0700 Subject: [PATCH 128/183] MAINT-7192: upgrade to VMP package 506412 --- autobuild.xml | 10 +++++----- build.sh | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4db3018c39..c9e9075bbc 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3072,9 +3072,9 @@ archive hash - 3e48bc03e0addce3b89a5b3dfcd2a720 + 26c1baecb8192fd627748e77550eea53 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6070/21122/viewer_manager-1.0.506059-darwin64-506059.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6423/22456/viewer_manager-1.0.506412-darwin64-506412.tar.bz2 name darwin64 @@ -3096,9 +3096,9 @@ archive hash - d17d5da63ae2e83bf2f9908591435e2b + c18521823d02e376bd9380fc50945abb url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6071/21128/viewer_manager-1.0.506059-windows-506059.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6424/22462/viewer_manager-1.0.506412-windows-506412.tar.bz2 name windows @@ -3109,7 +3109,7 @@ source_type hg version - 1.0.506059 + 1.0.506412 vlc-bin diff --git a/build.sh b/build.sh index 1d39ccf664..bb8d66599b 100755 --- a/build.sh +++ b/build.sh @@ -209,6 +209,7 @@ fi # load autobuild provided shell functions and variables "$autobuild" --quiet source_environment > "$build_log_dir/source_environment" +PYTHONPATH="$BUILDSCRIPTS_SHARED/packages/lib/python:$PYTHONPATH" begin_section "dump source environment commands" cat "$build_log_dir/source_environment" end_section "dump source environment commands" From 215a034d6cdd11b54aed27bca0027f1b124f6bbd Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 12 Jun 2017 14:07:30 -0700 Subject: [PATCH 129/183] MAINT-7192: upgrade to viewer to llbase 506286 --- autobuild.xml | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c9e9075bbc..20ebfd3557 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2137,33 +2137,69 @@ name darwin + darwin64 + + archive + + hash + e18eeb0691af053b83bd46b76c6ee86a + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2 + + name + darwin64 + linux archive hash - 80ef3f9f6bde28787b02837ace2ad84c + b77e44582267b499c63234e8b1012b9c url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Linux/installer/llbase-0.8.6.318106-linux-318106.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6298/21977/llbase-0.9.3.506286-linux-506286.tar.bz2 name linux + linux64 + + archive + + hash + 84f5808ed9772da32c3866cee84e8ceb + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6297/21970/llbase-0.9.3.506286-linux64-506286.tar.bz2 + + name + linux64 + windows archive hash - 57837daafa60f98a4d9fa4dfe53d995e + e6865670f9bca1c82fb8b91db3ea515c url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/CYGWIN/installer/llbase-0.8.6.0-windows-318106.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2 name windows + windows64 + + archive + + hash + 15be196632bf4b96955106c9a2dfd7a2 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6300/21988/llbase-0.9.3.506286-windows64-506286.tar.bz2 + + name + windows64 + version - 0.8.6.318106 + 0.9.3.506286 llphysicsextensions_source From 65dd2988dc3bf2a393463c1c2e49291432709c72 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 12 Jun 2017 16:12:37 -0700 Subject: [PATCH 130/183] MAINT-7192: upgrade to viewer to vmp package 506422 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 20ebfd3557..e57e4c7c6e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3108,9 +3108,9 @@ archive hash - 26c1baecb8192fd627748e77550eea53 + 8e6babaf2b47e09c253a6f913979df2c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6423/22456/viewer_manager-1.0.506412-darwin64-506412.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6433/22481/viewer_manager-1.0.506422-darwin64-506422.tar.bz2 name darwin64 @@ -3132,9 +3132,9 @@ archive hash - c18521823d02e376bd9380fc50945abb + 8db8e9f6e1a562da0d78eb1e4036d79d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6424/22462/viewer_manager-1.0.506412-windows-506412.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6434/22487/viewer_manager-1.0.506422-windows-506422.tar.bz2 name windows @@ -3145,7 +3145,7 @@ source_type hg version - 1.0.506412 + 1.0.506422 vlc-bin From d372cdf068cbc2b794d9fc3f2cbe29515504a24f Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 12 Jun 2017 20:40:55 -0700 Subject: [PATCH 131/183] MAINT-7192: upgrade to W64 viewer to llbase 506431 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index e57e4c7c6e..83d71d3c0a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3108,9 +3108,9 @@ archive hash - 8e6babaf2b47e09c253a6f913979df2c + 649e328b371b18700cae028affea6455 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6433/22481/viewer_manager-1.0.506422-darwin64-506422.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6442/22536/viewer_manager-1.0.506431-darwin64-506431.tar.bz2 name darwin64 @@ -3132,9 +3132,9 @@ archive hash - 8db8e9f6e1a562da0d78eb1e4036d79d + d7368d0b260dc967b0c3e31d73f7836f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6434/22487/viewer_manager-1.0.506422-windows-506422.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6443/22542/viewer_manager-1.0.506431-windows-506431.tar.bz2 name windows @@ -3145,7 +3145,7 @@ source_type hg version - 1.0.506422 + 1.0.506431 vlc-bin From ac78ad7ff3270f638dfd355a6987c0bc8472a83e Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 13 Jun 2017 08:15:07 -0700 Subject: [PATCH 132/183] SL-700: synchronize viewer and vmp llbase platforms --- autobuild.xml | 58 +++++---------------------------------------------- 1 file changed, 5 insertions(+), 53 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 83d71d3c0a..58bb9357bc 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2125,18 +2125,6 @@ llbase platforms - darwin - - archive - - hash - 13998879705aa1af36c6ea8f480901e3 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llbase/rev/318106/arch/Darwin/installer/llbase-0.8.6.318106-darwin-318106.tar.bz2 - - name - darwin - darwin64 archive @@ -2149,30 +2137,6 @@ name darwin64 - linux - - archive - - hash - b77e44582267b499c63234e8b1012b9c - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6298/21977/llbase-0.9.3.506286-linux-506286.tar.bz2 - - name - linux - - linux64 - - archive - - hash - 84f5808ed9772da32c3866cee84e8ceb - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6297/21970/llbase-0.9.3.506286-linux64-506286.tar.bz2 - - name - linux64 - windows archive @@ -2185,18 +2149,6 @@ name windows - windows64 - - archive - - hash - 15be196632bf4b96955106c9a2dfd7a2 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6300/21988/llbase-0.9.3.506286-windows64-506286.tar.bz2 - - name - windows64 - version 0.9.3.506286 @@ -3108,9 +3060,9 @@ archive hash - 649e328b371b18700cae028affea6455 + b5089aa1ee07546d6cc554ec7874ca5f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6442/22536/viewer_manager-1.0.506431-darwin64-506431.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6458/22603/viewer_manager-1.0.506447-darwin64-506447.tar.bz2 name darwin64 @@ -3132,9 +3084,9 @@ archive hash - d7368d0b260dc967b0c3e31d73f7836f + e3da9c355450b4a7c09b0bdc00bda5cd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6443/22542/viewer_manager-1.0.506431-windows-506431.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6459/22609/viewer_manager-1.0.506447-windows-506447.tar.bz2 name windows @@ -3145,7 +3097,7 @@ source_type hg version - 1.0.506431 + 1.0.506447 vlc-bin From 1c19d8d270f6c468b799498d071c6d19cffc13f2 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 13 Jun 2017 10:58:37 -0700 Subject: [PATCH 133/183] upgrade to vmp package 506452 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 58bb9357bc..ac182698f3 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - b5089aa1ee07546d6cc554ec7874ca5f + 3bcec41da369fc277508c315d306dc49 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6458/22603/viewer_manager-1.0.506447-darwin64-506447.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6463/22663/viewer_manager-1.0.506452-darwin64-506452.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - e3da9c355450b4a7c09b0bdc00bda5cd + b7bbf27d06ffec27771c78932beee808 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6459/22609/viewer_manager-1.0.506447-windows-506447.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6465/22676/viewer_manager-1.0.506452-windows-506452.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506447 + 1.0.506452 vlc-bin From bcf7195bce14efb8e36da0f6e4cfb1491e78c331 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 13 Jun 2017 11:54:09 -0700 Subject: [PATCH 134/183] upgrade to vmp package 506464 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ac182698f3..5b4c309f73 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - 3bcec41da369fc277508c315d306dc49 + 4616e442d86957b41fb019e34a1a45e9 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6463/22663/viewer_manager-1.0.506452-darwin64-506452.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6475/22696/viewer_manager-1.0.506464-darwin64-506464.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - b7bbf27d06ffec27771c78932beee808 + 1af5466244470bfd1f0226538d72aa81 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6465/22676/viewer_manager-1.0.506452-windows-506452.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6476/22702/viewer_manager-1.0.506464-windows-506464.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506452 + 1.0.506464 vlc-bin From c538ff12c5a75ba9aa51648e97fd629a9a2829e9 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 14 Jun 2017 14:16:23 -0700 Subject: [PATCH 135/183] SL-700: temporarily use local version of ca-bundle.crt instead of from voice, misc cleanup --- autobuild.xml | 10 +- indra/cmake/Copy3rdPartyLibs.cmake | 2 - indra/newview/ca-bundle.crt | 3899 ++++++++++++++++++++++++++++ indra/newview/licenses-solaris.txt | 685 ----- indra/newview/viewer_manifest.py | 4 +- 5 files changed, 3907 insertions(+), 693 deletions(-) create mode 100644 indra/newview/ca-bundle.crt delete mode 100644 indra/newview/licenses-solaris.txt diff --git a/autobuild.xml b/autobuild.xml index 5b4c309f73..363735f664 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - 4616e442d86957b41fb019e34a1a45e9 + 651a9a4cfa60ac75be17958ced9873dd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6475/22696/viewer_manager-1.0.506464-darwin64-506464.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6512/22903/viewer_manager-1.0.506501-darwin64-506501.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - 1af5466244470bfd1f0226538d72aa81 + 90c5c2556d1636bd56c232c7ba10361c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6476/22702/viewer_manager-1.0.506464-windows-506464.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6516/22916/viewer_manager-1.0.506501-windows-506501.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506464 + 1.0.506501 vlc-bin diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 43188673eb..5ccbe7d1d8 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -20,7 +20,6 @@ if(WINDOWS) set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(vivox_files SLVoice.exe - ca-bundle.crt libsndfile-1.dll vivoxsdk.dll ortp.dll @@ -151,7 +150,6 @@ elseif(DARWIN) set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(vivox_files SLVoice - ca-bundle.crt libsndfile.dylib libvivoxoal.dylib libortp.dylib diff --git a/indra/newview/ca-bundle.crt b/indra/newview/ca-bundle.crt new file mode 100644 index 0000000000..e1c052d6a8 --- /dev/null +++ b/indra/newview/ca-bundle.crt @@ -0,0 +1,3899 @@ +## +## /Users/jenkins/slave-jenkins-platform/workspace/sdk-4.6.17-osx/build/release/bin/ca-bundle.crt -- Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Sat Dec 29 20:03:40 2012 +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## + +# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.87 $ $Date: 2012/12/29 16:32:45 $ + +GTE CyberTrust Global Root +========================== +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg +Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG +A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz +MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL +Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 +IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u +sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql +HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID +AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW +M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF +NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +Thawte Server CA +================ +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE +AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j +b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV +BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u +c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG +A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 +ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl +/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 +1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J +GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ +GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +Thawte Premium Server CA +======================== +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE +AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl +ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT +AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 +aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ +cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 +aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh +Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ +qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm +SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf +8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t +UCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +Equifax Secure CA +================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR +fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW +8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE +CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS +spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 +zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB +BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 +70+sB3c4 +-----END CERTIFICATE----- + +Digital Signature Trust Co. Global CA 1 +======================================= +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE +ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy +MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs +IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE +NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i +o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo +BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw +IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY +MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM +BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq +kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 +RbyhkwS7hp86W0N6w4pl +-----END CERTIFICATE----- + +Digital Signature Trust Co. Global CA 3 +======================================= +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE +ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy +MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs +IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD +VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS +xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo +BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw +IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY +MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM +BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi +up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 +mPnHfxsb1gYgAlihw6ID +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA +TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah +WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf +Tqj/ZA1k +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd +k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq +WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB +MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM +XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC +lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h +cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp +Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h +cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp +Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx +nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC +wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA +ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK +1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk +LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO +FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 +lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB +MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT +1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD +Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 +-----END CERTIFICATE----- + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +ValiCert Class 1 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy +MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi +GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm +DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG +lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX +icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP +Orf1LXLI +-----END CERTIFICATE----- + +ValiCert Class 2 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC +CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf +ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ +SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV +UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 +W9ViH0Pd +-----END CERTIFICATE----- + +RSA Root Certificate 1 +====================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td +3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H +BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs +3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF +V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r +on+jjBXu +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E +bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ +rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+ +Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB +FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N +y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h +a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc +D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y +azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug +b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y +aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6 +tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7 +C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS +0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs +Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0 +JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf +0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx +JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j +GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Verisign Class 4 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS +tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM +8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW +Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX +Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt +mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd +RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG +UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +Entrust.net Secure Server CA +============================ +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV +BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg +cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl +ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG +A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi +eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p +dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ +aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 +gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw +ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw +CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l +dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw +NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow +HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA +BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN +Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 +n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC +AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER +gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B +AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo +oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS +o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z +2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX +OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +Equifax Secure Global eBusiness CA +================================== +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp +bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx +HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds +b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV +PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN +qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn +hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs +MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN +I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY +NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 1 +============================= +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB +LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE +ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz +IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ +1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a +IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk +MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW +Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF +AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 +lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ +KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 2 +============================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE +ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y +MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT +DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn +2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 +BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx +JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e +uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 +jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia +78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm +V+GRMOrN +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +RSA Security 2048 v3 +==================== +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK +ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy +MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb +BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 +Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb +WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH +KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP ++Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E +FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY +v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj +0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj +VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 +nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA +pKnXwiJPZ9d37CAFYd4= +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +UTN-USER First-Network Applications +=================================== +-----BEGIN CERTIFICATE----- +MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp +BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5 +WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T +YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB +cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug +mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj +DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu +Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi +P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE +j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w +HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j +cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G +CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y +IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK +RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp +xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq +DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE +-----END CERTIFICATE----- + +America Online Root Certification Authority 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG +v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z +DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh +sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP +8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z +o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf +GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF +VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft +3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g +Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds +sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 +-----END CERTIFICATE----- + +America Online Root Certification Authority 2 +============================================= +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en +fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 +f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO +qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN +RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 +gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn +6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid +FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 +Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj +B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op +aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY +T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p ++DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg +JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy +zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO +ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh +1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf +GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff +Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP +cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 1 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw +NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88 +7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9 +EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl +0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645 +2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa +HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT +iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9 +28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV +yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR +vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P +qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z +IRlXvVWa +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA +============================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE +ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w +HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh +bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt +vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P +jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca +C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth +vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 +22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV +HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v +dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN +BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR +EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw +MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y +nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +TDC Internet Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE +ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx +NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu +ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j +xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL +znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc +5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 +otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI +AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM +VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM +MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe +UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G +CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m +gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ +2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb +O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU +Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l +-----END CERTIFICATE----- + +TDC OCES Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE +ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 +MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH +nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 +zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV +iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde +dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO +3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB +5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k +ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm +cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp +Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x +LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM +MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm +aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy +MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 ++RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 +NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 +A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc +A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 +AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 +AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== +-----END CERTIFICATE----- + +UTN DATACorp SGC Root CA +======================== +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ +BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa +MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w +HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy +dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys +raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo +wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA +9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv +33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud +DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 +BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD +LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 +DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 +I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx +EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP +DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- + +UTN USERFirst Email Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0 +BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05 +OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx +FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx +ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz +dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx +B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8 +om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG +TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl +yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE +AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV +HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll +bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne +xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+ +5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV +NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ +w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +UTN USERFirst Object Root CA +============================ +-----BEGIN CERTIFICATE----- +MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb +BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz +NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx +HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy +dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR +loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ +w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu +lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7 +RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL +BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8 +ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly +c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw +DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw +NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO +PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE +qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG +hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +NetLock Qualified (Class QA) Root +================================= +-----BEGIN CERTIFICATE----- +MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn +eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0 +bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0 +LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0 +dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP +aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV +CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e +8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb +m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ +0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM +0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV +HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2 +YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh +biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p +a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz +YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg +YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg +ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov +L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr +Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0 +aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg +YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0 +IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3 +DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN +wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg +W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc +R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR +5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko +-----END CERTIFICATE----- + +NetLock Notary (Class A) Root +============================= +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI +EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j +ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX +DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH +EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD +VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz +cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM +D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ +z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC +/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 +tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 +4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG +A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC +Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv +bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn +LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 +ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz +IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh +IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu +b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg +Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp +bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 +ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP +ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB +CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr +KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM +8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +NetLock Business (Class B) Root +=============================== +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg +VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD +VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv +bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg +VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S +o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr +1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV +HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ +RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh +dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 +ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv +c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg +YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz +Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA +bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl +IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 +YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj +cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM +43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR +stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- + +NetLock Express (Class C) Root +============================== +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ +BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j +ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB +jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z +W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 +euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw +DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN +RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn +YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB +IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i +aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 +ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y +emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k +IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ +UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg +YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 +xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW +gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Firmaprofesional Root CA +======================== +-----BEGIN CERTIFICATE----- +MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT +GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp +Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA +ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL +MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT +OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 +ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V +j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH +lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf +3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 +NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww +KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG +AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD +ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq +u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf +wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm +7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG +VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= +-----END CERTIFICATE----- + +Wells Fargo Root CA +=================== +-----BEGIN CERTIFICATE----- +MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV +BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl +bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv +MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX +x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 +E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 +OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j +sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj +YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF +BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD +ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv +m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R +OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx +x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 +tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG +EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy +dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4 +MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln +aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM +MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF +NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe +AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC +b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn +7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN +cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp +WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5 +haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY +MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw +HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9 +MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn +jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ +MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H +VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl +vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl +OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3 +1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq +nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy +x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 1 +============================================== +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP +MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 +acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx +MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg +U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB +TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC +aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX +yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i +Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ +8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 +W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME +BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 +sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE +q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY +nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2 +============================================== +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN +MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr +dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe +LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI +x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g +QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr +5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB +AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt +Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ +hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P +9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 +UrbnBEI= +-----END CERTIFICATE----- + +SwissSign Platinum CA - G2 +========================== +-----BEGIN CERTIFICATE----- +MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWduIFBsYXRpbnVtIENBIC0gRzIw +HhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAwWjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMM +U3dpc3NTaWduIEFHMSMwIQYDVQQDExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu +669yIIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2HtnIuJpX+UF +eNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+6ixuEFGSzH7VozPY1kne +WCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5objM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIo +j5+saCB9bzuohTEJfwvH6GXp43gOCWcwizSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/6 +8++QHkwFix7qepF6w9fl+zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34T +aNhxKFrYzt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaPpZjy +domyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtFKwH3HBqi7Ri6Cr2D ++m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuWae5ogObnmLo2t/5u7Su9IPhlGdpV +CX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMBAAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCv +zAeHFUdvOMW0ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW +IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUAA4ICAQAIhab1 +Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0uMoI3LQwnkAHFmtllXcBrqS3 +NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4 +U99REJNi54Av4tHgvI42Rncz7Lj7jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8 +KV2LwUvJ4ooTHbG/u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl +9x8DYSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1puEa+S1B +aYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXaicYwu+uPyyIIoK6q8QNs +OktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbGDI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSY +Mdp08YSTcU1f+2BY0fvEwW2JorsgH51xkcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAci +IfNAChs0B0QTwoRqjt8ZWr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +IGC/A +===== +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD +VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE +Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy +MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI +EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT +STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 +TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW +So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy +HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd +frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ +tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB +egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC +iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK +q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q +MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI +lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF +0mBWWg== +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +S-TRUST Authentication and Encryption Root CA 2005 PN +===================================================== +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE +BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh +cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT +LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w +NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk +ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj +aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp +b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob +4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL +g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf +eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3 +KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB +/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv +bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU +D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD +pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08 +P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA +nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit +F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b +Hz2eBIPdltkdOpQ= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. +====================================== +-----BEGIN CERTIFICATE----- +MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT +AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg +LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w +HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ +U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh +IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN +yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU +2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 +4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP +2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm +8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf +HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa +Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK +5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b +czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g +ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF +BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug +cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf +AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX +EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v +/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 +MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 +3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk +eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f +/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h +RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU +Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 2 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw +MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw +IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 +xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ +Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u +SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G +dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ +KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj +TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP +JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk +vQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 3 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw +MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W +yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo +6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ +uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk +2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE +O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 +yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 +IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal +092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc +5A== +-----END CERTIFICATE----- + +TC TrustCenter Universal CA I +============================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy +IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN +MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg +VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw +JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC +qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv +xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw +ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O +gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j +BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG +1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy +vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 +ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT +ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a +7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +ComSign CA +========== +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD +EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy +MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp +Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q +ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy +P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN +GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk +YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM +rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy +oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P +AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+ +VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2 +QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI +mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb +/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG +zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U +AGegcQCCSA== +-----END CERTIFICATE----- + +ComSign Secured CA +================== +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE +AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w +NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD +QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs +49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH +7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB +kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 +9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw +AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t +U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA +j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC +AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a +BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp +FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP +51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +Buypass Class 2 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 +MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M +cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 +0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 +0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R +uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV +1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt +7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 +fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w +wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +Buypass Class 3 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 +MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx +ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 +n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia +AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c +1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 +pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA +EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 +htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj +el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 +-----END CERTIFICATE----- + +EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 +========================================================================== +-----BEGIN CERTIFICATE----- +MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg +QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe +Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p +ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt +IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by +X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b +gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr +eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ +TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy +Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn +uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI +qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm +ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0 +Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW +Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t +FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm +zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k +XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT +bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU +RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK +1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt +2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ +Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9 +AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +============================================ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +CA Disig +======== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK +QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw +MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz +bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm +GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD +Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo +hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt +ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w +gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P +AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz +aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff +ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa +BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t +WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 +mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K +ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA +4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +Juur-SK +======= +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA +c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw +DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG +SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy +aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf +TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC ++Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw +UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa +Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF +MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD +HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh +AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA +cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr +AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw +cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G +A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo +ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL +abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 +IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh +Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 +yyqcjg== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD +T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4 +MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG +A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk +WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD +YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew +MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb +m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk +HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT +xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2 +3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9 +2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq +TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz +4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU +9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg +aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP +eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk +zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1 +ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI +KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq +nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE +I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp +MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o +tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ +VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2 +yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa +XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n +0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ +RjXZ+Hxb +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky +CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX +bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ +D/xwzoiQ +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi +=================================================== +-----BEGIN CERTIFICATE----- +MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz +ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 +MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 +cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u +aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY +8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y +jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI +JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk +9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG +SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d +F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq +D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 +Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq +fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +TC TrustCenter Universal CA III +=============================== +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy +IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe +Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU +QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex +KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt +QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO +juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut +CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 +M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G +A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA +g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ +KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK +BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV +CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq +woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================= +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +Root CA Generalitat Valenciana +============================== +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE +ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 +IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 +WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE +CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 +F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B +ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ +D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte +JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB +AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n +dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB +ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl +AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA +YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy +AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt +AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA +YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu +AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA +OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 +dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV +BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S +b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh +TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz +Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 +NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH +iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt ++GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +A-Trust-nQual-03 +================ +-----BEGIN CERTIFICATE----- +MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE +Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy +a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R +dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw +RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 +ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 +c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA +zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n +yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE +SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 +iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V +cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV +eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 +ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr +sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd +JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS +mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 +ahq97BvIxYSazQ== +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +Vivox Root CA +============= +-----BEGIN CERTIFICATE----- +MIID5jCCA0+gAwIBAgIJAImvD34gft3eMA0GCSqGSIb3DQEBBAUAMIGpMRQwEgYD +VQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNhdGUgRGVwYXJ0bWVu +dDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMwEQYDVQQHEwpGcmFt +aW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzEWMBQG +A1UEAxMNVml2b3ggUm9vdCBDQTAeFw0wNjEyMDExNjUzNDZaFw0xNjExMjgxNjUz +NDZaMIGpMRQwEgYDVQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNh +dGUgRGVwYXJ0bWVudDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMw +EQYDVQQHEwpGcmFtaW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYD +VQQGEwJVUzEWMBQGA1UEAxMNVml2b3ggUm9vdCBDQTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAt6uRnN9SsAnM4LfLUB31ZUmRPxv+RrwSjDhQPbpmVGjQeeom +5zU74pJ3WGtS6Iq6QYKah0NdqjQ1dEEd8943Bbfy0uqdfQbOmedjDKcGzAwvgKai +2gJnKFi8pxbV4LYrFbtwMHzhQOHL5Ue5MICbCoX0fkTg+tmQ/cKu489jiRkCAwEA +AaOCARIwggEOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFAbenfLtlQ0ZUmc/tW0Q +bWn3UgukMIHeBgNVHSMEgdYwgdOAFAbenfLtlQ0ZUmc/tW0QbWn3UgukoYGvpIGs +MIGpMRQwEgYDVQQKEwtWaXZveCwgSW5jLjEfMB0GA1UECxMWQ2VydGlmaWNhdGUg +RGVwYXJ0bWVudDEeMBwGCSqGSIb3DQEJARYPY2VydHNAdml2b3guY29tMRMwEQYD +VQQHEwpGcmFtaW5naGFtMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQG +EwJVUzEWMBQGA1UEAxMNVml2b3ggUm9vdCBDQYIJAImvD34gft3eMA0GCSqGSIb3 +DQEBBAUAA4GBAFZMWOh7lT7fOMakbcV4sh1ePd5bm04QdUn/rKTfERuiBc1UC1Qq +PAgtvJvl39wIB581WE7+QZZDUQc4hUlFQetbXSnXIkZ1kLH2wPuKgkunKjXviuzk +ZGgJSPbsCb2+Ika9Cd4V6bNzucZp523TcSNNNmimyFR1iuEryLSEpI1v +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEUDCCA7mgAwIBAgIJAN4ppNGwj6yIMA0GCSqGSIb3DQEBBAUAMIHMMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j +aXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5jLjEpMCcGA1UECxMgTGluZGVu +IExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIExpbmRlbiBMYWIg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZIhvcNAQkBFhBjYUBsaW5kZW5s +YWIuY29tMB4XDTA1MDQyMTAyNDAzMVoXDTI1MDQxNjAyNDAzMVowgcwxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp +c2NvMRkwFwYDVQQKExBMaW5kZW4gTGFiLCBJbmMuMSkwJwYDVQQLEyBMaW5kZW4g +TGFiIENlcnRpZmljYXRlIEF1dGhvcml0eTEpMCcGA1UEAxMgTGluZGVuIExhYiBD +ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgkqhkiG9w0BCQEWEGNhQGxpbmRlbmxh +Yi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKXh1MThucdTbMg9bYBO +rAm8yWns32YojB0PRfbq8rUjepEhTm3/13s0u399Uc202v4ejcGhkIDWJZd2NZMF +oKrhmRfxGHSKPCuFaXC3jh0lRECj7k8FoPkcmaPjSyodrDFDUUuv+C06oYJoI+rk +8REyal9NwgHvqCzOrZtiTXAdAgMBAAGjggE2MIIBMjAdBgNVHQ4EFgQUO1zK2e1f +1wO1fHAjq6DTJobKDrcwggEBBgNVHSMEgfkwgfaAFDtcytntX9cDtXxwI6ug0yaG +yg63oYHSpIHPMIHMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEW +MBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5j +LjEpMCcGA1UECxMgTGluZGVuIExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAn +BgNVBAMTIExpbmRlbiBMYWIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZI +hvcNAQkBFhBjYUBsaW5kZW5sYWIuY29tggkA3imk0bCPrIgwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQQFAAOBgQA/ZkgfvwHYqk1UIAKZS3kMCxz0HvYuEQtviwnu +xA39CIJ65Zozs28Eg1aV9/Y+Of7TnWhW+U3J3/wD/GghaAGiKK6vMn9gJBIdBX/9 +e6ef37VGyiOEFFjnUIbuk0RWty0orN76q/lI/xjCi15XSA/VSq2j4vmnwfZcPTDu +glmQ1A== +-----END CERTIFICATE----- diff --git a/indra/newview/licenses-solaris.txt b/indra/newview/licenses-solaris.txt deleted file mode 100644 index c19f939a80..0000000000 --- a/indra/newview/licenses-solaris.txt +++ /dev/null @@ -1,685 +0,0 @@ -=========== -APR License -=========== - -Copyright 2000-2004 The Apache Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -============== -Base32 License -============== - - * Copyright (c) 2006 Christian Biere - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the authors nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - -============ -cURL License -============ - -COPYRIGHT AND PERMISSION NOTICE - -Copyright (c) 1996 - 2002, Daniel Stenberg, . - -All rights reserved. - -Permission to use, copy, modify, and distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright -notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of a copyright holder shall not -be used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization of the copyright holder. - - -============= -expat License -============= - -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -================ -FreeType License -================ - -Portions of this software are copyright (c) 2003 The FreeType -Project (www.freetype.org). All rights reserved. - -========================== -FSI FontShop International -========================== - -Certain of the fonts in the Meta family of copyrighted typefaces are -used in Second Life under license from FSI FontShop -International. Copies of such Meta fonts that are included in the -Viewer are not themselves open source and are not available under the -GPL license, and they may not be copied. Developers may use those -fonts solely to the extent necessary to use or customize the Linden -Software in Second Life and to develop and distribute content solely -for use in the Second Life environment, and for no other purposes. -Second Life developers who wish to make other uses of Meta fonts must -obtain a license from FSI FontShop International at www.fontfont.com. - -========== -GL License -========== - -Mesa 3-D graphics library -Version: 6.2 - -Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -========================= -glh OpenGL helper library -========================= - -glh - is a platform-indepenedent C++ OpenGL helper library - - -Copyright (c) 2000 Cass Everitt - Copyright (c) 2000 NVIDIA Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or - without modification, are permitted provided that the following - conditions are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - * The names of contributors to this software may not be used - to endorse or promote products derived from this software - without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - -Cass Everitt - cass@r3.nu - -======================= -JPEG Library 6b License -======================= - -This software is based in part on the work of the Independent JPEG Group - -================ -JPEG2000 License -================ - -Copyright 2001, David Taubman, The University of New South Wales (UNSW) -The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW) -Neither this copyright statement, nor the licensing details below -may be removed from this file or dissociated from its contents. - -Licensee: Linden Research, Inc. -License number: 00024 -The licensee has been granted a COMMERCIAL license to the contents of -this source file. A brief summary of this license appears below. This -summary is not to be relied upon in preference to the full text of the -license agreement, accepted at purchase of the license. -1. The Licensee has the right to Commercial Use of the Kakadu software, - including distribution of one or more Applications built using the - software. -2. The Licensee has the right to Internal Use of the Kakadu software, - including use by employees of the Licensee or an Affiliate for the - purpose of performing services on behalf of the Licensee or Affiliate, - or in the performance of services for Third Parties who engage Licensee - or an Affiliate for such services. -3. The Licensee has the right to distribute Reusable Code (including - source code and dynamically or statically linked libraries) to a Third - Party, provided the Third Party possesses a license to use the Kakadu - software. - -================== -ogg/vorbis License -================== - -Copyright (c) 2001, Xiphophorus - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -- Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -- Neither the name of the Xiphophorus nor the names of its contributors -may be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -=========== -SDL License -=========== - -SDL - Simple DirectMedia Layer -Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with this library; if not, write to the Free -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Sam Lantinga -slouken@libsdl.org - -The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html - -============= -ELFIO License -============= - -ELFIO.h - ELF reader and producer. -Copyright (C) 2001 Serge Lamikhov-Center - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -The GNU Library GPL is available at http://www.gnu.org/copyleft/lesser.html - -=============== -OpenSSL License -=============== - -Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -3. All advertising materials mentioning features or use of this - software must display the following acknowledgment: - "This product includes software developed by the OpenSSL Project - for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - -4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - endorse or promote products derived from this software without - prior written permission. For written permission, please contact - openssl-core@openssl.org. - -5. Products derived from this software may not be called "OpenSSL" - nor may "OpenSSL" appear in their names without prior written - permission of the OpenSSL Project. - -6. Redistributions of any form whatsoever must retain the following - acknowledgment: - "This product includes software developed by the OpenSSL Project - for use in the OpenSSL Toolkit (http://www.openssl.org/)" - -THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR -ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. -==================================================================== - -This product includes cryptographic software written by Eric Young -(eay@cryptsoft.com). This product includes software written by Tim -Hudson (tjh@cryptsoft.com). - - - -======================= -Original SSLeay License -======================= - -Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -All rights reserved. - -This package is an SSL implementation written -by Eric Young (eay@cryptsoft.com). -The implementation was written so as to conform with Netscapes SSL. - -This library is free for commercial and non-commercial use as long as -the following conditions are aheared to. The following conditions -apply to all code found in this distribution, be it the RC4, RSA, -lhash, DES, etc., code; not just the SSL code. The SSL documentation -included with this distribution is covered by the same copyright terms -except that the holder is Tim Hudson (tjh@cryptsoft.com). - -Copyright remains Eric Young's, and as such any Copyright notices in -the code are not to be removed. -If this package is used in a product, Eric Young should be given attribution -as the author of the parts of the library used. -This can be in the form of a textual message at program startup or -in documentation (online or textual) provided with the package. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - "This product includes cryptographic software written by - Eric Young (eay@cryptsoft.com)" - The word 'cryptographic' can be left out if the rouines from the library - being used are not cryptographic related :-). -4. If you include any Windows specific code (or a derivative thereof) from - the apps directory (application code) you must include an acknowledgement: - "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - -THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The licence and distribution terms for any publically available version or -derivative of this code cannot be changed. i.e. this code cannot simply be -copied and put under another distribution licence -[including the GNU Public Licence.] - - -================== -xmlrpc-epi License -================== - -Copyright 2000 Epinions, Inc. - -Subject to the following 3 conditions, Epinions, Inc. permits you, free of charge, to (a) use, copy, distribute, modify, perform and display this software and associated documentation files (the "Software"), and (b) permit others to whom the Software is furnished to do so as well. - -1) The above copyright notice and this permission notice shall be included without modification in all copies or substantial portions of the Software. - -2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. - -3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. - - -=============== -libuuid License -=============== - -Copyright (C) 1999, 2000, 2003, 2004 by Theodore Ts'o - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, and the entire permission notice in its entirety, - including the disclaimer of warranties. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The name of the author may not be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - - -============ -zlib License -============ - -'zlib' general purpose compression library version 1.1.4, March 11th, 2002 - -Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the -use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -The origin of this software must not be misrepresented; you must not claim -that you wrote the original software. If you use this software in a product, -an acknowledgment in the product documentation would be appreciated but is -not required. - -Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. - -This notice may not be removed or altered from any source distribution. - -Jean-loup Gailly -jloup@gzip.org - -Mark Adler -madler@alumni.caltech.edu - -================= -Vivox SDK License -================= - -RSA Data Security, Inc. MD5 Message-Digest Algorithm - -Audio coding: Polycom Siren14TM (ITU-T Rec. G.722.1 Annex C) - -Open Source Software Licensing -Each open source software component utilized by this product is subject to its own copyright and licensing terms, as listed below. - - -************************************************************* -************************************************************* - -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2000 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -************************************************************* -************************************************************* -RTP code under Lesser General Public License - -/* - The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack. - Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -************************************************************ -************************************************************* - -/* - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * - * - */ -************************************************************* -************************************************************* - -Internet Software Consortium code - -/* This is from the BIND 4.9.4 release, modified to compile by itself */ -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -************************************************************* - -************************************************************* - -************************************************************ - -http://tinyxpath.sourceforge.net/ - -TinyXPath is covered by the zlib license : - - www.sourceforge.net/projects/tinyxpath - Copyright (c) 2002-2006 Yves Berquin (yvesb@users.sourceforge.net) - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any - damages arising from the use of this software. - - Permission is granted to anyone to use this software for any - purpose, including commercial applications, and to alter it and - redistribute it freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product documentation - would be appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and - must not be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution. - - -************************************************************ -************************************************************ - -THE FREE SOFTWARE FOUNDATION - -Any customer may request the source code for all open source portions of this product which are covered by the Free Software Foundation's General Public License (GPL), for a period of three years from purchase. Please contact the vendor from whom you obtained this product for instructions. A fee equivalent to the cost of making the code available may be charged. Alternatively, customers may choose to download desired GPL components directly from their original vendors. Specifically, this product contains the following GPL-licensed components: - - -From Vivox: - - Assorted software components. To request source, contact Vivox at: - Vivox, Inc. - Attn: customer support - 40 Speen Street Suite 402 - Framingham, MA 01701 diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index d9fef022e5..5ccedee06d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -482,7 +482,7 @@ class WindowsManifest(ViewerManifest): self.path(src="licenses-win32.txt", dst="licenses.txt") self.path("featuretable.txt") - self.path("featuretable_xp.txt") + self.path("ca-bundle.crt") # Media plugins - CEF if self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"): @@ -836,6 +836,7 @@ class DarwinManifest(ViewerManifest): self.path("licenses-mac.txt", dst="licenses.txt") self.path("featuretable_mac.txt") self.path("SecondLife.nib") + self.path("ca-bundle.crt") icon_path = self.icon_path() if self.prefix(src=icon_path, dst="") : @@ -1295,6 +1296,7 @@ class LinuxManifest(ViewerManifest): print "Skipping llcommon.so (assuming llcommon was linked statically)" self.path("featuretable_linux.txt") + self.path("ca-bundle.crt") def package_finish(self): installer_name = self.installer_base_name() From 7ead7c7285c3f47f1dd271f80adfd098b6757326 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 14 Jun 2017 16:02:54 -0700 Subject: [PATCH 136/183] SL-700: temporarily use local version of ca-bundle.crt, remove ca-bundle copy calls from viewer manifest --- indra/newview/viewer_manifest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 5ccedee06d..001c4817b1 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -460,7 +460,6 @@ class WindowsManifest(ViewerManifest): self.path("ortp.dll") self.path("libsndfile-1.dll") self.path("vivoxoal.dll") - self.path("ca-bundle.crt") # Security self.path("ssleay32.dll") @@ -915,7 +914,6 @@ class DarwinManifest(ViewerManifest): 'libvivoxoal.dylib', 'libvivoxsdk.dylib', 'libvivoxplatform.dylib', - 'ca-bundle.crt', 'SLVoice', ): self.path2basename(relpkgdir, libfile) From 430566a393266883df8af922185e57164f474d08 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 15 Jun 2017 09:01:52 -0700 Subject: [PATCH 137/183] SL-700: upgrade to VMP package 506528 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 363735f664..adbcb02f60 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - 651a9a4cfa60ac75be17958ced9873dd + 3cc13ed44cce8705e854f47d1ef3d27f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6512/22903/viewer_manager-1.0.506501-darwin64-506501.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6539/23018/viewer_manager-1.0.506528-darwin64-506528.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - 90c5c2556d1636bd56c232c7ba10361c + c81cffa70d6a2f189060a9704c9e23f7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6516/22916/viewer_manager-1.0.506501-windows-506501.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6540/23024/viewer_manager-1.0.506528-windows-506528.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506501 + 1.0.506528 vlc-bin From 55796deebb553d23b524267d93812dcc7ff00679 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 16 Jun 2017 10:43:04 -0400 Subject: [PATCH 138/183] MAINT-7505: correct packaging of python llbase --- indra/newview/viewer_manifest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 001c4817b1..58bdf1816f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -372,7 +372,7 @@ class WindowsManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - llbasedir = os.path.join(pkgdir, "llbase") + llbasedir = os.path.join(pkgdir, "lib", "python", "llbase") if self.is_packaging_viewer(): # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe. @@ -792,7 +792,7 @@ class DarwinManifest(ViewerManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") - llbasedir = os.path.join(pkgdir, "llbase") + llbasedir = os.path.join(pkgdir, "lib", "python", "llbase") requestsdir = os.path.join(pkgdir, "requests") if self.prefix(src="", dst="Contents"): # everything goes in Contents @@ -1255,8 +1255,8 @@ class LinuxManifest(ViewerManifest): if not os.path.exists(llbase_path): os.makedirs(llbase_path) if self.prefix(dst="llbase"): - self.path2basename("../packages/llbase","*.py") - self.path2basename("../packages/llbase","_cllsd.so") + self.path2basename("../packages/lib/python/llbase","*.py") + self.path2basename("../packages/lib/python/llbase","_cllsd.so") self.end_prefix("bin") if self.prefix("res-sdl"): From 51116c46c684de158000299cf7bef6f7e46fb2a7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 16 Jun 2017 13:29:44 -0400 Subject: [PATCH 139/183] remove redundant slash from update service base url (cosmetic) --- indra/newview/viewer_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 58bdf1816f..97ed24bad7 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -207,7 +207,7 @@ class ViewerManifest(LLManifest): "Channel Base": CHANNEL_VENDOR_BASE, "Channel":self.channel_with_pkg_suffix(), "Platform":build_data_json_platform, - "Update Service":"https://update.secondlife.com/update/", + "Update Service":"https://update.secondlife.com/update", } #MAINT-7294: Windows exe names depend on channel name, so write that in also if build_data_json_platform.startswith('win'): From ff9314d955b531e34c298b9b4c533106ed0e52f4 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 16 Jun 2017 13:34:51 -0400 Subject: [PATCH 140/183] update viewer-manager to fix problem with finding the ca-bundle --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index adbcb02f60..8482c04544 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - 3cc13ed44cce8705e854f47d1ef3d27f + cba2a87cedfde7566261de1e8a609da6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6539/23018/viewer_manager-1.0.506528-darwin64-506528.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6618/23361/viewer_manager-1.0.506607-darwin64-506607.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - c81cffa70d6a2f189060a9704c9e23f7 + 9641fac387abdadb354ce618fda2dfa6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6540/23024/viewer_manager-1.0.506528-windows-506528.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6619/23367/viewer_manager-1.0.506607-windows-506607.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506528 + 1.0.506607 vlc-bin From 6465523de68d24b04473fcc03e8a965de07a57a3 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Fri, 16 Jun 2017 16:48:57 -0400 Subject: [PATCH 141/183] remove dependency on urllib3 in viewer-manager --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 8482c04544..9b7029745c 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - cba2a87cedfde7566261de1e8a609da6 + bd26f884a20781b349dd5f7e156896e7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6618/23361/viewer_manager-1.0.506607-darwin64-506607.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6633/23444/viewer_manager-1.0.506622-darwin64-506622.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - 9641fac387abdadb354ce618fda2dfa6 + b7056f9eb96137288ae1baba22fb7eaa url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6619/23367/viewer_manager-1.0.506607-windows-506607.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6634/23454/viewer_manager-1.0.506622-windows-506622.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506607 + 1.0.506622 vlc-bin From 543d9b98a315980ee1ab35558ad07dd45673b837 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 19 Jun 2017 18:01:40 -0400 Subject: [PATCH 142/183] update viewer-manager, primarily to solve Mac packaging problem --- autobuild.xml | 110 ++++++++++++++++++++++++++++--- indra/cmake/Requests.cmake | 3 + indra/newview/viewer_manifest.py | 32 ++++++++- 3 files changed, 133 insertions(+), 12 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9b7029745c..5e0f501765 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -225,6 +225,36 @@ version 1.57 + chardet + + copyright + Contributors to charset (see https://github.com/chardet/chardet) + description + Python Character Encoding Library + license + LGPL + license_file + LICENSES/chardet.txt + name + chardet + platforms + + darwin64 + + archive + + hash + 0124862b6a1b88455c78a68f8b823d21 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2 + + name + darwin64 + + + version + 3.0.4 + colladadom copyright @@ -1435,6 +1465,36 @@ version 2012.1-2 + idna + + copyright + Copyright (c) 2013-2017, Kim Davies. All rights reserved. + description + Python Internationalized Domain Names in Applications (IDNA) Library + license + see idna.rst + license_file + LICENSES/idna.rst + name + idna + platforms + + darwin64 + + archive + + hash + 7dfe9fc4023d7d4f511dd9fac7258266 + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2 + + name + darwin64 + + + version + 2.5 + jpeglib copyright @@ -2788,13 +2848,13 @@ requests copyright - Kenneth Reitz + Copyright 2016 Kenneth Reitz description Python HTTP Library license Apache license_file - requests.txt + LICENSES/requests.txt name requests platforms @@ -2804,9 +2864,9 @@ archive hash - 20a84252b40223d5c08a6c1575b3333b + b8d134a970261b445a3f376ba4e05ff7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4106/11536/requests-1.0-darwin64-504094.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2 name darwin64 @@ -2829,7 +2889,7 @@ source_type hg version - 1.0 + 2.18.1 slvoice @@ -3041,6 +3101,36 @@ version 0.8.0.1 + urllib3 + + copyright + Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt) + description + Python HTTP Library + license + MIT + license_file + LICENSES/urllib3.txt + name + urllib3 + platforms + + darwin64 + + archive + + hash + 22f64c7fbb6704d2e9519fd1cca8e49b + url + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2 + + name + darwin64 + + + version + 1.21.1 + viewer-manager copyright @@ -3060,9 +3150,9 @@ archive hash - bd26f884a20781b349dd5f7e156896e7 + 76e5db832ec9c6aeac267b8179d9212b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6633/23444/viewer_manager-1.0.506622-darwin64-506622.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6706/23848/viewer_manager-1.0.506695-darwin64-506695.tar.bz2 name darwin64 @@ -3084,9 +3174,9 @@ archive hash - b7056f9eb96137288ae1baba22fb7eaa + d0f708f119d5e0c437e73cf2a332bf85 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6634/23454/viewer_manager-1.0.506622-windows-506622.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6707/23854/viewer_manager-1.0.506695-windows-506695.tar.bz2 name windows @@ -3097,7 +3187,7 @@ source_type hg version - 1.0.506622 + 1.0.506695 vlc-bin diff --git a/indra/cmake/Requests.cmake b/indra/cmake/Requests.cmake index 84ee070813..b9c729d697 100644 --- a/indra/cmake/Requests.cmake +++ b/indra/cmake/Requests.cmake @@ -1,4 +1,7 @@ if (DARWIN) include (Prebuilt) use_prebuilt_binary(requests) + use_prebuilt_binary(urllib3) + use_prebuilt_binary(chardet) + use_prebuilt_binary(idna) endif (DARWIN) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 97ed24bad7..377c46f8e0 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -793,7 +793,10 @@ class DarwinManifest(ViewerManifest): debpkgdir = os.path.join(pkgdir, "lib", "debug") vmpdir = os.path.join(pkgdir, "VMP") llbasedir = os.path.join(pkgdir, "lib", "python", "llbase") - requestsdir = os.path.join(pkgdir, "requests") + requestsdir = os.path.join(pkgdir, "lib", "python", "requests") + urllib3dir = os.path.join(pkgdir, "lib", "python", "urllib3") + chardetdir = os.path.join(pkgdir, "lib", "python", "chardet") + idnadir = os.path.join(pkgdir, "lib", "python", "idna") if self.prefix(src="", dst="Contents"): # everything goes in Contents self.path("Info.plist", dst="Info.plist") @@ -806,10 +809,17 @@ class DarwinManifest(ViewerManifest): #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322, SL-323 self.path2basename(vmpdir,"SL_Launcher") self.path2basename(vmpdir,"*.py") + # certifi will be imported by requests; this is our custom version to get our ca-bundle.crt + certifi_path = os.path.join(self.get_dst_prefix(),'certifi') + if not os.path.exists(certifi_path): + os.makedirs(certifi_path) + if self.prefix(dst="certifi"): + self.path2basename(os.path.join(vmpdir,"certifi"),"*") + self.end_prefix() + # llbase provides our llrest service layer and llsd decoding llbase_path = os.path.join(self.get_dst_prefix(),'llbase') if not os.path.exists(llbase_path): os.makedirs(llbase_path) - #before, we only needed llbase at build time. With VMP, we need it at run time. if self.prefix(dst="llbase"): self.path2basename(llbasedir,"*.py") self.path2basename(llbasedir,"_cllsd.so") @@ -822,6 +832,24 @@ class DarwinManifest(ViewerManifest): if self.prefix(dst="requests"): self.path2basename(requestsdir,"*") self.end_prefix() + urllib3_path = os.path.join(self.get_dst_prefix(),'urllib3') + if not os.path.exists(urllib3_path): + os.makedirs(urllib3_path) + if self.prefix(dst="urllib3"): + self.path2basename(urllib3dir,"*") + self.end_prefix() + chardet_path = os.path.join(self.get_dst_prefix(),'chardet') + if not os.path.exists(chardet_path): + os.makedirs(chardet_path) + if self.prefix(dst="chardet"): + self.path2basename(chardetdir,"*") + self.end_prefix() + idna_path = os.path.join(self.get_dst_prefix(),'idna') + if not os.path.exists(idna_path): + os.makedirs(idna_path) + if self.prefix(dst="idna"): + self.path2basename(idnadir,"*") + self.end_prefix() self.end_prefix() # most everything goes in the Resources directory From e7b8a598f0434775c9c8eb13877476dc6a39133c Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 20 Jun 2017 10:20:46 -0700 Subject: [PATCH 143/183] upgrade to VMP package 506528 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 9b7029745c..adbcb02f60 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3060,9 +3060,9 @@ archive hash - bd26f884a20781b349dd5f7e156896e7 + 3cc13ed44cce8705e854f47d1ef3d27f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6633/23444/viewer_manager-1.0.506622-darwin64-506622.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6539/23018/viewer_manager-1.0.506528-darwin64-506528.tar.bz2 name darwin64 @@ -3084,9 +3084,9 @@ archive hash - b7056f9eb96137288ae1baba22fb7eaa + c81cffa70d6a2f189060a9704c9e23f7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6634/23454/viewer_manager-1.0.506622-windows-506622.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6540/23024/viewer_manager-1.0.506528-windows-506528.tar.bz2 name windows @@ -3097,7 +3097,7 @@ source_type hg version - 1.0.506622 + 1.0.506528 vlc-bin From d09bebe3235e7f8966b1ccec67cdaa41b248db27 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 20 Jun 2017 14:32:50 -0700 Subject: [PATCH 144/183] upgrade to VMP package 506741 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6dcf3fd903..4b4a623696 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 3cc13ed44cce8705e854f47d1ef3d27f + 18812f9ef5d389bce37b6d4e7abbc017 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6539/23018/viewer_manager-1.0.506528-darwin64-506528.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6753/24153/viewer_manager-1.0.506741-darwin64-506741.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - c81cffa70d6a2f189060a9704c9e23f7 + 8d81b3bbe18585fd5f397f8b7f63e2cd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6540/23024/viewer_manager-1.0.506528-windows-506528.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6752/24123/viewer_manager-1.0.506741-windows-506741.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506528 + 1.0.506741 vlc-bin From 2a24defdd0be397b2247022b471e85ed823f65fb Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 21 Jun 2017 15:37:15 -0700 Subject: [PATCH 145/183] upgrade to VMP package 506766 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4b4a623696..14c398170e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 18812f9ef5d389bce37b6d4e7abbc017 + 76b264523cb94c879195ee7d513fca21 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6753/24153/viewer_manager-1.0.506741-darwin64-506741.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6777/24319/viewer_manager-1.0.506766-darwin64-506766.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 8d81b3bbe18585fd5f397f8b7f63e2cd + 433e57ad4bcaaecbf320468ad2192524 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6752/24123/viewer_manager-1.0.506741-windows-506741.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6779/24327/viewer_manager-1.0.506766-windows-506766.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506741 + 1.0.506766 vlc-bin From 58f62e2883fd450a36ff5491e5fb75ef334c7c13 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 22 Jun 2017 14:13:42 -0400 Subject: [PATCH 146/183] DRTVWR-418: Update to curl build 506810 --- autobuild.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ebf24a051c..c575faf73e 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -344,9 +344,9 @@ archive hash - 99fbc15f514be77c36280f300d257d5a + 8854daffb8b87a2238461a7f72e4b4fd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1077/2495/curl-7.47.0.501064-darwin64-501064.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6822/24534/curl-7.54.1.506810-darwin64-506810.tar.bz2 name darwin64 @@ -368,9 +368,9 @@ archive hash - e5d1b0439235f5f3829662a45e566743 + 37a6a2615d81b491e449e5680cf8d9c7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1075/2484/curl-7.47.0.501064-linux64-501064.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6821/24528/curl-7.54.1.506810-linux64-506810.tar.bz2 name linux64 @@ -380,11 +380,11 @@ archive hash - bda9f237d3e8238440bc5bedc2657547 + eb2508dd444ac885b7fdf7d89cd2e010 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1078/2487/curl-7.47.0.501064-windows-501064.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6823/24516/curl-7.54.1.506810-windows-506810.tar.bz2 name windows @@ -394,16 +394,16 @@ archive hash - f7fa42c7157cd5007283ae7a5d97393d + 1a9848d3b1ed53e57afe44f175c2ecea url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1079/2490/curl-7.47.0.501064-windows64-501064.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6824/24522/curl-7.54.1.506810-windows64-506810.tar.bz2 name windows64 version - 7.47.0.501064 + 7.54.1.506810 db From 6bcbee332827d4f341dab8f48ce929e07a8e6b22 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 22 Jun 2017 16:24:31 -0700 Subject: [PATCH 147/183] upgrade to VMP package 506825 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 14c398170e..33631603e4 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 76b264523cb94c879195ee7d513fca21 + e80a1e54cd419f96fed84f52f4803b0f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6777/24319/viewer_manager-1.0.506766-darwin64-506766.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6836/24610/viewer_manager-1.0.506825-darwin64-506825.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 433e57ad4bcaaecbf320468ad2192524 + 528d82bb5299c31f95a10af594f757d7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6779/24327/viewer_manager-1.0.506766-windows-506766.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6837/24616/viewer_manager-1.0.506825-windows-506825.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506766 + 1.0.506825 vlc-bin From faf237e60c66573b1293fd3e9f957ff56cca30ed Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 23 Jun 2017 09:49:09 -0700 Subject: [PATCH 148/183] MAINT-7515: point shortcut icon at viewer exe --- indra/newview/installers/windows/installer_template.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 0481c029ac..adc7c96ffc 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -318,9 +318,9 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ # Other shortcuts SetOutPath "$INSTDIR" CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE" CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE" CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ '"$INSTDIR\uninst.exe"' '' From b3c506bc68ea64d9e296d2be94380cd93b0c49c4 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Jun 2017 09:15:01 -0400 Subject: [PATCH 149/183] MAINT-7514: Add (32) or (64) to registry for "install again?" prompt. Specifically, append (32) or (64) to the four-part version number stored in the registry entry used to detect whether this viewer has already been installed. This is injected as a new VERSION_REGISTRY NSIS variable. (It was tempting to simply change the value of VERSION_LONG with the embedded address size. However, there is one other use of VERSION_LONG in the NSIS template. That use is the subject of MAINT-7533.) Synthesize the VERSION_REGISTRY value in viewer_manifest.py and add it to the substitution dict used to populate the NSIS template. ADDRESS_SIZE isn't passed into viewer_manifest.py, but it can be inferred from the existing 'arch' parameter: 'arch' as well as 'platform' is used to select the specific subclass of the ViewerManifest class to instantiate for this run. Add an appropriate address_size attribute to every such subclass. Change a couple existing tests on 'arch' to tests on self.address_size instead -- clearer to the maintainer. Also, given that subclass selection mechanism, the ViewerManifest base class shouldn't need if / elif tests on 'platform'. Make build_data_json_platform a class attribute as well, removing the base-class stanza that dynamically examines 'platform' and 'arch'. Similarly, move platform-specific tweaks to the build_data_dict used to populate build_data.json into a new finish_build_data_dict() method overridden by individual platform subclasses. Encapsulate the logic around running the Windows code-signing tool into a sign() method, and call it as needed. For obtaining environment variables with fallback values, use os.environ.get() instead of os.path.expandvars() with tests on the returned value. --- .../installers/windows/installer_template.nsi | 6 +- indra/newview/viewer_manifest.py | 137 +++++++++--------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 0481c029ac..f5b2de4fdc 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -331,7 +331,7 @@ FileClose $9 # Write registry WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_REGISTRY}" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "Linden Research, Inc." @@ -340,7 +340,7 @@ WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninst WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "HelpLink" "https://support.secondlife.com/contact-support/" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"' -WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_LONG}" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_REGISTRY}" WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500" # ~117 MB # from FS:Ansariel @@ -458,7 +458,7 @@ FunctionEnd Function CheckIfAlreadyCurrent Push $0 ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" - StrCmp $0 ${VERSION_LONG} 0 continue_install + StrCmp $0 ${VERSION_REGISTRY} 0 continue_install StrCmp $SKIP_DIALOGS "true" continue_install MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK continue_install Quit diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 377c46f8e0..3f6fc94d92 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -121,24 +121,6 @@ class ViewerManifest(LLManifest): settings_install['CmdLineGridChoice']['Value'] = self.grid() print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid() - #do not need to test for existence. If no platform is passed, llmanifest computes a default in get_default_platform - #the choice of value names (lnx, mac, win32, win) is dictated by the VMM API - build_data_json_platform = "" - if 'linux' in self.args['platform']: - build_data_json_platform = 'lnx' - elif 'darwin' in self.args['platform']: - build_data_json_platform = 'mac' - elif 'windows' in self.args['platform']: - #default case - build_data_json_platform = 'win' - if 'arch' in self.args and self.args['arch']: - if 'i686' in self.args['arch']: - build_data_json_platform = 'win32' - #we really shouldn't be here, something is very wrong at this point - else: - build_data_json_platform = 'None' - - # put_in_file(src=) need not be an actual pathname; it # only needs to be non-empty self.put_in_file(llsd.format_pretty_xml(settings_install), @@ -206,14 +188,10 @@ class ViewerManifest(LLManifest): build_data_dict = {"Type":"viewer","Version":'.'.join(self.args['version']), "Channel Base": CHANNEL_VENDOR_BASE, "Channel":self.channel_with_pkg_suffix(), - "Platform":build_data_json_platform, + "Platform":self.build_data_json_platform, "Update Service":"https://update.secondlife.com/update", } - #MAINT-7294: Windows exe names depend on channel name, so write that in also - if build_data_json_platform.startswith('win'): - build_data_dict.update({'Executable':self.final_exe()}) - if build_data_json_platform.startswith('mac'): - build_data_dict.update({'Bundle Id':self.args['bundleid']}) + build_data_dict = self.finish_build_data_dict(build_data_dict) with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle: json.dump(build_data_dict,build_data_handle) @@ -222,6 +200,9 @@ class ViewerManifest(LLManifest): if not self.path2basename(os.pardir, "build_data.json"): print "No build_data.json file" + def finish_build_data_dict(self, build_data_dict): + return build_data_dict + def grid(self): return self.args['grid'] @@ -319,6 +300,11 @@ class WindowsManifest(ViewerManifest): def final_exe(self): return self.app_name_oneword()+".exe" + def finish_build_data_dict(self, build_data_dict): + #MAINT-7294: Windows exe names depend on channel name, so write that in also + build_data_dict.update({'Executable':self.final_exe()}) + return build_data_dict + def test_msvcrt_and_copy_action(self, src, dst): # This is used to test a dll manifest. # It is used as a temporary override during the construct method @@ -431,7 +417,7 @@ class WindowsManifest(ViewerManifest): # Get fmodex dll, continue if missing try: - if(self.args['arch'].lower() == 'x86_64'): + if(self.address_size == 64): self.path("fmodex64.dll") else: self.path("fmodex.dll") @@ -664,6 +650,8 @@ class WindowsManifest(ViewerManifest): 'version' : '.'.join(self.args['version']), 'version_short' : '.'.join(self.args['version'][:-1]), 'version_dashes' : '-'.join(self.args['version']), + 'version_registry' : '%s(%s)' % + ('.'.join(self.args['version']), self.address_size), 'final_exe' : self.final_exe(), 'flags':'', 'app_name':self.app_name(), @@ -678,6 +666,7 @@ class WindowsManifest(ViewerManifest): !define VERSION "%(version_short)s" !define VERSION_LONG "%(version)s" !define VERSION_DASHES "%(version_dashes)s" + !define VERSION_REGISTRY "%(version_registry)s" !define VIEWER_EXE "%(final_exe)s" """ % substitution_strings @@ -694,7 +683,7 @@ class WindowsManifest(ViewerManifest): Caption "%(caption)s" """ - if(self.args['arch'].lower() == 'x86_64'): + if(self.address_size == 64): engage_registry="SetRegView 64" program_files="$PROGRAMFILES64" else: @@ -715,71 +704,77 @@ class WindowsManifest(ViewerManifest): # If we're on a build machine, sign the code using our Authenticode certificate. JC # note that the enclosing setup exe is signed later, after the makensis makes it. - sign_py = os.path.expandvars("${SIGN}") - if not sign_py or sign_py == "${SIGN}": - sign_py = 'C:\\buildscripts\\code-signing\\sign.py' - else: - sign_py = sign_py.replace('\\', '\\\\\\\\') - python = os.path.expandvars("${PYTHON}") - if not python or python == "${PYTHON}": - python = 'python' - if os.path.exists(sign_py): - #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. - print "about to run signing of: ", self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("apply_update.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("download_update.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("SL_Launcher.exe").replace('\\', '\\\\\\\\'))) - print "about to run signing of: ", self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of("update_manager.exe").replace('\\', '\\\\\\\\'))) - else: - print "Skipping code signing of vmp executables,", sign_py, "does not exist" + sign_py = os.environ.get('SIGN', r'C:\buildscripts\code-signing\sign.py') + python = os.environ.get('PYTHON', 'python') + #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. + for exe in ( + "apply_update.exe", + "download_update.exe", + "SL_Launcher.exe", + "update_manager.exe", + ): + self.sign(sign_py, exe) # We use the Unicode version of NSIS, available from # http://www.scratchpaper.com/ # Check two paths, one for Program Files, and one for Program Files (x86). # Yay 64bit windows. - NSIS_path = os.path.expandvars('${ProgramFiles}\\NSIS\\Unicode\\makensis.exe') - if not os.path.exists(NSIS_path): - NSIS_path = os.path.expandvars('${ProgramFiles(x86)}\\NSIS\\Unicode\\makensis.exe') + for ProgramFiles in 'ProgramFiles', 'ProgramFiles(x86)': + NSIS_path = os.path.expandvars(r'${%s}\NSIS\Unicode\makensis.exe' % ProgramFiles) + if os.path.exists(NSIS_path): + break installer_created=False nsis_attempts=3 nsis_retry_wait=15 - while (not installer_created) and (nsis_attempts > 0): + for attempt in xrange(nsis_attempts): try: - nsis_attempts-=1; self.run_command('"' + NSIS_path + '" /V2 ' + self.dst_path_of(tempfile)) - installer_created=True # if no exception was raised, the codesign worked except ManifestError, err: - if nsis_attempts: + if attempt+1 < nsis_attempts: print >> sys.stderr, "nsis failed, waiting %d seconds before retrying" % nsis_retry_wait time.sleep(nsis_retry_wait) nsis_retry_wait*=2 - else: - print >> sys.stderr, "Maximum nsis attempts exceeded; giving up" - raise - - if os.path.exists(sign_py): - print "about to run signing of: ", self.dst_path_of(installer_file).replace('\\', '\\\\\\\\') - self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of(installer_file).replace('\\', '\\\\\\\\'))) + else: + # NSIS worked! Done! + break else: - print "Skipping code signing of setup executable,", sign_py, "does not exist" + print >> sys.stderr, "Maximum nsis attempts exceeded; giving up" + raise + + self.sign(sign_py, installer_file) self.created_path(self.dst_path_of(installer_file)) self.package_file = installer_file + def sign(self, sign_py, exe): + if os.path.exists(sign_py): + dst_path = self.dst_path_of(exe) + print "about to run signing of: ", dst_path + self.run_command(' '.join((python, self.escape_slashes(sign_py), + self.escape_slashes(dst_path)))) + else: + print "Skipping code signing of %s: %s not found" % (exe, sign_py) + + def escape_slashes(self, path): + return path.replace('\\', '\\\\\\\\') class Windows_i686_Manifest(WindowsManifest): - # specialize when we must - pass - + # Although we aren't literally passed ADDRESS_SIZE, we can infer it from + # the passed 'arch', which is used to select the specific subclass. + address_size = 32 + build_data_json_platform = 'win32' class Windows_x86_64_Manifest(WindowsManifest): - # specialize when we must - pass + address_size = 64 + build_data_json_platform = 'win' class DarwinManifest(ViewerManifest): + build_data_json_platform = 'mac' + + def finish_build_data_dict(self, build_data_dict): + build_data_dict.update({'Bundle Id':self.args['bundleid']}) + return build_data_dict + def is_packaging_viewer(self): # darwin requires full app bundle packaging even for debugging. return True @@ -1237,7 +1232,7 @@ class DarwinManifest(ViewerManifest): class Darwin_i386_Manifest(DarwinManifest): - pass + address_size = 32 class Darwin_i686_Manifest(DarwinManifest): @@ -1246,10 +1241,12 @@ class Darwin_i686_Manifest(DarwinManifest): class Darwin_x86_64_Manifest(DarwinManifest): - pass + address_size = 64 class LinuxManifest(ViewerManifest): + build_data_json_platform = 'lnx' + def construct(self): super(LinuxManifest, self).construct() @@ -1369,6 +1366,8 @@ class LinuxManifest(ViewerManifest): self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name \*.py \! -name SL_Launcher \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) class Linux_i686_Manifest(LinuxManifest): + address_size = 32 + def construct(self): super(Linux_i686_Manifest, self).construct() @@ -1454,6 +1453,8 @@ class Linux_i686_Manifest(LinuxManifest): class Linux_x86_64_Manifest(LinuxManifest): + address_size = 64 + def construct(self): super(Linux_x86_64_Manifest, self).construct() From 924414d65e06c6aa4d835fd40ea7940c7ca92080 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Jun 2017 10:04:57 -0400 Subject: [PATCH 150/183] MAINT-7514: Fetch needed env vars in WindowsManifest.sign() method. --- indra/newview/viewer_manifest.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 3f6fc94d92..2d88fe7dce 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -704,16 +704,14 @@ class WindowsManifest(ViewerManifest): # If we're on a build machine, sign the code using our Authenticode certificate. JC # note that the enclosing setup exe is signed later, after the makensis makes it. - sign_py = os.environ.get('SIGN', r'C:\buildscripts\code-signing\sign.py') - python = os.environ.get('PYTHON', 'python') - #Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. + # Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc. for exe in ( "apply_update.exe", "download_update.exe", "SL_Launcher.exe", "update_manager.exe", ): - self.sign(sign_py, exe) + self.sign(exe) # We use the Unicode version of NSIS, available from # http://www.scratchpaper.com/ @@ -741,11 +739,13 @@ class WindowsManifest(ViewerManifest): print >> sys.stderr, "Maximum nsis attempts exceeded; giving up" raise - self.sign(sign_py, installer_file) + self.sign(installer_file) self.created_path(self.dst_path_of(installer_file)) self.package_file = installer_file - def sign(self, sign_py, exe): + def sign(self, exe): + sign_py = os.environ.get('SIGN', r'C:\buildscripts\code-signing\sign.py') + python = os.environ.get('PYTHON', 'python') if os.path.exists(sign_py): dst_path = self.dst_path_of(exe) print "about to run signing of: ", dst_path From 74afc93a49635a8eec185426b65ba66a4cefa822 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 26 Jun 2017 07:17:02 -0700 Subject: [PATCH 151/183] upgrade to VMP package 506854 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 7ae2adde21..4e72b9a51b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - e80a1e54cd419f96fed84f52f4803b0f + 949a1c69fd476dc76bd001318c8082fc url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6836/24610/viewer_manager-1.0.506825-darwin64-506825.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6865/24782/viewer_manager-1.0.506854-darwin64-506854.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 528d82bb5299c31f95a10af594f757d7 + 6ec8e5444c70ce3fede77bb113b0fb5d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6837/24616/viewer_manager-1.0.506825-windows-506825.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6866/24788/viewer_manager-1.0.506854-windows-506854.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506825 + 1.0.506854 vlc-bin From 263a9e7791f6b6c1ce15dc5c9505bc6b479d8d8b Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 26 Jun 2017 13:11:20 -0700 Subject: [PATCH 152/183] MAINT-7514: remove check if same version is installed --- .../installers/windows/installer_template.nsi | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 4dc4d05589..d82783a7ec 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -280,7 +280,6 @@ StrCpy $INSTEXE "${INSTEXE}" StrCpy $INSTSHORTCUT "${SHORTCUT}" Call CheckIfAdministrator # Make sure the user can install/uninstall -Call CheckIfAlreadyCurrent # Make sure this version is not already installed Call CloseSecondLife # Make sure Second Life not currently running Call CheckNetworkConnection # Ping secondlife.com Call CheckWillUninstallV2 # Check if Second Life is already installed @@ -331,7 +330,7 @@ FileClose $9 # Write registry WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR" -WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_REGISTRY}" +WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT" WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "Linden Research, Inc." @@ -340,7 +339,7 @@ WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninst WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "HelpLink" "https://support.secondlife.com/contact-support/" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG" WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"' -WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_REGISTRY}" +WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_LONG}" WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500" # ~117 MB # from FS:Ansariel @@ -451,23 +450,6 @@ lbl_is_admin: FunctionEnd -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Checks to see if the current version has already been installed (according to the registry). -;; If it has, allow user to bail out of install process. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -Function CheckIfAlreadyCurrent - Push $0 - ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" - StrCmp $0 ${VERSION_REGISTRY} 0 continue_install - StrCmp $SKIP_DIALOGS "true" continue_install - MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK continue_install - Quit -continue_install: - Pop $0 - Return - -FunctionEnd - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Function CheckWillUninstallV2 ;; From cc85030f7e5d2e218759179a134db0bc60e80615 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 27 Jun 2017 07:57:04 -0700 Subject: [PATCH 153/183] Try pointing icon path to actual viewer exe --- indra/newview/installers/windows/installer_template.nsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index d82783a7ec..69e7e06243 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -317,9 +317,9 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ # Other shortcuts SetOutPath "$INSTDIR" CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ '"$INSTDIR\uninst.exe"' '' From 3fd2ac14ea6dcbe2a8b6025dac37f6311c5cc319 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Tue, 27 Jun 2017 12:20:55 -0700 Subject: [PATCH 154/183] upgrade to VMP package 506923 --- autobuild.xml | 10 +++++----- .../installers/windows/installer_template.nsi | 2 +- .../newview/installers/windows/lang_en-us.nsi | Bin 9096 -> 8734 bytes 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 4e72b9a51b..df8ca73600 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 949a1c69fd476dc76bd001318c8082fc + e4fa9d067379b1800324f7764bb02a6c url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6865/24782/viewer_manager-1.0.506854-darwin64-506854.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6934/25239/viewer_manager-1.0.506923-darwin64-506923.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 6ec8e5444c70ce3fede77bb113b0fb5d + ff7e089d2e4b16a2a15b04b61d3e03e3 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6866/24788/viewer_manager-1.0.506854-windows-506854.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6935/25245/viewer_manager-1.0.506923-windows-506923.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506854 + 1.0.506923 vlc-bin diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 69e7e06243..1020702945 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -299,7 +299,7 @@ StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT" SetOutPath "$INSTDIR" CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \ - "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "%%SOURCE%%\icons\release\secondlife.ico" + "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE" WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \ diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index aa403a961cbdd0e39122c9273140346bb67a715f..00aa47de690a2a066ab023bccfe05a7559c3c938 100644 GIT binary patch delta 12 TcmeBhpXainMQHOo;aU6uBt!*O delta 180 zcmbQ|(&4_LMMyrAA&nuCA%~%eAr(lcFjO)mGn4{(AbuW0$>fhBvXc|IIru$+>YNcW zll4WlC$HmX6HR0&078)7B8FlH1%?ua42HzXAK7Im_sA Date: Tue, 27 Jun 2017 13:32:34 -0700 Subject: [PATCH 155/183] use icon in viewer exe for shortcut --- indra/newview/installers/windows/installer_template.nsi | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 69e7e06243..809f7367d7 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -277,6 +277,7 @@ SetShellVarContext all # Install for all users (if you change this, change it # Start with some default values. StrCpy $INSTPROG "${INSTNAME}" StrCpy $INSTEXE "${INSTEXE}" +StrCpy $VIEWER_EXE "${VIEWER_EXE}" StrCpy $INSTSHORTCUT "${SHORTCUT}" Call CheckIfAdministrator # Make sure the user can install/uninstall From ab1255c41615da872b47984f256625eacaf3f8ab Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 28 Jun 2017 10:50:52 -0400 Subject: [PATCH 156/183] DRTVWR-418: Bump TEXTURE_CACHE_VERSION and INDRA_OBJECT_CACHE_VERSION so the Alex Ivy viewer will reset caches. We have some evidence that the cache content is tied to ADDRESS_SIZE, so asking a 64-bit viewer to process 32-bit cache content is problematic. --- indra/newview/llappviewer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 686cad9255..5a0cdd4f1a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4079,7 +4079,7 @@ void dumpVFSCaches() U32 LLAppViewer::getTextureCacheVersion() { //viewer texture cache version, change if the texture cache format changes. - const U32 TEXTURE_CACHE_VERSION = 7; + const U32 TEXTURE_CACHE_VERSION = 8; return TEXTURE_CACHE_VERSION ; } @@ -4089,7 +4089,7 @@ U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 14; + const U32 INDRA_OBJECT_CACHE_VERSION = 15; return INDRA_OBJECT_CACHE_VERSION; } From 240239142b3a4ffbbf86f253db6462c4dc4ce8be Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Wed, 28 Jun 2017 14:11:01 -0700 Subject: [PATCH 157/183] upgrade to VMP package 506977 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index df8ca73600..6b753aaeae 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - e4fa9d067379b1800324f7764bb02a6c + 77c92cf55936daf788a56d60f59e2faf url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6934/25239/viewer_manager-1.0.506923-darwin64-506923.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6988/25592/viewer_manager-1.0.506977-darwin64-506977.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - ff7e089d2e4b16a2a15b04b61d3e03e3 + 271860ac11066d3037406a6c639ff8fe url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6935/25245/viewer_manager-1.0.506923-windows-506923.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6989/25598/viewer_manager-1.0.506977-windows-506977.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506923 + 1.0.506977 vlc-bin From b66032554691c382d3bb25403e8a18e7942cbe23 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 29 Jun 2017 08:00:21 -0700 Subject: [PATCH 158/183] upgrade to VMP package 507000 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 6b753aaeae..c30b289a2a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 77c92cf55936daf788a56d60f59e2faf + 425fc3c3ab386ba39a43e4648f917fc7 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6988/25592/viewer_manager-1.0.506977-darwin64-506977.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7011/25711/viewer_manager-1.0.507000-darwin64-507000.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 271860ac11066d3037406a6c639ff8fe + c448493f1afd7eb93160c4cb3fc9ef57 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6989/25598/viewer_manager-1.0.506977-windows-506977.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7012/25717/viewer_manager-1.0.507000-windows-507000.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.506977 + 1.0.507000 vlc-bin From a12ba6692429642de2ab3349c58c20b3ff59f2b6 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 30 Jun 2017 08:12:03 -0700 Subject: [PATCH 159/183] MAINT-7442: remove old skool check for updates --- indra/newview/skins/default/xui/de/menu_login.xml | 1 - indra/newview/skins/default/xui/de/menu_viewer.xml | 1 - indra/newview/skins/default/xui/en/floater_about.xml | 8 -------- indra/newview/skins/default/xui/en/menu_login.xml | 6 ------ indra/newview/skins/default/xui/en/menu_viewer.xml | 6 ------ indra/newview/skins/default/xui/es/menu_login.xml | 1 - indra/newview/skins/default/xui/es/menu_viewer.xml | 1 - indra/newview/skins/default/xui/fr/menu_login.xml | 1 - indra/newview/skins/default/xui/fr/menu_viewer.xml | 1 - indra/newview/skins/default/xui/it/menu_login.xml | 1 - indra/newview/skins/default/xui/it/menu_viewer.xml | 1 - indra/newview/skins/default/xui/ja/menu_login.xml | 1 - indra/newview/skins/default/xui/ja/menu_viewer.xml | 1 - indra/newview/skins/default/xui/pt/menu_login.xml | 1 - indra/newview/skins/default/xui/pt/menu_viewer.xml | 1 - indra/newview/skins/default/xui/ru/menu_login.xml | 1 - indra/newview/skins/default/xui/ru/menu_viewer.xml | 1 - indra/newview/skins/default/xui/tr/menu_login.xml | 1 - indra/newview/skins/default/xui/tr/menu_viewer.xml | 1 - indra/newview/skins/default/xui/zh/menu_login.xml | 1 - indra/newview/skins/default/xui/zh/menu_viewer.xml | 1 - 21 files changed, 38 deletions(-) diff --git a/indra/newview/skins/default/xui/de/menu_login.xml b/indra/newview/skins/default/xui/de/menu_login.xml index 69856c0852..9d4c49b05d 100644 --- a/indra/newview/skins/default/xui/de/menu_login.xml +++ b/indra/newview/skins/default/xui/de/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 2a8eaf26ec..c484f11590 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index ec87b3684e..60f36770bb 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -43,14 +43,6 @@ top_pad="5" height="25" width="180" /> - - - - - diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index 99aab42db8..805b24e290 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/fr/menu_login.xml b/indra/newview/skins/default/xui/fr/menu_login.xml index cbfdcdaf22..498196f602 100644 --- a/indra/newview/skins/default/xui/fr/menu_login.xml +++ b/indra/newview/skins/default/xui/fr/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 98a69aa043..451d45bedd 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml index 6dafc68f7c..cfb7941ad4 100644 --- a/indra/newview/skins/default/xui/it/menu_login.xml +++ b/indra/newview/skins/default/xui/it/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index 216af0e458..e010ec1591 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/ja/menu_login.xml b/indra/newview/skins/default/xui/ja/menu_login.xml index 1f31971078..d93395725b 100644 --- a/indra/newview/skins/default/xui/ja/menu_login.xml +++ b/indra/newview/skins/default/xui/ja/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index a8be8e7616..f2d989f17f 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml index 7b45eb1ad3..1001ede4e7 100644 --- a/indra/newview/skins/default/xui/pt/menu_login.xml +++ b/indra/newview/skins/default/xui/pt/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 542734eb22..f4a18cfc2c 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -183,7 +183,6 @@ - diff --git a/indra/newview/skins/default/xui/ru/menu_login.xml b/indra/newview/skins/default/xui/ru/menu_login.xml index 754803904a..8a086e5c16 100644 --- a/indra/newview/skins/default/xui/ru/menu_login.xml +++ b/indra/newview/skins/default/xui/ru/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/ru/menu_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml index e0d8861225..b92e266b8d 100644 --- a/indra/newview/skins/default/xui/ru/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml @@ -180,7 +180,6 @@ - diff --git a/indra/newview/skins/default/xui/tr/menu_login.xml b/indra/newview/skins/default/xui/tr/menu_login.xml index 145fc74508..1a810d58ce 100644 --- a/indra/newview/skins/default/xui/tr/menu_login.xml +++ b/indra/newview/skins/default/xui/tr/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/tr/menu_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml index ef001a8687..04b05ee2bb 100644 --- a/indra/newview/skins/default/xui/tr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml @@ -181,7 +181,6 @@ - diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml index e3f6ca2690..2cace27eca 100644 --- a/indra/newview/skins/default/xui/zh/menu_login.xml +++ b/indra/newview/skins/default/xui/zh/menu_login.xml @@ -16,7 +16,6 @@ - diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml index a58e1bb0fa..0388b891d6 100644 --- a/indra/newview/skins/default/xui/zh/menu_viewer.xml +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -181,7 +181,6 @@ - From 5fd1c47bb45f2fac68bfbd643ed3432ef3245573 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 30 Jun 2017 08:21:29 -0700 Subject: [PATCH 160/183] SL-671: uninstall pinning changes --- indra/newview/installers/windows/installer_template.nsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index aeb92eb15b..6fbbf1f1c6 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -404,6 +404,8 @@ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" # BUG-2707 Remove entry that disabled SEHOP DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE" +DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE" +DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" # Clean up shortcuts Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*" From 61f3366eecb98229ef27e3b9ab51cbefea2195a7 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 6 Jul 2017 11:53:03 -0700 Subject: [PATCH 161/183] upgrade to VMP package 507087 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index c30b289a2a..bf422af0b6 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 425fc3c3ab386ba39a43e4648f917fc7 + ec55e24d949ba07c7539410c062fdfa6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7011/25711/viewer_manager-1.0.507000-darwin64-507000.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7098/26128/viewer_manager-1.0.507087-darwin64-507087.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - c448493f1afd7eb93160c4cb3fc9ef57 + e6f9379345e44b7049c9e67758967676 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7012/25717/viewer_manager-1.0.507000-windows-507000.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7099/26138/viewer_manager-1.0.507087-windows-507087.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.507000 + 1.0.507087 vlc-bin From 42a8dbbd1629881089d77d23af4b32f2f5e1e658 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 6 Jul 2017 15:44:13 -0700 Subject: [PATCH 162/183] upgrade to VMP package 507104 --- autobuild.xml | 10 +-- indra/newview/llfeaturemanager.cpp | 99 ++++++++++++++++-------------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index bf422af0b6..70765abbe3 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - ec55e24d949ba07c7539410c062fdfa6 + 818d1703e73f9cc906ee3dd7824a82ac url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7098/26128/viewer_manager-1.0.507087-darwin64-507087.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7115/26245/viewer_manager-1.0.507104-darwin64-507104.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - e6f9379345e44b7049c9e67758967676 + 1c04406ed1b618b5debe384001e2144d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7099/26138/viewer_manager-1.0.507087-windows-507087.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7116/26251/viewer_manager-1.0.507104-windows-507104.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.507087 + 1.0.507104 vlc-bin diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ad048f6668..8aa4505e57 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -403,70 +403,79 @@ F32 gpu_benchmark(); bool LLFeatureManager::loadGPUClass() { - //get memory bandwidth from benchmark - F32 gbps = gpu_benchmark(); - - if (gbps < 0.f) - { //couldn't bench, use GLVersion -#if LL_DARWIN - //GLVersion is misleading on OSX, just default to class 3 if we can't bench + benchmark_flag = gSavedSettings.getBOOL("SkipBenchmark") + if (!benchmark_flag) + { + //get memory bandwidth from benchmark + F32 gbps = gpu_benchmark(); + + if (gbps < 0.f) + { //couldn't bench, use GLVersion + #if LL_DARWIN + //GLVersion is misleading on OSX, just default to class 3 if we can't bench LL_WARNS() << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; - mGPUClass = GPU_CLASS_3; -#else - if (gGLManager.mGLVersion < 2.f) + mGPUClass = GPU_CLASS_3; + #else + if (gGLManager.mGLVersion < 2.f) + { + mGPUClass = GPU_CLASS_0; + } + else if (gGLManager.mGLVersion < 3.f) + { + mGPUClass = GPU_CLASS_1; + } + else if (gGLManager.mGLVersion < 3.3f) + { + mGPUClass = GPU_CLASS_2; + } + else if (gGLManager.mGLVersion < 4.f) + { + mGPUClass = GPU_CLASS_3; + } + else + { + mGPUClass = GPU_CLASS_4; + } + #endif + } + else if (gGLManager.mGLVersion <= 2.f) { mGPUClass = GPU_CLASS_0; } - else if (gGLManager.mGLVersion < 3.f) + else if (gGLManager.mGLVersion <= 3.f) { mGPUClass = GPU_CLASS_1; } - else if (gGLManager.mGLVersion < 3.3f) + else if (gbps <= 5.f) + { + mGPUClass = GPU_CLASS_0; + } + else if (gbps <= 8.f) + { + mGPUClass = GPU_CLASS_1; + } + else if (gbps <= 16.f) { mGPUClass = GPU_CLASS_2; } - else if (gGLManager.mGLVersion < 4.f) + else if (gbps <= 40.f) { mGPUClass = GPU_CLASS_3; } - else + else if (gbps <= 80.f) { mGPUClass = GPU_CLASS_4; } -#endif - } - else if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) + else + { + mGPUClass = GPU_CLASS_5; + } + } //end if benchmark + else { + //setting says don't benchmark MAINT-7558 mGPUClass = GPU_CLASS_1; } - else if (gbps <= 5.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gbps <= 8.f) - { - mGPUClass = GPU_CLASS_1; - } - else if (gbps <= 16.f) - { - mGPUClass = GPU_CLASS_2; - } - else if (gbps <= 40.f) - { - mGPUClass = GPU_CLASS_3; - } - else if (gbps <= 80.f) - { - mGPUClass = GPU_CLASS_4; - } - else - { - mGPUClass = GPU_CLASS_5; - } // defaults mGPUString = gGLManager.getRawGLString(); From 5c1d9d65f65a1fadc00a0a81cf37d6389169b8c0 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Thu, 6 Jul 2017 16:09:44 -0700 Subject: [PATCH 163/183] fix missing declaration --- indra/newview/llfeaturemanager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 8aa4505e57..9c19bd582c 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -403,8 +403,7 @@ F32 gpu_benchmark(); bool LLFeatureManager::loadGPUClass() { - benchmark_flag = gSavedSettings.getBOOL("SkipBenchmark") - if (!benchmark_flag) + if (!gSavedSettings.getBOOL("SkipBenchmark")) { //get memory bandwidth from benchmark F32 gbps = gpu_benchmark(); From 510202a4e2e9f8c7f1c33b68c9623c917e14fc8b Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 7 Jul 2017 14:49:36 -0700 Subject: [PATCH 164/183] MAINT-7571: detect if all HD cards are bad and addr is forced to 64, then stay at 64 bit --- indra/newview/app_settings/cmd_line.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index a9f6079630..f20c0fb89c 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -81,6 +81,14 @@ map-to PacketDropPercentage + + forceaddresssize + + count + 1 + map-to + CmdLineForceAddrSize + god From b5d61b571996888d720fcf53e3597430ebf52823 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Fri, 7 Jul 2017 15:05:17 -0700 Subject: [PATCH 165/183] upgrade to VMP package 507135 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 70765abbe3..ae3b705164 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 818d1703e73f9cc906ee3dd7824a82ac + 2859976588023c257e8924bf8524dccd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7115/26245/viewer_manager-1.0.507104-darwin64-507104.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7146/26456/viewer_manager-1.0.507135-darwin64-507135.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 1c04406ed1b618b5debe384001e2144d + 988a1467275a8a42a15a392fe0bf49fd url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7116/26251/viewer_manager-1.0.507104-windows-507104.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7147/26471/viewer_manager-1.0.507135-windows-507135.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.507104 + 1.0.507135 vlc-bin From aaaf4cb4ec2d2211703db23c5d8a920ee0970a2a Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 10 Jul 2017 11:07:29 -0700 Subject: [PATCH 166/183] Remove FAS from cmd_line.xml --- indra/newview/app_settings/cmd_line.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index f20c0fb89c..e4e1cdcf44 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -82,14 +82,6 @@ PacketDropPercentage - forceaddresssize - - count - 1 - map-to - CmdLineForceAddrSize - - god desc From 98815fd99ac4709f8138a2a3a54a89fb149d7e37 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 10 Jul 2017 13:10:17 -0700 Subject: [PATCH 167/183] upgrade to VMP package 507165 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index ae3b705164..20da24d81b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 2859976588023c257e8924bf8524dccd + 86644959d0bf188162e5e08c731c0a1f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7146/26456/viewer_manager-1.0.507135-darwin64-507135.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7176/26636/viewer_manager-1.0.507165-darwin64-507165.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 988a1467275a8a42a15a392fe0bf49fd + 67ddd1cbc94a8cddcb0415edf1bd2c0d url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7147/26471/viewer_manager-1.0.507135-windows-507135.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7177/26642/viewer_manager-1.0.507165-windows-507165.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.507135 + 1.0.507165 vlc-bin From b0d8f3a1ab671668abb98fe1327f0fd73fca0fc7 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Mon, 10 Jul 2017 16:30:28 -0400 Subject: [PATCH 168/183] MAINT-4532: properly detect Windows 10 in the 64bit build (only - 32bit runs in Windows 8 compatibility mode) --- doc/contributions.txt | 1 + indra/CMakeLists.txt | 4 +- indra/llcommon/llsys.cpp | 387 ++++++++++----------------------- indra/newview/CMakeLists.txt | 9 + indra/newview/windows.manifest | 20 ++ 5 files changed, 149 insertions(+), 272 deletions(-) create mode 100644 indra/newview/windows.manifest diff --git a/doc/contributions.txt b/doc/contributions.txt index 79ff7161f6..5168bcd5fa 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -215,6 +215,7 @@ Ansariel Hiller MAINT-7028 MAINT-7059 MAINT-6519 + STORM-2105 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 39f8697e8c..a40b2c0846 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -3,8 +3,8 @@ # cmake_minimum_required should appear before any # other commands to guarantee full compatibility # with the version specified -## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly -cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR) +## prior to 3.4, the Windows manifest handling was missing +cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR) set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING "The root project/makefile/solution name. Defaults to SecondLife.") diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index fd1828b1cc..1ef6c538ba 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -61,6 +61,7 @@ using namespace llsd; #if LL_WINDOWS # include "llwin32headerslean.h" # include // GetPerformanceInfo() et al. +# include #elif LL_DARWIN # include # include @@ -110,78 +111,6 @@ static const F32 MEM_INFO_THROTTLE = 20; // dropped below the login framerate, we'd have very little additional data. static const F32 MEM_INFO_WINDOW = 10*60; -#if LL_WINDOWS -// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string -static const U32 WINNT_WINBLUE = 0x0603; - -#ifndef DLLVERSIONINFO -typedef struct _DllVersionInfo -{ - DWORD cbSize; - DWORD dwMajorVersion; - DWORD dwMinorVersion; - DWORD dwBuildNumber; - DWORD dwPlatformID; -}DLLVERSIONINFO; -#endif - -#ifndef DLLGETVERSIONPROC -typedef int (FAR WINAPI *DLLGETVERSIONPROC) (DLLVERSIONINFO *); -#endif - -bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number) -{ - bool result = false; - const U32 BUFF_SIZE = 32767; - WCHAR tempBuf[BUFF_SIZE]; - if(GetSystemDirectory((LPWSTR)&tempBuf, BUFF_SIZE)) - { - - std::basic_string shell32_path(tempBuf); - - // Shell32.dll contains the DLLGetVersion function. - // according to msdn its not part of the API - // so you have to go in and get it. - // http://msdn.microsoft.com/en-us/library/bb776404(VS.85).aspx - shell32_path += TEXT("\\shell32.dll"); - - HMODULE hDllInst = LoadLibrary(shell32_path.c_str()); //load the DLL - if(hDllInst) - { // Could successfully load the DLL - DLLGETVERSIONPROC pDllGetVersion; - /* - You must get this function explicitly because earlier versions of the DLL - don't implement this function. That makes the lack of implementation of the - function a version marker in itself. - */ - pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hDllInst, - "DllGetVersion"); - - if(pDllGetVersion) - { - // DLL supports version retrieval function - DLLVERSIONINFO dvi; - - ZeroMemory(&dvi, sizeof(dvi)); - dvi.cbSize = sizeof(dvi); - HRESULT hr = (*pDllGetVersion)(&dvi); - - if(SUCCEEDED(hr)) - { // Finally, the version is at our hands - major = dvi.dwMajorVersion; - minor = dvi.dwMinorVersion; - build_number = dvi.dwBuildNumber; - result = true; - } - } - - FreeLibrary(hDllInst); // Release DLL - } - } - return result; -} -#endif // LL_WINDOWS - // Wrap boost::regex_match() with a function that doesn't throw. template static bool regex_match_no_exc(const S& string, M& match, const R& regex) @@ -214,221 +143,139 @@ static bool regex_search_no_exc(const S& string, M& match, const R& regex) } } -#if LL_WINDOWS -// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case -static bool check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) -{ - OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; - DWORDLONG const dwlConditionMask = VerSetConditionMask( - VerSetConditionMask( - VerSetConditionMask( - 0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), - VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - - osvi.dwMajorVersion = wMajorVersion; - osvi.dwMinorVersion = wMinorVersion; - osvi.wServicePackMajor = wServicePackMajor; - - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; -} -#endif - LLOSInfo::LLOSInfo() : mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("") { #if LL_WINDOWS - OSVERSIONINFOEX osvi; - BOOL bOsVersionInfoEx; - BOOL bShouldUseShellVersion = false; + + if (IsWindowsVersionOrGreater(10, 0, 0)) + { + mMajorVer = 10; + mMinorVer = 0; + mOSStringSimple = "Microsoft Windows 10 "; + } + else if (IsWindows8Point1OrGreater()) + { + mMajorVer = 6; + mMinorVer = 3; + if (IsWindowsServer()) + { + mOSStringSimple = "Windows Server 2012 R2 "; + } + else + { + mOSStringSimple = "Microsoft Windows 8.1 "; + } + } + else if (IsWindows8OrGreater()) + { + mMajorVer = 6; + mMinorVer = 2; + if (IsWindowsServer()) + { + mOSStringSimple = "Windows Server 2012 "; + } + else + { + mOSStringSimple = "Microsoft Windows 8 "; + } + } + else if (IsWindows7SP1OrGreater()) + { + mMajorVer = 6; + mMinorVer = 1; + if (IsWindowsServer()) + { + mOSStringSimple = "Windows Server 2008 R2 SP1 "; + } + else + { + mOSStringSimple = "Microsoft Windows 7 SP1 "; + } + } + else if (IsWindows7OrGreater()) + { + mMajorVer = 6; + mMinorVer = 1; + if (IsWindowsServer()) + { + mOSStringSimple = "Windows Server 2008 R2 "; + } + else + { + mOSStringSimple = "Microsoft Windows 7 "; + } + } + else if (IsWindowsVistaSP2OrGreater()) + { + mMajorVer = 6; + mMinorVer = 0; + if (IsWindowsServer()) + { + mOSStringSimple = "Windows Server 2008 SP2 "; + } + else + { + mOSStringSimple = "Microsoft Windows Vista SP2 "; + } + } + else + { + mOSStringSimple = "Unsupported Windows version "; + } + + ///get native system info if available.. + typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo + SYSTEM_INFO si; //System Info object file contains architecture info + PGNSI pGNSI; //pointer object + ZeroMemory(&si, sizeof(SYSTEM_INFO)); //zero out the memory in information + pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function + if (NULL != pGNSI) //check if it has failed + pGNSI(&si); //success + else + GetSystemInfo(&si); //if it fails get regular system info + //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) + + //msdn microsoft finds 32 bit and 64 bit flavors this way.. + //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors + //of windows than this code does (in case it is needed for the future) + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) //check for 64 bit + { + mOSStringSimple += "64-bit "; + } + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) + { + mOSStringSimple += "32-bit "; + } // Try calling GetVersionEx using the OSVERSIONINFOEX structure. + OSVERSIONINFOEX osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) + if (GetVersionEx((OSVERSIONINFO *)&osvi)) + { + mBuild = osvi.dwBuildNumber & 0xffff; + } + else { // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); - if(!GetVersionEx( (OSVERSIONINFO *) &osvi)) - return; + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx((OSVERSIONINFO *)&osvi)) + { + mBuild = osvi.dwBuildNumber & 0xffff; + } } - mMajorVer = osvi.dwMajorVersion; - mMinorVer = osvi.dwMinorVersion; - mBuild = osvi.dwBuildNumber; - DWORD shell32_major, shell32_minor, shell32_build; - bool got_shell32_version = get_shell32_dll_version(shell32_major, - shell32_minor, - shell32_build); - - switch(osvi.dwPlatformId) + mOSString = mOSStringSimple; + if (mBuild > 0) { - case VER_PLATFORM_WIN32_NT: - { - // Test for the product. - if(osvi.dwMajorVersion <= 4) - { - mOSStringSimple = "Microsoft Windows NT "; - } - else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - { - mOSStringSimple = "Microsoft Windows 2000 "; - } - else if(osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1) - { - mOSStringSimple = "Microsoft Windows XP "; - } - else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) - { - if(osvi.wProductType == VER_NT_WORKSTATION) - mOSStringSimple = "Microsoft Windows XP x64 Edition "; - else - mOSStringSimple = "Microsoft Windows Server 2003 "; - } - else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 2) - { - if(osvi.dwMinorVersion == 0) - { - if(osvi.wProductType == VER_NT_WORKSTATION) - mOSStringSimple = "Microsoft Windows Vista "; - else - mOSStringSimple = "Windows Server 2008 "; - } - else if(osvi.dwMinorVersion == 1) - { - if(osvi.wProductType == VER_NT_WORKSTATION) - mOSStringSimple = "Microsoft Windows 7 "; - else - mOSStringSimple = "Windows Server 2008 R2 "; - } - else if(osvi.dwMinorVersion == 2) - { - if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0)) - { - mOSStringSimple = "Microsoft Windows 8.1 "; - bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version - } - else - { - if(osvi.wProductType == VER_NT_WORKSTATION) - mOSStringSimple = "Microsoft Windows 8 "; - else - mOSStringSimple = "Windows Server 2012 "; - } - } - - ///get native system info if available.. - typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo - SYSTEM_INFO si; //System Info object file contains architecture info - PGNSI pGNSI; //pointer object - ZeroMemory(&si, sizeof(SYSTEM_INFO)); //zero out the memory in information - pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function - if(NULL != pGNSI) //check if it has failed - pGNSI(&si); //success - else - GetSystemInfo(&si); //if it fails get regular system info - //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) - - //msdn microsoft finds 32 bit and 64 bit flavors this way.. - //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors - //of windows than this code does (in case it is needed for the future) - if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) //check for 64 bit - { - mOSStringSimple += "64-bit "; - } - else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) - { - mOSStringSimple += "32-bit "; - } - } - else // Use the registry on early versions of Windows NT. - { - mOSStringSimple = "Microsoft Windows (unrecognized) "; - - HKEY hKey; - WCHAR szProductType[80]; - DWORD dwBufLen; - RegOpenKeyEx( HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", - 0, KEY_QUERY_VALUE, &hKey ); - RegQueryValueEx( hKey, L"ProductType", NULL, NULL, - (LPBYTE) szProductType, &dwBufLen); - RegCloseKey( hKey ); - if ( lstrcmpi( L"WINNT", szProductType) == 0 ) - { - mOSStringSimple += "Professional "; - } - else if ( lstrcmpi( L"LANMANNT", szProductType) == 0 ) - { - mOSStringSimple += "Server "; - } - else if ( lstrcmpi( L"SERVERNT", szProductType) == 0 ) - { - mOSStringSimple += "Advanced Server "; - } - } - - std::string csdversion = utf16str_to_utf8str(osvi.szCSDVersion); - // Display version, service pack (if any), and build number. - std::string tmpstr; - if(osvi.dwMajorVersion <= 4) - { - tmpstr = llformat("version %d.%d %s (Build %d)", - osvi.dwMajorVersion, - osvi.dwMinorVersion, - csdversion.c_str(), - (osvi.dwBuildNumber & 0xffff)); - } - else - { - tmpstr = !bShouldUseShellVersion ? llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)): - llformat("%s (Build %d)", csdversion.c_str(), shell32_build); - } - - mOSString = mOSStringSimple + tmpstr; - } - break; - - case VER_PLATFORM_WIN32_WINDOWS: - // Test for the Windows 95 product family. - if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) - { - mOSStringSimple = "Microsoft Windows 95 "; - if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) - { - mOSStringSimple += "OSR2 "; - } - } - if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) - { - mOSStringSimple = "Microsoft Windows 98 "; - if ( osvi.szCSDVersion[1] == 'A' ) - { - mOSStringSimple += "SE "; - } - } - if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) - { - mOSStringSimple = "Microsoft Windows Millennium Edition "; - } - mOSString = mOSStringSimple; - break; + mOSString += llformat("(Build %d)", mBuild); } - std::string compatibility_mode; - if(got_shell32_version) - { - if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion) - { - compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)", - shell32_major, - shell32_minor, - shell32_build); - } - } - mOSString += compatibility_mode; + LLStringUtil::trim(mOSStringSimple); + LLStringUtil::trim(mOSString); #elif LL_DARWIN diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 266de7277d..f353109deb 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1561,6 +1561,15 @@ if (WINDOWS) if (INTEL_MEMOPS_LIBRARY) list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY}) endif (INTEL_MEMOPS_LIBRARY) + + if (ADDRESS_SIZE EQUAL 64) + # We deliberately omit this from the 32bit build because it declares that + # the viewer is compatible with Windows 10; we need that to properly detect + # the Windows version, but doing so causes systems with certain HD video + # cards to fail because Windows 10 does not support them. Leaving this out + # causes those systems to run in a Windows 8 compatibility mode, which works. + LIST(APPEND viewer_SOURCE_FILES windows.manifest) + endif (ADDRESS_SIZE EQUAL 64) endif (WINDOWS) # Add the xui files. This is handy for searching for xui elements diff --git a/indra/newview/windows.manifest b/indra/newview/windows.manifest new file mode 100644 index 0000000000..8321ac5337 --- /dev/null +++ b/indra/newview/windows.manifest @@ -0,0 +1,20 @@ + + + + + True/PM + + + + + + + + + + + + + + + From 6cb0881aff9eae5f3abb48d556d9a339f41848a7 Mon Sep 17 00:00:00 2001 From: Glenn Glazer Date: Mon, 10 Jul 2017 15:23:15 -0700 Subject: [PATCH 169/183] upgrade to VMP package 507182 --- autobuild.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 20da24d81b..7544408277 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3150,9 +3150,9 @@ archive hash - 86644959d0bf188162e5e08c731c0a1f + 83237f66d1406285b35a55e3f3691a9e url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7176/26636/viewer_manager-1.0.507165-darwin64-507165.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7193/26740/viewer_manager-1.0.507182-darwin64-507182.tar.bz2 name darwin64 @@ -3174,9 +3174,9 @@ archive hash - 67ddd1cbc94a8cddcb0415edf1bd2c0d + ce2aa248510bc233f3b0c35572641957 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7177/26642/viewer_manager-1.0.507165-windows-507165.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7194/26746/viewer_manager-1.0.507182-windows-507182.tar.bz2 name windows @@ -3187,7 +3187,7 @@ source_type hg version - 1.0.507165 + 1.0.507182 vlc-bin From d4974cdff93b774871395bcaf97753c0b348622a Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Tue, 11 Jul 2017 08:47:53 -0400 Subject: [PATCH 170/183] MAINT-7592: Update ToS agreement floater --- .../skins/default/xui/en/floater_tos.xml | 111 ++++++++++-------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index 612c894b59..9b97df1af3 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -15,6 +15,67 @@ name="loading_url"> data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E + + Please read the following Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the requirements for the use of arbitration and the waiver of any class or group claim to resolve disputes. To continue logging in to [SECOND_LIFE], you must accept these agreements. + + + You will need to go to https://my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you! + + + + the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements. +