Merge viewer64

master
Ansariel 2017-07-27 21:07:14 +02:00
commit e6f9a5e2db
78 changed files with 4821 additions and 5500 deletions

View File

@ -25,7 +25,6 @@ build-darwin-*
build-vc80/
build-vc100/
build-vc120/
build-vc120_x64/
build-vc120-32/
build-vc120-64/
indra/build-vc[0-9]*

View File

@ -329,11 +329,11 @@
<key>linux</key>
<map>
<key>archive</key>
' <map>
<map>
<key>hash</key>
<string>402552cf158e2fe953b7224f4615a957</string>
<string>1aa2e5355bb9df09f9196d14a72b6705</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/apr_3p-update-apr/rev/297252/arch/Linux/installer/apr_suite-1.4.5.297252-linux-297252.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-apr/rev/314241/arch/Linux/installer/apr_suite-1.4.5.314241-linux-314241.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -468,6 +468,36 @@
<key>version</key>
<string>1.57</string>
</map>
<key>chardet</key>
<map>
<key>copyright</key>
<string>Contributors to charset (see https://github.com/chardet/chardet)</string>
<key>description</key>
<string>Python Character Encoding Library</string>
<key>license</key>
<string>LGPL</string>
<key>license_file</key>
<string>LICENSES/chardet.txt</string>
<key>name</key>
<string>chardet</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>0124862b6a1b88455c78a68f8b823d21</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
</map>
<key>version</key>
<string>3.0.4</string>
</map>
<key>colladadom</key>
<map>
<key>copyright</key>
@ -587,9 +617,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>99fbc15f514be77c36280f300d257d5a</string>
<string>8854daffb8b87a2238461a7f72e4b4fd</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1077/2495/curl-7.47.0.501064-darwin64-501064.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6822/24534/curl-7.54.1.506810-darwin64-506810.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -599,9 +629,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f49d4ed203b03852a3f6b01b18319f7a</string>
<string>9430c08954c00736117099046694e1b1</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-curl/rev/312763/arch/Linux/installer/curl-7.47.0.312763-linux-312763.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-curl/rev/314230/arch/Linux/installer/curl-7.47.0.314230-linux-314230.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -611,9 +641,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>5b164c2b1cfc1270a60c3b4ad8dd9cd1</string>
<string>37a6a2615d81b491e449e5680cf8d9c7</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/curl-7.47.0.201604192059-linux64-201604192059.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6821/24528/curl-7.54.1.506810-linux64-506810.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -623,11 +653,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>bda9f237d3e8238440bc5bedc2657547</string>
<string>eb2508dd444ac885b7fdf7d89cd2e010</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1078/2487/curl-7.47.0.501064-windows-501064.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6823/24516/curl-7.54.1.506810-windows-506810.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -637,16 +667,16 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f7fa42c7157cd5007283ae7a5d97393d</string>
<string>1a9848d3b1ed53e57afe44f175c2ecea</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1079/2490/curl-7.47.0.501064-windows64-501064.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6824/24522/curl-7.54.1.506810-windows64-506810.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>7.47.0.501064</string>
<string>7.54.1.506810</string>
</map>
<key>db</key>
<map>
@ -697,9 +727,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c11ff7e2e0bd59e6e59628f24902bbcd</string>
<string>6d676abd9ad8d2883b855dbe397d9034</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/dbus-glib_3p-update-dbus-glib/rev/297768/arch/Linux/installer/dbus_glib-0.76-linux-297768.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux-314266.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -895,9 +925,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f546615d76bc0f9e8bc2b9ef89f0ca86</string>
<string>387c90b9bb5ec412587fbe7a56261dd1</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/expat_3p-update-expat/rev/297014/arch/Linux/installer/expat-2.0.1.297014-linux-297014.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-expat/rev/314211/arch/Linux/installer/expat-2.1.1.314211-linux-314211.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -907,9 +937,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>da531d07c19cb09c1a7e5d9b3a8c8c1d</string>
<string>5e1f025d1cebd12db542080aa755257f</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/expat-2.0.1.201505150200-r31-linux-x64-201505150200-r31.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/380/943/expat-2.1.1.500375-linux64-500375.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -1049,9 +1079,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>864f9361661748ecf0e2cec7110d70b3</string>
<string>a20a3d0ab7fc3401bc2ca81e9309f630</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/fontconfig_3p-update-fontconfig/rev/297551/arch/Linux/installer/fontconfig-2.11.0-linux-297551.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux-314281.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1061,9 +1091,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>15b2955b9b66926e52f48e929bf5e332</string>
<string>e2419d56960c160670051fbb055fb729</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/fontconfig-2.11.0-linux-x64-201505150243-r22.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux64-314281.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -1115,9 +1145,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>1ac3152b440287c58509d8af0a50326d</string>
<string>1b401394106cedc86926bd488f5aa45e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/freetype_3p-update-freetype/rev/297053/arch/Linux/installer/freetype-2.4.4.297053-linux-297053.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-freetype/rev/314215/arch/Linux/installer/freetype-2.4.4.314215-linux-314215.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1181,9 +1211,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>4bf4f9e65168138eebbc769e9e12230b</string>
<string>baf1fd13e1fe6aef586200fc87a70f53</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/glext_3p-update-glext/rev/296893/arch/Linux/installer/glext-68-linux-296893.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-glext/rev/314200/arch/Linux/installer/glext-68-linux-314200.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1397,9 +1427,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>e294e6ca721e271b4bae8046cfbc3c9b</string>
<string>352e673897e8f36f8470150b8ace6ce9</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/google-breakpad_3p-update-google-breakpad/rev/298127/arch/Linux/installer/google_breakpad-1413.298127-linux-298127.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-google-breakpad/rev/314225/arch/Linux/installer/google_breakpad-1413.314225-linux-314225.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1551,9 +1581,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>fb1479533a7699b44d34e3a550037eb7</string>
<string>5017b3e95d2c6f47bb111c3f9c075522</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/gstreamer_3p-update-gstreamer/rev/294903/arch/Linux/installer/gstreamer-0.10.6.294903-linux-294903.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux-314267.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1704,6 +1734,36 @@
<key>version</key>
<string>2012.1-2</string>
</map>
<key>idna</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2013-2017, Kim Davies. All rights reserved.</string>
<key>description</key>
<string>Python Internationalized Domain Names in Applications (IDNA) Library</string>
<key>license</key>
<string>see idna.rst</string>
<key>license_file</key>
<string>LICENSES/idna.rst</string>
<key>name</key>
<string>idna</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>7dfe9fc4023d7d4f511dd9fac7258266</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
</map>
<key>version</key>
<string>2.5</string>
</map>
<key>jpeglib</key>
<map>
<key>copyright</key>
@ -1747,9 +1807,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>0a6641f030e173a7bc0dc8a3087b6c7d</string>
<string>32560d3200da72fea2922371fcef25f5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jpeglib_3p-update-jpeglib/rev/296854/arch/Linux/installer/jpeglib-8c.296854-linux-296854.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jpeglib/rev/314202/arch/Linux/installer/jpeglib-8c.314202-linux-314202.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1837,9 +1897,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>910bf12e4b4635170e462b739887cda9</string>
<string>9d5d9fec28cbbb1651b95728173f8af7</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/jsoncpp_3p-update-jsoncpp/rev/297580/arch/Linux/installer/jsoncpp-0.5.0.297580-linux-297580.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-jsoncpp/rev/314229/arch/Linux/installer/jsoncpp-0.5.0.314229-linux-314229.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2017,9 +2077,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>988deae5c63ec638ad222b400a431f5b</string>
<string>0d8009c3b6c1eb510593476dd1d821b5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/hunspell_3p-update-hunspell/rev/296916/arch/Linux/installer/libhunspell-1.3.2.296916-linux-296916.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-hunspell/rev/314217/arch/Linux/installer/libhunspell-1.3.2.314217-linux-314217.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2173,9 +2233,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>744e22c5fcaaf3483a60e29f217daa9c</string>
<string>0758f3cb4c02ebab61854b811b0894e9</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libpng_3p-update-libpng/rev/301387/arch/Linux/installer/libpng-1.6.8.301387-linux-301387.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libpng/rev/314214/arch/Linux/installer/libpng-1.6.8.314214-linux-314214.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2239,9 +2299,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>f231b6ec8bc2f050cfb1ee20bd83190d</string>
<string>a2eaf9515cd129f3e21a08e92689006b</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libuuid_3p-update-libuuid/rev/295209/arch/Linux/installer/libuuid-1.6.2-linux-295209.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux-314269.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2305,9 +2365,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b8b584853dc1344bb3571c13b06ec39e</string>
<string>6954173a141d928f2614076577d952de</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/libxml_3p-update-libxml/rev/297050/arch/Linux/installer/libxml2-2.9.1.297050-linux-297050.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libxml/rev/314197/arch/Linux/installer/libxml2-2.9.1.314197-linux-314197.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2382,6 +2442,46 @@
<key>version</key>
<string>0.0.1</string>
</map>
<key>llbase</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2010, Linden Research, Inc.</string>
<key>license</key>
<string>mit</string>
<key>license_file</key>
<string>LICENSES/llbase-license.txt</string>
<key>name</key>
<string>llbase</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>e18eeb0691af053b83bd46b76c6ee86a</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>e6865670f9bca1c82fb8b91db3ea515c</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>version</key>
<string>0.9.3.506286</string>
</map>
<key>llphysicsextensions_source</key>
<map>
<key>copyright</key>
@ -2597,9 +2697,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b0cd31d5b07a9fc25c4d69ba2f95eace</string>
<string>5c9d94dce4551b19790057766ff939ea</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/oggvorbis_3p-update-oggvorbis/rev/296878/arch/Linux/installer/ogg_vorbis-1.2.2-1.3.2.296878-linux-296878.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-oggvorbis/rev/314224/arch/Linux/installer/ogg_vorbis-1.2.2-1.3.2.314224-linux-314224.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2705,11 +2805,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>15ebe611213c9577691ffbade081549d</string>
<string>24b91eda3831a51c7774644016c4cb09</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openal_3p-update-openal/rev/297677/arch/Linux/installer/openal-1.12.854-1.1.0.297677-linux-297677.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openal/rev/314223/arch/Linux/installer/openal-1.12.854-1.1.0.314223-linux-314223.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2799,9 +2899,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>675c283030879d3d9c49082bfa2192eb</string>
<string>e82317482647559d46a818ba48e9423a</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openjpeg_3p-update-openjpeg/rev/297018/arch/Linux/installer/openjpeg-1.4.297018-linux-297018.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openjpeg/rev/314205/arch/Linux/installer/openjpeg-2.0.0.314205-linux-314205.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2889,9 +2989,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c310ba9971cbd796b303c3be67fb11c6</string>
<string>f46a601d60b7dbcfde32afc0cb64453e</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/openssl_3p-update-openssl/rev/297168/arch/Linux/installer/openssl-1.0.1h.297168-linux-297168.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-openssl/rev/314227/arch/Linux/installer/openssl-1.0.1h.314227-linux-314227.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2979,9 +3079,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>b82817bcc2f63094d9c915d018d0b036</string>
<string>24a119b18e63017ad932ad54df8161bc</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/pcre_3p-update-pcre/rev/297155/arch/Linux/installer/pcre-8.35.-linux-297155.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-pcre/rev/314136/arch/Linux/installer/pcre-8.35.314136-linux-314136.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -2991,9 +3091,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>316f14bec0578c39a6674938853afc88</string>
<string>0f058ca2176e7d02d51e54c66a96f336</string>
<key>url</key>
<string>http://downloads.phoenixviewer.com/pcre-8.35.-linux-x64-201505150212-r52.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/908/2010/pcre-8.35.500898-linux64-500898.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
@ -3008,7 +3108,7 @@
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/911/2021/pcre-8.35.500898-windows-500898.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
<string>windows</string>
</map>
<key>windows64</key>
<map>
@ -3026,6 +3126,52 @@
<key>version</key>
<string>8.35.500898</string>
</map>
<key>requests</key>
<map>
<key>copyright</key>
<string>Copyright 2016 Kenneth Reitz</string>
<key>description</key>
<string>Python HTTP Library</string>
<key>license</key>
<string>Apache</string>
<key>license_file</key>
<string>LICENSES/requests.txt</string>
<key>name</key>
<string>requests</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>b8d134a970261b445a3f376ba4e05ff7</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>linux64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>a92f2235991871c3d601a73cfef9b2af</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4105/11530/requests-1.0-linux64-504094.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>
</map>
</map>
<key>source</key>
<string>https://bitbucket.org/lindenlab/p64_python-requests</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>2.18.1</string>
</map>
<key>slvoice</key>
<map>
<key>copyright</key>
@ -3236,6 +3382,94 @@
<key>version</key>
<string>0.8.0.1</string>
</map>
<key>urllib3</key>
<map>
<key>copyright</key>
<string>Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt)</string>
<key>description</key>
<string>Python HTTP Library</string>
<key>license</key>
<string>MIT</string>
<key>license_file</key>
<string>LICENSES/urllib3.txt</string>
<key>name</key>
<string>urllib3</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>22f64c7fbb6704d2e9519fd1cca8e49b</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
</map>
<key>version</key>
<string>1.21.1</string>
</map>
<key>viewer-manager</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
<key>description</key>
<string>Linden Lab Viewer Management Process suite.</string>
<key>license</key>
<string>Proprietary</string>
<key>license_file</key>
<string>LICENSE</string>
<key>name</key>
<string>viewer-manager</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>01b463520b0f253842335428901404ae</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7371/27810/viewer_manager-1.0.507360-darwin64-507360.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>linux</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>8c7f32f85850248809ae811ba8e47d81</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/3428/8686/viewer_manager-1.0-linux-503417.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>2f8626ce0448d56ecfd07e51affadcfd</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/7372/27832/viewer_manager-1.0.507360-windows-507360.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
<key>source</key>
<string>https://bitbucket.org/lindenlab/vmp-standalone</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>1.0.507360</string>
</map>
<key>vlc-bin</key>
<map>
<key>copyright</key>
@ -3355,9 +3589,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>30bb26d6cc78c16047fc85a63f48fcdb</string>
<string>b63f828e798287d475991134cdcfbca3</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/xmlrpc-emi_3p-update-xmlrpc-epi/rev/297075/arch/Linux/installer/xmlrpc_epi-0.54.1.297075-linux-297075.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-xmlrpc-epi/rev/314240/arch/Linux/installer/xmlrpc_epi-0.54.1.314240-linux-314240.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -3445,11 +3679,11 @@
<key>archive</key>
<map>
<key>hash</key>
<string>2eb8e59b6464222dcf4435016ad5f618</string>
<string>98a8c775c581ca80bb559e8b4e8eaae7</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/zlib_3p-update-zlib/rev/296881/arch/Linux/installer/zlib-1.2.8.296881-linux-296881.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-zlib/rev/314131/arch/Linux/installer/zlib-1.2.8.314131-linux-314131.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -3971,7 +4205,6 @@
<key>options</key>
<array>
<string>-G</string>
<string>'Unix Makefiles'</string>
</array>
</map>
<!--

View File

@ -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"

View File

@ -218,6 +218,7 @@ Ansariel Hiller
MAINT-7028
MAINT-7059
MAINT-6519
STORM-2105
Aralara Rajal
Arare Chantilly
CHUIBUG-191

View File

@ -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)
# [FS:CR] Shut up Cmake 2.8.12+ by using the old policy.
if(${CMAKE_VERSION} VERSION_GREATER 2.8.12 OR ${CMAKE_VERSION} VERSION_EQUAL 2.8.12)
@ -102,7 +102,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)
@ -114,9 +114,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)

View File

@ -107,23 +107,7 @@ endif (WINDOWS)
if (LINUX)
set(CMAKE_SKIP_RPATH TRUE)
# <FS:ND/>
# And another hack for FORTIFY_SOURCE. Some distributions (for example Gentoo) define FORTIFY_SOURCE by default.
# Check if this is the case, if yes, do not define it again.
execute_process(
COMMAND echo "int main( char **a, int c ){ \n#ifdef _FORTIFY_SOURCE\n#error FORTITY_SOURCE_SET\n#else\nreturn 0;\n#endif\n}"
COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -xc++ -w - -o /dev/null"
OUTPUT_VARIABLE FORTIFY_SOURCE_OUT
ERROR_VARIABLE FORTIFY_SOURCE_ERR
RESULT_VARIABLE FORTIFY_SOURCE_RES
)
if ( ${FORTIFY_SOURCE_RES} EQUAL 0 )
add_definitions(-D_FORTIFY_SOURCE=2)
endif()
add_definitions(-D_FORTIFY_SOURCE=2)
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
# gcc 4.3 and above don't like the LL boost and also

View File

@ -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
@ -159,7 +158,6 @@ elseif(DARWIN)
set(vivox_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(vivox_files
SLVoice
ca-bundle.crt
libsndfile.dylib
libvivoxoal.dylib
libortp.dylib

View File

@ -10,7 +10,7 @@ find_path(HUNSPELL_INCLUDE_DIR hunspell.h
PATH_SUFFIXES hunspell
)
set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell)
set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3 libhunspell)
find_library(HUNSPELL_LIBRARY
NAMES ${HUNSPELL_NAMES}
)

4
indra/cmake/LLBase.cmake Normal file
View File

@ -0,0 +1,4 @@
# -*- cmake -*-
include(Prebuilt)
use_prebuilt_binary(llbase)

View File

@ -39,7 +39,7 @@ macro (use_prebuilt_binary _binary)
if(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0)
if(DEBUG_PREBUILT)
message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
--install-dir=${AUTOBUILD_INSTALL_DIR}
${_binary} ")
endif(DEBUG_PREBUILT)

View File

@ -0,0 +1,7 @@
if (DARWIN)
include (Prebuilt)
use_prebuilt_binary(requests)
use_prebuilt_binary(urllib3)
use_prebuilt_binary(chardet)
use_prebuilt_binary(idna)
endif (DARWIN)

View File

@ -0,0 +1,3 @@
include (Prebuilt)
use_prebuilt_binary(viewer-manager)

View File

@ -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

View File

@ -65,6 +65,31 @@
#define LLINSTANCETRACKER_DTOR_NOEXCEPT
#endif
// As of 2017-05-06, as far as nat knows, only clang supports __has_feature().
// Unfortunately VS2013's preprocessor shortcut logic doesn't prevent it from
// producing (fatal) warnings for defined(__clang__) && __has_feature(...).
// Have to work around that.
#if ! defined(__clang__)
#define __has_feature(x) 0
#endif // __clang__
#if defined(LL_TEST_llinstancetracker) && __has_feature(cxx_noexcept)
// ~LLInstanceTracker() performs llassert_always() validation. That's fine in
// production code, since the llassert_always() is implemented as an LL_ERRS
// message, which will crash-with-message. In our integration test executable,
// though, this llassert_always() throws an exception instead so we can test
// error conditions and continue running the test. However -- as of C++11,
// destructors are implicitly noexcept(true). Unless we mark
// ~LLInstanceTracker() noexcept(false), the test executable crashes even on
// the ATTEMPT to throw.
#define LLINSTANCETRACKER_DTOR_NOEXCEPT noexcept(false)
#else
// If we're building for production, or in fact building *any other* test, or
// we're using a compiler that doesn't support __has_feature(), or we're not
// compiling with a C++ version that supports noexcept -- don't specify it.
#define LLINSTANCETRACKER_DTOR_NOEXCEPT
#endif
/**
* Base class manages "class-static" data that must actually have singleton
* semantics: one instance per process, rather than one instance per module as

View File

@ -788,7 +788,6 @@ void LLWindowWin32::close()
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
// Don't process events in our mainWindowProc any longer.
// SetWindowLong(mWindowHandle, GWL_USERDATA, NULL);
SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL);
// Make sure we don't leave a blank toolbar button.

View File

@ -23,4 +23,3 @@ endif (WINDOWS)
if (WINDOWS OR LINUX)
add_subdirectory(gstreamer10)
endif (WINDOWS OR LINUX)

View File

@ -759,14 +759,12 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
uint32_t native_scan_code = (uint32_t)(native_key_data["sdl_sym"].asInteger());
uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
uint32_t native_modifiers = (uint32_t)(native_key_data["cef_modifiers"].asInteger());
if( native_scan_code == '\n' )
native_scan_code = '\r';
mCEFLib->nativeKeyboardEvent(key_event, native_scan_code, native_virtual_key, native_modifiers);
#endif
// </FS:ND>
}
void MediaPluginCEF::unicodeInput(LLSD native_key_data = LLSD::emptyMap())
{
#if LL_DARWIN

View File

@ -16,6 +16,7 @@ include(GLOD)
include(Hunspell)
include(JsonCpp)
include(LLAppearance)
include(LLBase)
include(LLAudio)
include(LLCharacter)
include(LLCommon)
@ -42,10 +43,12 @@ include(OPENAL)
include(OpenGL)
include(OpenSSL)
include(PNG)
include(Requests)
include(TemplateCheck)
include(UI)
include(UnixInstall)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
include(WinManifest)
include(URIPARSER)
@ -91,7 +94,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}
@ -1609,7 +1611,7 @@ list(APPEND viewer_HEADER_FILES ${CMAKE_CURRENT_BINARY_DIR}/fsversionvalues.h)
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")
@ -1886,6 +1888,15 @@ if (WINDOWS)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG")
endif ( )
# </FS:Ansariel>
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
@ -2282,7 +2293,6 @@ endif (WINDOWS)
target_link_libraries(${VIEWER_BINARY_NAME}
${URIPARSER_PRELOAD_ARCHIVES}
${UPDATER_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
${LLAUDIO_LIBRARIES}
${LLCHARACTER_LIBRARIES}
@ -2427,6 +2437,8 @@ endif (LINUX)
if (DARWIN)
# These all get set with PROPERTIES
set(product "Firestorm")
# 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 "Firestorm Viewer")
set(MACOSX_BUNDLE_ICON_FILE "firestorm_icon.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.phoenixviewer.firestorm.viewer-${ND_VIEWER_FLAVOR}")
@ -2470,6 +2482,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}

View File

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>

View File

@ -81,7 +81,7 @@
<key>map-to</key>
<string>PacketDropPercentage</string>
</map>
<key>god</key>
<map>
<key>desc</key>

View File

@ -8700,19 +8700,6 @@
<key>Backup</key>
<integer>0</integer>
</map>
<key>MemProfiling</key>
<map>
<key>Comment</key>
<string>You want to use tcmalloc's memory profiling options.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>MenuAccessKeyTime</key>
<map>
<key>Comment</key>
@ -12732,30 +12719,30 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Backup</key>
<integer>0</integer>
</map>
<key>RenderUseFarClip</key>
<map>
<key>Comment</key>
<string>If false, frustum culling will ignore far clip plane.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<key>RenderUseFarClip</key>
<map>
<key>Comment</key>
<string>If false, frustum culling will ignore far clip plane.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
<key>Backup</key>
<integer>0</integer>
</map>
<key>RenderUseImpostors</key>
<map>
<key>Comment</key>
</map>
<key>RenderUseImpostors</key>
<map>
<key>Comment</key>
<string>OBSOLETE and UNUSED. See RenderAvatarMaxNonImpostors and RenderAvatarMaxComplexity.</string>
<key>Persist</key>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
</map>
<key>RenderAutoMuteByteLimit</key>
<map>
<key>Comment</key>
@ -20940,6 +20927,18 @@ Change of this parameter will affect the layout of buttons in notification toast
<string>U32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>SkipBenchmark</key>
<map>
<key>Comment</key>
<string>if true, disables running the GPU benchmark at startup
(default to class 1)</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<key>Backup</key>
<integer>0</integer>
</map>

3899
indra/newview/ca-bundle.crt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -94,10 +94,12 @@ SetOverwrite on # Overwrite files by default
# <FS:Ansariel> Don't auto-close so we can check details
#AutoCloseWindow true # After all files install, close window
;;InstallDir "$PROGRAMFILES\${INSTNAME}"
;;InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\${INSTNAME}" ""
# initial location of install (default when not already installed)
# note: Now we defer looking for existing install until onInit when we
# are able to engage the 32/64 registry function
InstallDir "%%PROGRAMFILES%%\${INSTNAME}"
InstallDirRegKey HKEY_LOCAL_MACHINE "%%INSTALL_DIR_REGKEY%%" ""
UninstallText $(UninstallTextMsg)
DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
@ -113,6 +115,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
@ -311,10 +314,10 @@ 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
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
@ -338,7 +341,7 @@ StrCmp $NO_STARTMENU "true" label_skip_start_menu
CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT"
SetOutPath "$INSTDIR"
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
@ -360,15 +363,15 @@ label_skip_start_menu:
# Other shortcuts
SetOutPath "$INSTDIR"
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
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
@ -407,6 +410,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" ""
# <FS:CR> Register hop:// protocol registry info
WriteRegStr HKEY_CLASSES_ROOT "hop" "(default)" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "hop" "URL Protocol" ""
@ -451,6 +458,8 @@ DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPRO
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\*.*"
@ -498,23 +507,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\The Phoenix Firestorm Project\$INSTPROG" "Version"
StrCmp $0 ${VERSION_LONG} 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
;;
@ -783,7 +775,7 @@ FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInstSuccess
Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch.
Push $R0 # Option value, unused
Push $R0 # Option value, unused#
# <FS:PP> Disable autorun
# StrCmp $SKIP_AUTORUN "true" +2;
# Assumes SetOutPath $INSTDIR
@ -804,11 +796,10 @@ label_ask_launch:
label_launch:
# Assumes SetOutPath $INSTDIR
Exec '"$WINDIR\explorer.exe" "$INSTDIR\autorun.bat"'
Exec '"$WINDIR\explorer.exe" "$INSTDIR\autorun.bat"'
label_no_launch:
Pop $R0
Pop $R0
# </FS:PP>
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -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 <christianbiere@gmx.de>
* 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, <daniel@haxx.se>.
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 <to_serge@users.sourceforge.net>
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

View File

@ -101,7 +101,6 @@
// [/RLVa:KB]
#include "llweb.h"
#include "llupdaterservice.h"
// <FS:Ansariel> [FS communication UI]
#include "fsfloatervoicecontrols.h"
// </FS:Ansariel> [FS communication UI]
@ -298,14 +297,6 @@ static LLAppViewerListener sAppViewerListener(LLAppViewer::instance);
// viewer.cpp - these are only used in viewer, should be easily moved.
#if LL_DARWIN
// <FS:CR>
//const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
#ifdef OPENSIM
const char * const LL_VERSION_BUNDLE_ID = "com.phoenixviewer.firestorm.viewer-oss";
#else // !OPENSIM
const char * const LL_VERSION_BUNDLE_ID = "com.phoenixviewer.firestorm.viewer-hvk";
#endif // OPENSIM
// </FS:CR>
extern void init_apple_menu(const char* product);
#endif // LL_DARWIN
@ -331,9 +322,7 @@ 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
else
# error "Unknown Platform"
#endif
const char* gPlatform = LL_PLATFORM_KEY;
@ -537,8 +526,6 @@ struct SettingsFiles : public LLInitParam::Block<SettingsFiles>
};
LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
//----------------------------------------------------------------------------
// Metrics logging control constants
//----------------------------------------------------------------------------
@ -777,7 +764,6 @@ LLAppViewer::LLAppViewer()
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mUpdater(new LLUpdaterService()),
mSettingsLocationList(NULL),
mIsFirstRun(false),
mSaveSettingsOnExit(true), // <FS:Zi> Backup Settings
@ -819,7 +805,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());
}
@ -1062,14 +1047,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;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@ -3480,229 +3457,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<char> 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,
// DRTVWR-418 transitional: query using "win64" until VMP is in place
#if LL_WINDOWS && (ADDRESS_SIZE == 64)
"win64",
#else
gPlatform,
#endif
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", &notify_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.
@ -5105,7 +4859,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 ;
}
@ -5115,7 +4869,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;
}
@ -6715,142 +6469,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("phoenixviewer.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<std::string> 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)
{

View File

@ -55,7 +55,6 @@ class LLTextureCache;
class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLUpdaterService;
class LLViewerJoystick;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
@ -239,7 +238,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() ;
@ -329,38 +327,22 @@ private:
LLAllocator mAlloc;
LLFrameTimer mMemCheckTimer;
boost::scoped_ptr<LLUpdaterService> mUpdater;
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
bool mIsFirstRun;
//---------------------------------------------
//*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();
//---------------------------------------------
bool mIsFirstRun;
// <FS:Zi> Backup Settings
public:
void setSaveSettingsOnExit(bool state) {mSaveSettingsOnExit = state; };
private:
bool mSaveSettingsOnExit;
// </FS:Zi>
// <FS:ND> For Windows, purging the cache can take an extraordinary amount of time. Rename the cache dir and purge it using another thread.
private:
// <FS:ND> For Windows, purging the cache can take an extraordinary amount of time. Rename the cache dir and purge it using another thread.
virtual void startCachePurge() {}
// </FS:ND>
};
// consts from viewer.h

View File

@ -435,17 +435,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)
{

View File

@ -35,13 +35,13 @@
#include "llwaterparammanager.h"
#include "llwlhandlers.h"
#include "llwlparammanager.h"
#include "lltrans.h"
// [RLVa:KB] - Checked: 2011-09-04 (RLVa-1.4.1a) | Added: RLVa-1.4.1a
#include <boost/algorithm/string.hpp>
#include "rlvhandler.h"
// [/RLVa:KB]
#include "kcwlinterface.h"
#include "quickprefs.h"
#include "lltrans.h"
std::string LLWLParamKey::toString() const
{

View File

@ -408,7 +408,9 @@ F32 gpu_benchmark();
bool LLFeatureManager::loadGPUClass()
{
//get memory bandwidth from benchmark
if (!gSavedSettings.getBOOL("SkipBenchmark"))
{
//get memory bandwidth from benchmark
// <FS:ND> Allow to skip gpu_benchmark with -noprobe.
// This can make sense for some Intel GPUs which can take 15+ Minutes or crash during gpu_benchmark
@ -419,68 +421,76 @@ bool LLFeatureManager::loadGPUClass()
gbps = gpu_benchmark();
// </FS:ND>
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)
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("RenderInit") << "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_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
LL_WARNS("RenderInit") << "Setting 'SkipBenchmark' is true; defaulting to class 1 (may be required for some GPUs)" << LL_ENDL;
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();
@ -624,7 +634,7 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
if(ctrl == NULL)
{
LL_WARNS() << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
continue;
}
@ -647,7 +657,7 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
}
else
{
LL_WARNS() << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
}
}
}
@ -854,7 +864,7 @@ LLSD LLFeatureManager::getRecommendedSettingsMap()
LLControlVariable* ctrl = gSavedSettings.getControl(mIt->first);
if (ctrl == NULL)
{
LL_WARNS() << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
LL_WARNS("RenderInit") << "AHHH! Control setting " << mIt->first << " does not exist!" << LL_ENDL;
continue;
}
@ -872,7 +882,7 @@ LLSD LLFeatureManager::getRecommendedSettingsMap()
}
else
{
LL_WARNS() << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
LL_WARNS("RenderInit") << "AHHH! Control variable is not a numeric type!" << LL_ENDL;
continue;
}
map[mIt->first]["Comment"] = ctrl->getComment();;

View File

@ -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"
@ -63,6 +62,7 @@
#include "llsdutil_math.h"
#include "lleventapi.h"
#include "llcorehttputil.h"
#include "lldir.h"
#if LL_WINDOWS
#include "lldxhardware.h"
@ -90,10 +90,7 @@ public:
static LLSD getInfo();
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();
static void setUpdateListener();
// <FS:Ansariel> Release notes link not updating
//private:
@ -104,9 +101,9 @@ public:
// callback method for manual checks
static bool callbackCheckUpdate(LLSD const & event);
// listener name for update checks
static const std::string sCheckUpdateListenerName;
// listener name for update checks
static const std::string sCheckUpdateListenerName;
static void startFetchServerReleaseNotes();
static void fetchServerReleaseNotesCoro(std::string cap_url);
@ -140,7 +137,7 @@ BOOL LLFloaterAbout::postBuild()
getChild<LLUICtrl>("copy_btn")->setCommitCallback(
boost::bind(&LLFloaterAbout::onClickCopyToClipboard, this));
// <FS:Ansariel> Disabled update button
//getChild<LLUICtrl>("update_btn")->setCommitCallback(
// boost::bind(&LLFloaterAbout::onClickUpdateCheck, this));
@ -321,7 +318,7 @@ void LLFloaterAbout::onClickCopyToClipboard()
void LLFloaterAbout::onClickUpdateCheck()
{
setUpdateListener();
setUpdateListener();
}
void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
@ -344,66 +341,92 @@ 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;
}
//This is bound as a callback in postBuild()
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);
}
typedef std::vector<std::string> 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) && (!skip) )
{
LLNotificationsUtil::add("UpdateDownloadComplete");
}
else //done and there is a next or skip
{
LLNotificationsUtil::add("UpdateDeferred");
}
}
}
///----------------------------------------------------------------------------
@ -413,11 +436,10 @@ void LLFloaterAboutUtil::registerFloater()
{
LLFloaterReg::add("sl_about", "floater_about.xml",
&LLFloaterReg::build<LLFloaterAbout>);
}
void LLFloaterAboutUtil::checkUpdatesAndNotify()
{
LLFloaterAbout::setUpdateListener();
LLFloaterAbout::setUpdateListener();
}

View File

@ -75,8 +75,7 @@ BOOL LLFloaterTOS::postBuild()
}
// disable Agree to TOS radio button until the page has fully loaded
LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
tos_agreement->setEnabled( false );
updateAgreeEnabled(false);
// hide the SL text widget if we're displaying TOS with using a browser widget.
LLUICtrl *editor = getChild<LLUICtrl>("tos_text");
@ -131,7 +130,7 @@ BOOL LLFloaterTOS::postBuild()
if (LLGridManager::getInstance()->isInOpenSim())
{
mRealNavigateBegun = true;
tos_agreement->setEnabled(true);
updateAgreeEnabled(true);
web_browser->navigateTo(mMessage);
}
else
@ -165,7 +164,7 @@ BOOL LLFloaterTOS::postBuild()
"%3C/head%3E%3Cbody%3E%3Cpre%3E" + mMessage + "%3C/pre%3E%3C/body%3E%3C/html%3E";
mRealNavigateBegun = true;
tos_agreement->setEnabled(true);
updateAgreeEnabled(true);
web_browser->navigateTo(showTos);
}
#endif // OPENSIM
@ -207,8 +206,7 @@ void LLFloaterTOS::setSiteIsAlive( bool alive )
LL_INFOS("TOS") << "ToS page: ToS page unavailable!" << LL_ENDL;
// normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads)
// but if the page is unavailable, we need to do this now
LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
tos_agreement->setEnabled( true );
updateAgreeEnabled(true);
}
}
#endif
@ -225,6 +223,17 @@ void LLFloaterTOS::draw()
LLModalDialog::draw();
}
// update status of "Agree" checkbox and text
void LLFloaterTOS::updateAgreeEnabled(bool enabled)
{
LLCheckBoxCtrl* tos_agreement_agree_cb = getChild<LLCheckBoxCtrl>("agree_chk");
tos_agreement_agree_cb->setEnabled(enabled);
LLTextBox* tos_agreement_agree_text = getChild<LLTextBox>("agree_list");
tos_agreement_agree_text->setEnabled(enabled);
}
// static
void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata )
{
@ -287,9 +296,8 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
else if(mRealNavigateBegun)
{
LL_INFOS("TOS") << "TOS: NAVIGATE COMPLETE" << LL_ENDL;
// enable Agree to TOS radio button now that page has loaded
LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk");
tos_agreement->setEnabled( true );
// enable Agree to TOS check box now that page has loaded
updateAgreeEnabled(true);
}
}
}
@ -302,9 +310,8 @@ void LLFloaterTOS::testSiteIsAliveCoro(LLHandle<LLFloater> handle, std::string u
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setHeadersOnly(true);
LL_INFOS("testSiteIsAliveCoro") << "Generic POST for " << url << LL_ENDL;

View File

@ -58,6 +58,8 @@ public:
void setSiteIsAlive( bool alive );
void updateAgreeEnabled(bool enabled);
// inherited from LLViewerMediaObserver
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);

View File

@ -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<State> 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<State> 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));
@ -605,13 +207,14 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> 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) )
{
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;
@ -713,19 +316,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;
@ -737,22 +327,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)
@ -802,135 +377,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,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,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;

View File

@ -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.
@ -63,10 +62,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; }
@ -75,10 +70,6 @@ public:
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
typedef boost::function<void()> UpdaterLauncherCallback;
void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; }
void setUpdaterService(LLUpdaterService * updaterService) { mUpdaterService = updaterService; }
private:
void constructAuthParams(LLPointer<LLCredential> user_credentials);
void updateApp(bool mandatory, const std::string& message);
@ -100,7 +91,6 @@ private:
std::string mLoginState;
LLSD mRequestData;
LLSD mResponseData;
bool mSkipOptionalUpdate;
bool mAttemptComplete;
F64 mTransferRate;
std::string mSerialNumber;
@ -108,10 +98,7 @@ private:
S32 mLastExecDuration;
std::string mPlatform;
std::string mPlatformVersion;
UpdaterLauncherCallback mUpdaterLauncher;
LLEventDispatcher mDispatcher;
LLUpdaterService * mUpdaterService;
boost::scoped_ptr<Disposable> mUpdateStateMachine;
};
#endif

View File

@ -1569,7 +1569,6 @@ bool idle_startup()
login->setLastExecEvent(last_exec_event);
// </AW: crash report grid correctness>
login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
// This call to LLLoginInstance::connect() starts the
// authentication process.

View File

@ -78,7 +78,6 @@
#include "llspellcheck.h"
#include "llslurl.h"
#include "llstartup.h"
#include "llupdaterservice.h"
// [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0)
#include "rlvcommon.h"
// [/RLVa:KB]
@ -707,19 +706,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();
}
}
// <FS:Ansariel> Change visibility of main chatbar if autohide setting is changed
static void handleAutohideChatbarChanged(const LLSD& new_value)
{
@ -1100,7 +1086,6 @@ void settings_setup_listeners()
// </FS: Zi>
gSavedSettings.getControl("ShowMenuBarLocation")->getSignal()->connect(boost::bind(&toggle_show_menubar_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("ShowStartLocation")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); // <FS:Ansariel> Show start location setting has no effect on login
gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));

View File

@ -2419,22 +2419,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 //
////////////////////
@ -11382,7 +11366,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");

View File

@ -1394,10 +1394,7 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl
LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL;
}
// <FS:Ansariel> Texture memory management
//S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped(); // In MB
S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
// </FS:Ansariel>
//LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL;
if (get_recommended)
max_texmem = llmin(max_texmem, system_ram/2);

View File

@ -802,7 +802,7 @@ public:
// only display these messages if we are actually rendering beacons at this moment
// <FS:LO> Always show the beacon text regardless if the floater is visible
// <FS:Ansa> ...and if we want to see it
//if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
//if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
static LLCachedControl<bool> fsRenderBeaconText(gSavedSettings, "FSRenderBeaconText");
if (LLPipeline::getRenderBeacons() && fsRenderBeaconText)
// </FS:Ansa>
@ -816,7 +816,7 @@ public:
}
// <FS:LO> pull the text saying if particles are hidden out from beacons
/*if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
/*if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES))
{
addText(xpos, ypos, particle_hiding);
ypos += y_inc;

View File

@ -19,7 +19,6 @@
<menu_item_call label="Fehler melden" name="Report Bug"/>
<menu_item_call label="[APP_NAME]-Hilfe" name="Second Life Help"/>
<menu_item_call label="Info über [APP_NAME]" name="About Second Life"/>
<menu_item_call label="Nach Updates suchen" name="Check for Updates"/>
</menu>
<menu_item_check label="Debug-Menü anzeigen" name="Show Debug Menu"/>
<menu label="Debug" name="Debug">

View File

@ -13,8 +13,71 @@
</floater.string>
<floater.string
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
data:text/html;charset=utf-8;base64,PGh0bWw+DQo8aGVhZD4NCjxzdHlsZT4NCmJvZHkgew0KICBmb250LWZhbWlseTogIkRlamEgVnUgU2FucyIsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiAjZmZmOw0KICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMzEsIDMxLCAzMSk7DQp9DQphIHsNCiAgICBjb2xvcjogcmdiKDkyLCAxNzcsIDE0Nik7DQogICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KfQ0KI2NlbnRlcmVkIHsNCiAgcG9zaXRpb246IHJlbGF0aXZlOw0KICBmbG9hdDogbGVmdDsNCiAgdG9wOiA1MCU7DQogIGxlZnQ6IDUwJTsNCiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7DQp9DQo8L3N0eWxlPg0KPC9oZWFkPg0KPGJvZHk+DQo8ZGl2IGlkPSJjZW50ZXJlZCI+TG9hZGluZyA8YSB0YXJnZXQ9Il9leHRlcm5hbCIgaHJlZj0iaHR0cDovL3NlY29uZGxpZmUuY29tL2FwcC90b3MvIj5UZXJtcyBvZiBTZXJ2aWNlPC9hPi4uLjwvZGl2Pg0KPC9ib2R5Pg0KPC9odG1sPg==
</floater.string>
<text
type="string"
length="1"
follows="left|top"
font="SansSerif"
height="45"
layout="topleft"
left="20"
name="tos_heading"
top="20"
word_wrap="true"
width="552">
Please read the following Terms of Service and Privacy Policy carefully. To continue logging in you must accept the agreement.
</text>
<text
type="string"
length="1"
follows="left|top"
font="SansSerif"
height="30"
layout="topleft"
left="20"
name="external_tos_required"
visible="false"
top="20"
word_wrap="true"
width="552">
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!
</text>
<web_browser
trusted_content="true"
follows="left|top"
height="305"
layout="topleft"
left_delta="0"
name="tos_html"
top_delta="70"
width="568" />
<check_box
follows="top|left"
font="SansSerif"
height="16"
label=""
layout="topleft"
left_delta="0"
name="agree_chk"
top_delta="320"
width="55" />
<text
type="string"
length="1"
follows="left|top"
font="SansSerif"
height="30"
layout="topleft"
left_delta="28"
name="agree_list"
top_delta="0"
word_wrap="true"
text_readonly_color="LabelDisabledColor"
width="552">
I have read and agree to the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements.
</text>
<button
enabled="false"
height="20"
@ -23,7 +86,7 @@
layout="topleft"
left="484"
name="Continue"
top="464"
top_delta="35"
width="100" />
<button
height="20"
@ -34,51 +97,4 @@
name="Cancel"
top_delta="0"
width="100" />
<check_box
follows="top|right"
height="16"
label="I Agree to the Terms of Service and Privacy Policy"
layout="topleft"
left_delta="0"
name="agree_chk"
top_delta="-45"
width="55" />
<text
type="string"
length="1"
follows="left|top"
font="SansSerif"
height="30"
layout="topleft"
left_delta="0"
name="tos_heading"
top_delta="-399"
word_wrap="true"
width="552">
Please read the following Terms of Service and Privacy Policy carefully. To continue logging in you must accept the agreement.
</text>
<text
type="string"
length="1"
follows="left|top"
font="SansSerif"
height="30"
layout="topleft"
left="16"
name="external_tos_required"
visible="false"
top="32"
word_wrap="true"
width="552">
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!
</text>
<web_browser
trusted_content="true"
follows="left|top"
height="340"
layout="topleft"
left_delta="0"
name="tos_html"
top_delta="40"
width="568" />
</floater>

View File

@ -151,10 +151,8 @@
parameter="sl_about" />
</menu_item_call>
<menu_item_separator name="grid_help_seperator_login"/>
<menu_item_call
label="[CURRENT_GRID] Help"
name="current_grid_help_login">
<menu_item_call.on_click
function="ShowHelp"
parameter="grid_help" />
</menu_item_call>
@ -164,7 +162,6 @@
<menu_item_call.on_click
function="ShowHelp"
parameter="grid_about" />
</menu_item_call>
</menu>
<menu_item_check
label="Show Debug Menu"

View File

@ -143,6 +143,14 @@
<impl>
media_plugin_example
</impl>
</scheme>
</label>
<widgettype>
movie
</widgettype>
<impl>
media_plugin_example
</impl>
</scheme>
<mimetype name="blank">
<label name="blank_label">

View File

@ -4254,10 +4254,9 @@ An update was downloaded. It will be installed during restart.
<notification
icon="alertmodal.tga"
name="UpdateCheckError"
name="UpdateDeferred"
type="alertmodal">
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.
<tag>confirm</tag>
<usetemplate
name="okbutton"

View File

@ -16,7 +16,6 @@
<menu_item_call label="Blogs de [SECOND_LIFE]" name="Second Life Blogs"/>
<menu_item_call label="Informar de un fallo" name="Report Bug"/>
<menu_item_call label="Acerca de [APP_NAME]" name="About Second Life"/>
<menu_item_call label="Buscar actualizaciones" name="Check for Updates"/>
</menu>
<menu_item_check label="Mostrar el menú &apos;Debug&apos;" name="Show Debug Menu"/>
<menu label="Depurar" name="Debug">

View File

@ -8,7 +8,6 @@
<menu label="Aiuto" name="Help">
<menu_item_call label="Aiuto di [APP_NAME]" name="Second Life Help"/>
<menu_item_call label="Informazioni su [APP_NAME]" name="About Second Life"/>
<menu_item_call label="Cerca aggiornamenti" name="Check for Updates"/>
</menu>
<menu_item_check label="Mostra menu Debug" name="Show Debug Menu"/>
<menu label="Debug" name="Debug">

View File

@ -8,7 +8,6 @@
<menu label="Ajuda" name="Help">
<menu_item_call label="Ajuda do [APP_NAME]" name="Second Life Help"/>
<menu_item_call label="Sobre [APP_NAME]" name="About Second Life"/>
<menu_item_call label="Verificar atualizações" name="Check for Updates"/>
</menu>
<menu_item_check label="Exibir menu de depuração" name="Show Debug Menu"/>
<menu label="Depurar" name="Debug">

View File

@ -16,7 +16,6 @@
<menu_item_call label="[SECOND_LIFE] Bloklar" name="Second Life Blogs"/>
<menu_item_call label="Hata Bildir" name="Report Bug"/>
<menu_item_call label="[APP_NAME] Hakkında" name="About Second Life"/>
<menu_item_call label="Güncellemeleri Kontrol Et" name="Check for Updates"/>
</menu>
<menu_item_check label="Hata Ayıklama Menüsünü Göster" name="Show Debug Menu"/>
<menu label="Hata ayıkla" name="Debug">

View File

@ -178,7 +178,6 @@
<menu_item_call label="Hata Bildir" name="Report Bug"/>
<menu_item_call label="Toslamalar, İtmeler ve Vurmalar" name="Bumps, Pushes &amp;amp; Hits"/>
<menu_item_call label="[APP_NAME] Hakkında" name="About Second Life"/>
<menu_item_call label="Güncellemeleri Kontrol Et" name="Check for Updates"/>
</menu>
<menu label="Gelişmiş" name="Advanced">
<menu_item_call label="Dokuları Tekrar Kaydet" name="Rebake Texture"/>

View File

@ -38,7 +38,7 @@
Grafik başlatma başarılamadı. Lütfen grafik sürücünüzü güncelleştirin!
</string>
<string name="AboutHeader">
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([CHANNEL])
[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) ([CHANNEL])
[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
</string>
<string name="BuildConfig">

View File

@ -8,7 +8,6 @@
<menu label="幫助" name="Help">
<menu_item_call label="[CURRENT_GRID] 幫助" name="Second Life Help"/>
<menu_item_call label="關於 [APP_NAME]" name="About Second Life"/>
<menu_item_call label="查詢是否有新版" name="Check for Updates"/>
</menu>
<menu_item_check label="顯示除錯選單" name="Show Debug Menu"/>
<menu label="除錯" name="Debug">

View File

@ -31,6 +31,9 @@
#include "../llviewernetwork.h"
#include "../lllogininstance.h"
// Needed for Auth Test
#include "../llhasheduniqueid.h"
// STL headers
// std headers
// external library headers
@ -210,41 +213,17 @@ void LLUIColorTable::saveUserSettings(void)const {}
const std::string &LLVersionInfo::getVersion() { return VIEWERLOGIN_VERSION; }
const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
//-----------------------------------------------------------------------------
#include "../llappviewer.h"
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 "../llappviewer.h"
void LLAppViewer::forceQuit(void) {}
LLAppViewer * LLAppViewer::sInstance = 0;
//-----------------------------------------------------------------------------
#include "llnotifications.h"
#include "llfloaterreg.h"
@ -361,7 +340,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);
@ -499,110 +477,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);
}
}

View File

@ -29,6 +29,8 @@
#include "../llversioninfo.h"
#include <iostream>
// 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);

View File

@ -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
@ -36,7 +37,6 @@ import tarfile
import time
import random
#AO
import os
import shlex
import subprocess
import zipfile
@ -226,15 +226,25 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# 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
summary_dict = {"Type":"viewer","Version":'.'.join(self.args['version']),"Channel":self.channel_with_pkg_suffix()}
with open(os.path.join(os.pardir,'summary.json'), 'w') as summary_handle:
json.dump(summary_dict,summary_handle)
#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
build_data_dict = {"Type":"viewer","Version":'.'.join(self.args['version']),
"Channel Base": CHANNEL_VENDOR_BASE,
"Channel":self.channel_with_pkg_suffix(),
"Platform":self.build_data_json_platform,
"Update Service":"https://update.secondlife.com/update",
}
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)
#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 finish_build_data_dict(self, build_data_dict):
return build_data_dict
def grid(self):
return self.args['grid']
@ -266,7 +276,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
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,6 +356,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
@ -398,17 +413,42 @@ 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")
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.
self.path(src='%s/firestorm-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']),
"slplugin.exe")
self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat")
# Get shared libs from the shared libs staging directory
if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
dst=""):
@ -433,7 +473,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")
@ -447,11 +487,11 @@ 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("msvcr120d.dll")
self.path("msvcp120d.dll")
else:
self.path("msvcr120.dll")
self.path("msvcp120.dll")
self.path("msvcr120.dll")
self.path("msvcp120.dll")
# Vivox runtimes
self.path("SLVoice.exe")
@ -459,7 +499,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")
@ -494,6 +533,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
self.path("ca-bundle.crt")
self.path("VivoxAUP.txt")
# Media plugins - CEF
@ -506,21 +546,16 @@ class WindowsManifest(ViewerManifest):
self.path("media_plugin_libvlc.dll")
self.end_prefix()
# Media plugins - GStreamer
if self.prefix(src='../media_plugins/gstreamer10/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_gstreamer10.dll")
self.end_prefix()
# Media plugins - LibVLC
if self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_libvlc.dll")
self.end_prefix()
# Media plugins - Example (useful for debugging - not shipped with release viewer)
if self.channel_type() != 'release':
if self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_example.dll")
self.end_prefix()
# Media plugins - GStreamer
if self.prefix(src='../media_plugins/gstreamer10/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_gstreamer10.dll")
self.end_prefix()
# CEF runtime files - debug
if self.args['configuration'].lower() == 'debug':
@ -700,6 +735,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(),
@ -718,10 +755,12 @@ class WindowsManifest(ViewerManifest):
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"
!define VERSION_REGISTRY "%(version_registry)s"
!define VIEWER_EXE "%(final_exe)s"
""" % substitution_strings
if self.channel_type() == 'release':
@ -738,7 +777,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:
@ -769,67 +808,81 @@ class WindowsManifest(ViewerManifest):
"%%INSTALL_DIR_REGKEY%%": install_dir_regkey,
"%%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.
# 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(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
# self.remove(self.dst_path_of(tempfile))
else:
# NSIS worked! Done!
break
else:
print >> sys.stderr, "Maximum nsis attempts exceeded; giving up"
raise
self.fs_sign_win_installer( substitution_strings ) # <FS:ND/> Sign files, step two. Sign installer.
self.fs_save_windows_symbols( substitution_strings )
# 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):
# self.run_command("%s %s %s" % (python, sign_py, self.dst_path_of(installer_file).replace('\\', '\\\\\\\\')))
# else:
# print "Skipping code signing,", sign_py, "does not exist"
self.created_path(self.dst_path_of(installer_file))
self.package_file = installer_file
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
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
@ -841,17 +894,66 @@ 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")
vmpdir = os.path.join(pkgdir, "VMP")
llbasedir = os.path.join(pkgdir, "lib", "python", "llbase")
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")
# copy additional libs in <bundle>/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")
self.end_prefix()
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")
# 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)
if self.prefix(dst="llbase"):
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()
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()
# Growl Frameworks
self.path("../packages/Frameworks/Growl", dst="Frameworks/Growl")
@ -867,12 +969,19 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
self.path("VivoxAUP.txt")
self.path("ca-bundle.crt")
icon_path = self.icon_path()
if self.prefix(src=icon_path, dst="") :
self.path("firestorm_icon.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("Firestorm.nib")
# Translations
@ -944,10 +1053,9 @@ class DarwinManifest(ViewerManifest):
'libvivoxoal.dylib',
'libvivoxsdk.dylib',
'libvivoxplatform.dylib',
'ca-bundle.crt',
'SLVoice',
):
self.path2basename(relpkgdir, libfile)
self.path2basename(relpkgdir, libfile)
# dylibs that vary based on configuration
if self.args['configuration'].lower() == 'debug':
@ -996,8 +1104,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
@ -1111,12 +1219,6 @@ class DarwinManifest(ViewerManifest):
self.run_command('strip -S %(viewer_binary)r' %
{ 'viewer_binary' : self.dst_path_of('Contents/MacOS/Firestorm')})
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
substitution_strings = self.fs_get_substitution_strings() # <FS:AO> Copied from windows manifest, since we're starting to use many of the same vars
@ -1298,8 +1400,7 @@ class DarwinManifest(ViewerManifest):
class Darwin_i386_Manifest(DarwinManifest):
pass
address_size = 32
class Darwin_i686_Manifest(DarwinManifest):
"""alias in case arch is passed as i686 instead of i386"""
@ -1307,10 +1408,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()
@ -1339,8 +1442,16 @@ class LinuxManifest(ViewerManifest):
if self.prefix(src="", dst="bin"):
self.path("firestorm-bin","do-not-directly-run-firestorm-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")
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/lib/python/llbase","*.py")
self.path2basename("../packages/lib/python/llbase","_cllsd.so")
self.end_prefix("bin")
if self.prefix("res-sdl"):
@ -1468,7 +1579,8 @@ class LinuxManifest(ViewerManifest):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
self.path("featuretable_linux.txt")
self.path("ca-bundle.crt")
if self.is_packaging_viewer():
if self.prefix("../packages/lib/release", dst="lib"):
self.path("libapr-1.so*")
@ -1549,11 +1661,6 @@ class LinuxManifest(ViewerManifest):
self.path("libvivoxplatform.so")
self.end_prefix("lib")
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 'firestorm', 'bin/update_install':
self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
def package_finish(self):
# a standard map of strings for replacing in the templates
@ -1604,9 +1711,13 @@ 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"
# makes some small assumptions about our packaged dir structure
self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install \! -name *.pak \! -name *.dat \! -name *.bin \! -name core \! -path '*win32*' | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # 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):
address_size = 32
def construct(self):
super(Linux_i686_Manifest, self).construct()
@ -1697,6 +1808,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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>

View File

@ -1,4 +1,3 @@
# -*- cmake -*-
add_subdirectory(login)
add_subdirectory(updater)

View File

@ -0,0 +1,9 @@
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:
test_get_summary.py
update_manager.get_summary()
for more details
- coyot 201606.02

View File

@ -0,0 +1 @@
{"Type":"viewer","Version":"4.0.5.315117","Channel":"Second Life Release"}

View File

@ -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 ""
)

View File

@ -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 <stdexcept>
#include <boost/format.hpp>
#include "llsd.h"
#include "llupdatechecker.h"
#include "lluri.h"
#include "llcorehttputil.h"
#if LL_DARWIN
#include <CoreServices/CoreServices.h>
#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();
}

View File

@ -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 <boost/shared_ptr.hpp>
#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<Implementation> 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<Implementation> mImplementation;
};
#endif

View File

@ -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 "llexception.h"
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <curl/curl.h>
#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 LLException
{
public:
DownloadError(const char * message):
LLException(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<LLUpdateDownloader::Implementation *>(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<LLUpdateDownloader::Implementation *>(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<LLUpdateDownloader::Implementation *>(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<bool>(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<const char *> (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<size_t>(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<const char *>(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<int>(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)
{
LLTHROW(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)
{
LLTHROW(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) LLTHROW(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) {
LLTHROW(DownloadError(curl_easy_strerror(code)));
} else {
LLTHROW(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.
}
}

View File

@ -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 <string>
#include <boost/shared_ptr.hpp>
#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<Implementation> 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

View File

@ -1,100 +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 <apr_file_io.h>
#include "llapr.h"
#include "llprocess.h"
#include "llupdateinstaller.h"
#include "lldir.h"
#include "llsd.h"
#include "llexception.h"
#if defined(LL_WINDOWS)
#pragma warning(disable: 4702) // disable 'unreachable code' so we can use lexical_cast (really!).
#endif
#include <boost/lexical_cast.hpp>
namespace {
struct RelocateError: public LLException
{
RelocateError(): LLException("llupdateinstaller: 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) LLTHROW(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<std::string>(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;
}

View File

@ -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 <string>
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

View File

@ -1,766 +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 "llexception.h"
#include <boost/scoped_ptr.hpp>
#include <boost/weak_ptr.hpp>
#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<LLUpdaterServiceImpl> 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;
LLTempBoundListener mMainLoopConnection;
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;
// Destroying an LLTempBoundListener implicitly disconnects. That's its
// whole purpose.
}
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)
{
LLTHROW(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())
{
LLTHROW(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()
{
// <FS:Ansariel> Commented out 2015-08-21
//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;
// }
// }
// }
//}
// </FS:Ansariel>
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);
mMainLoopConnection = 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();
mMainLoopConnection.disconnect();
}
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);
}
//<FS:TM> 3.6.4 check this, commented out to compile
//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<LLUpdaterServiceImpl>(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;
}

View File

@ -1,113 +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 <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include "llhasheduniqueid.h"
#include "llexception.h"
class LLUpdaterServiceImpl;
class LLUpdaterService
{
public:
class UsageError: public LLException
{
public:
UsageError(const std::string& msg) : LLException(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<void (void)> app_exit_callback_t;
template <typename F>
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<LLUpdaterServiceImpl> 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

View File

@ -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

View File

@ -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)

View File

@ -1,414 +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"
TITLE = "Firestorm Viewer Updater"
# Magic bundle identifier used by all Second Life viewer bundles
#BUNDLE_IDENTIFIER = "com.secondlife.indra.viewer"
BUNDLE_IDENTIFIER = "com.firestorm.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:])

View File

@ -1,220 +0,0 @@
#! /bin/bash
# @file update_install
# @author Nat Goodspeed
# @date 2013-01-09
# @brief Update the containing Second Life application bundle to the version in
# the specified tarball.
#
# This bash implementation is derived from the previous linux-updater.bin
# application.
#
# $LicenseInfo:firstyear=2013&license=viewerlgpl$
# Copyright (c) 2013, Linden Research, Inc.
# $/LicenseInfo$
# ****************************************************************************
# script parameters
# ****************************************************************************
tarball="$1" # the file to install
markerfile="$2" # create this file on failure
mandatory="$3" # what to write to markerfile on failure
# ****************************************************************************
# helper functions
# ****************************************************************************
# empty array
cleanups=()
# add a cleanup action to execute on exit
function cleanup {
# wacky bash syntax for appending to array
cleanups[${#cleanups[*]}]="$*"
}
# called implicitly on exit
function onexit {
for action in "${cleanups[@]}"
do # don't quote, support actions consisting of multiple words
$action
done
}
trap 'onexit' EXIT
# write to log file
function log {
# our log file will be open as stderr -- but until we set up that
# redirection, logging to stderr is better than nothing
echo "$*" 1>&2
}
# We display status by leaving one background xmessage process running. This
# is the pid of that process.
statuspid=""
function clear_message {
[ -n "$statuspid" ] && kill $statuspid
statuspid=""
}
# make sure we remove any message box we might have put up
cleanup clear_message
# can we use zenity, or must we fall back to xmessage?
zenpath="$(which zenity)"
if [ -n "$zenpath" ]
then # zenity on PATH and is executable
# display a message box and continue
function status {
# clear any previous message
clear_message
# put up a new zenity box and capture its pid
## "$zenpath" --info --title "Second Life Viewer Updater" \
## --width=320 --height=120 --text="$*" &
# MAINT-2333: use bouncing progress bar
"$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
--width=320 --height=120 --text "$*" </dev/null &
statuspid=$!
}
# display an error box and wait for user
function errorbox {
"$zenpath" --error --title "Second Life Viewer Updater" \
--width=320 --height=120 --text="$*"
}
else # no zenity, use xmessage instead
# display a message box and continue
function status {
# clear any previous message
clear_message
# put up a new xmessage and capture its pid
xmessage -buttons OK:2 -center "$*" &
statuspid=$!
}
# display an error box and wait for user
function errorbox {
xmessage -buttons OK:2 -center "$*"
}
fi
# display an error box and terminate
function fail {
# Log the message
log "$@"
# tell subsequent viewer things went south
echo "$mandatory" > "$markerfile"
# add boilerplate
errorbox "An error occurred while updating Second Life:
$*
Please download the latest viewer from www.secondlife.com."
exit 1
}
# Find a graphical sudo program and define mysudo function. On error, $? is
# nonzero; output is in $err instead of being written to stdout/stderr.
gksudo="$(which gksudo)"
kdesu="$(which kdesu)"
if [ -n "$gksudo" ]
then function mysudo {
# gksudo allows you to specify description
err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)"
}
elif [ -n "$kdesu" ]
then function mysudo {
err="$("$kdesu" "$@" 2>&1)"
}
else # couldn't find either one, just try it anyway
function mysudo {
err="$("$@" 2>&1)"
}
fi
# Move directories, using mysudo if we think it necessary. On error, $? is
# nonzero; output is in $err instead of being written to stdout/stderr.
function sudo_mv {
# If we have write permission to both parent directories, shouldn't need
# sudo.
if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ]
then err="$(mv "$@" 2>&1)"
else # use available sudo program; mysudo sets $? and $err
mysudo mv "$@"
fi
}
# ****************************************************************************
# main script logic
# ****************************************************************************
mydir="$(dirname "$0")"
# We happen to know that the viewer specifies a marker-file pathname within
# the logs directory.
logsdir="$(dirname "$markerfile")"
logname="$logsdir/updater.log"
# move aside old updater.log; we're about to create a new one
[ -f "$logname" ] && mv "$logname" "$logname.old"
# Set up redirections for this script such that stderr is logged. (But first
# move the previous stderr to file descriptor 3.)
exec 3>&2- 2> "$logname"
# Rather than setting up a special pipeline to timestamp every line of stderr,
# produce header lines into log file indicating timestamp and the arguments
# with which we were invoked.
date 1>&2
log "$0 $*"
# Log every command we execute, along with any stderr it might produce
set -x
status 'Installing Second Life...'
# Creating tempdir under /tmp means it's possible that tempdir is on a
# different filesystem than INSTALL_DIR. One is tempted to create tempdir on a
# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can
# handle moving across filesystems??
tempdir="$(mktemp -d)"
tempinstall="$tempdir/install"
# capture the actual error message, if any
err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err"
cleanup rm -rf "$tempdir"
# If we already knew the name of the tarball's top-level directory, we could
# just move that when all was said and done. Since we don't, untarring to the
# 'install' subdir with --strip 1 effectively renames that top-level
# directory.
# untar failures tend to be voluminous -- don't even try to capture, just log
tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed"
INSTALL_DIR="$(cd "$mydir/.." ; pwd)"
# Considering we're launched from a subdirectory of INSTALL_DIR, would be
# surprising if it did NOT already exist...
if [ -e "$INSTALL_DIR" ]
then backup="$INSTALL_DIR.backup"
backupn=1
while [ -e "$backup" ]
do backup="$INSTALL_DIR.backup.$backupn"
((backupn += 1))
done
# on error, fail with actual error message from sudo_mv: permissions,
# cross-filesystem mv, ...?
sudo_mv "$INSTALL_DIR" "$backup" || fail "$err"
fi
# We unpacked the tarball into tempinstall. Move that.
if ! sudo_mv "$tempinstall" "$INSTALL_DIR"
then # If we failed to move the temp install to INSTALL_DIR, try to restore
# INSTALL_DIR from backup. Save $err because next sudo_mv will trash it!
realerr="$err"
sudo_mv "$backup" "$INSTALL_DIR"
fail "$realerr"
fi
# Removing the tarball here, rather than with a 'cleanup' action, means we
# only remove it if we succeeded.
rm -f "$tarball"
# Launch the updated viewer. Restore original stderr from file descriptor 3,
# though -- otherwise updater.log gets cluttered with the viewer log!
"$INSTALL_DIR/secondlife" 2>&3- &

View File

@ -1,3 +0,0 @@
start /WAIT %1 /SKIP_DIALOGS
IF ERRORLEVEL 1 ECHO %3 > %2
DEL %1

View File

@ -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<char,std::char_traits< char > >(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_data> 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());
}
}