diff options
-rwxr-xr-x | .hgtags | 118 | ||||
-rwxr-xr-x | indra/mac_updater/AutoUpdater.nib | bin | 5251 -> 0 bytes | |||
-rw-r--r-- | indra/mac_updater/AutoUpdater.nib/classes.nib | 4 | ||||
-rw-r--r-- | indra/mac_updater/AutoUpdater.nib/info.nib | 14 | ||||
-rw-r--r-- | indra/mac_updater/AutoUpdater.nib/objects.xib | 56 | ||||
-rw-r--r-- | indra/mac_updater/AutoUpdater.xib | 520 | ||||
-rw-r--r-- | indra/mac_updater/CMakeLists.txt | 22 | ||||
-rw-r--r-- | indra/mac_updater/MacUpdater-Info.plist | 30 | ||||
-rw-r--r-- | indra/mac_updater/MacUpdaterAppDelegate.h | 60 | ||||
-rw-r--r-- | indra/mac_updater/MacUpdaterAppDelegate.mm | 265 | ||||
-rw-r--r-- | indra/mac_updater/mac_updater.cpp | 1594 | ||||
-rw-r--r-- | indra/mac_updater/main.m | 34 |
12 files changed, 1227 insertions, 1490 deletions
@@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release 461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip 9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2 9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2 -42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release -42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1 -c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release -c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release 56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1 d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1 -214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release -214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release +42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release +42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release +c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release +c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release 52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1 d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1 0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2 0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2 -8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release -8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release 3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work +214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release +214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1 +8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release +8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release 800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1 +5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release -5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1 beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1 be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release @@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start 9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1 e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1 +6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release -6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start 6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1 be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1 -057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release -057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release 19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start 09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1 09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1 -6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release -6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1 e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1 -493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release -493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release +057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release +057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release +6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release +6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release 502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start 2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1 2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1 +493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release +493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release +54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start +ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start 29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release 29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release 4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix 4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix -54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start -ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start 599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1 599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1 -fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release -fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release 6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1 b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1 -1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release -1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release +fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release +fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release 82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start 364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1 364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1 f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start 42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1 42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1 +1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release +1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2 e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2 b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start @@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start 6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1 61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2 61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2 +586907287be581817b2422b5137971b22d54ea48 3.0.4-start 0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release 0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release -586907287be581817b2422b5137971b22d54ea48 3.0.4-start 92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start 2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1 @@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1 c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start 9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1 9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1 -a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release -a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release 40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start 523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1 523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1 +a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release +a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release 80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start @@ -248,67 +248,57 @@ bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156 6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148 2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155 24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153 -a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159 -9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157 5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1 f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144 -089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161 -600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162 -c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163 2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164 +600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162 80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165 fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2 af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169 4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3 6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release +a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159 +9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157 +089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161 +c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163 b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171 050e48759337249130f684b4a21080b683f61732 DRTVWR-168 09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170 f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158 f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1 -005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167 bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173 cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174 82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2 57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176 eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177 a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3 -888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175 4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180 5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183 6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4 9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184 ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5 28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release +005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167 +888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175 a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182 1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1 -81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186 -47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190 -cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181 -c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188 9ee9387789701d597130f879d9011a4958753862 DRTVWR-189 +47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190 421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192 -4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191 33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195 e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193 -78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194 7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196 ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198 507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197 b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2 37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200 182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3 -248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203 6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199 7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2 7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201 84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4 -de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202 573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5 -34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag -6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205 -7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206 8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207 351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3 af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212 @@ -319,7 +309,6 @@ ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215 97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release 5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1 b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a -b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219 2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220 0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221 e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3 @@ -344,31 +333,36 @@ baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236 b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237 3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12 e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release +81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186 +cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181 +c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188 +4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191 +78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194 +248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203 +de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202 +34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag +6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205 +7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206 +b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219 32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217 704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1 -d799593b53ed733862e9a13871e318e886469377 DRTVWR-208 -e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223 288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216 e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2 -93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240 0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242 710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3 -2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209 -f7bedce18ad52283e6072814db23318907261487 DRTVWR-238 -7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210 e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243 73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4 16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release +d799593b53ed733862e9a13871e318e886469377 DRTVWR-208 +e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223 +93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240 +2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209 +f7bedce18ad52283e6072814db23318907261487 DRTVWR-238 +7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210 5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241 f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232 4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245 94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1 -4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229 -f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246 -39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247 -7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249 -f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230 -b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255 965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252 bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251 ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253 @@ -377,12 +371,22 @@ ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253 44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258 c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257 452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259 -9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260 daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265 9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266 73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267 870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3 0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release +4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229 +f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246 +39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247 +7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249 +f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230 +b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255 +9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260 84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244 083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1 +b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270 +cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2 +2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271 +2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3 35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273 diff --git a/indra/mac_updater/AutoUpdater.nib b/indra/mac_updater/AutoUpdater.nib Binary files differdeleted file mode 100755 index 03883e2b86..0000000000 --- a/indra/mac_updater/AutoUpdater.nib +++ /dev/null diff --git a/indra/mac_updater/AutoUpdater.nib/classes.nib b/indra/mac_updater/AutoUpdater.nib/classes.nib new file mode 100644 index 0000000000..ea58db1189 --- /dev/null +++ b/indra/mac_updater/AutoUpdater.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/indra/mac_updater/AutoUpdater.nib/info.nib b/indra/mac_updater/AutoUpdater.nib/info.nib new file mode 100644 index 0000000000..a49a92385b --- /dev/null +++ b/indra/mac_updater/AutoUpdater.nib/info.nib @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IBDocumentLocation</key> + <string>103 138 356 240 0 0 1280 1002 </string> + <key>IBFramework Version</key> + <string>362.0</string> + <key>IBSystem Version</key> + <string>7D24</string> + <key>targetFramework</key> + <string>IBCarbonFramework</string> +</dict> +</plist> diff --git a/indra/mac_updater/AutoUpdater.nib/objects.xib b/indra/mac_updater/AutoUpdater.nib/objects.xib new file mode 100644 index 0000000000..310411b711 --- /dev/null +++ b/indra/mac_updater/AutoUpdater.nib/objects.xib @@ -0,0 +1,56 @@ +<?xml version="1.0" standalone="yes"?> +<object class="NSIBObjectData"> + <string name="targetFramework">IBCarbonFramework</string> + <object name="rootObject" class="NSCustomObject" id="1"> + <string name="customClass">NSApplication</string> + </object> + <array count="5" name="allObjects"> + <object class="IBCarbonWindow" id="166"> + <string name="windowRect">405 222 533 663 </string> + <string name="title">Second Life Updater</string> + <object name="rootControl" class="IBCarbonRootControl" id="167"> + <string name="bounds">0 0 128 441 </string> + <array count="3" name="subviews"> + <object class="IBCarbonStaticText" id="181"> + <string name="bounds">20 20 44 421 </string> + <ostype name="controlSignature">what</ostype> + <string name="title">Initializing…</string> + </object> + <object class="IBCarbonButton" id="183"> + <string name="bounds">88 351 108 421 </string> + <string name="title">Cancel</string> + <ostype name="command">not!</ostype> + <int name="buttonType">2</int> + </object> + <object class="IBCarbonProgressBar" id="193"> + <string name="bounds">51 19 70 422 </string> + <ostype name="controlSignature">prog</ostype> + <int name="initialValue">50</int> + </object> + </array> + </object> + <boolean name="isResizable">FALSE</boolean> + <int name="carbonWindowClass">2</int> + <int name="themeBrush">3</int> + <int name="windowPosition">7</int> + </object> + <reference idRef="167"/> + <reference idRef="181"/> + <reference idRef="183"/> + <reference idRef="193"/> + </array> + <array count="5" name="allParents"> + <reference idRef="1"/> + <reference idRef="166"/> + <reference idRef="167"/> + <reference idRef="167"/> + <reference idRef="167"/> + </array> + <dictionary count="2" name="nameTable"> + <string>File's Owner</string> + <reference idRef="1"/> + <string>Updater</string> + <reference idRef="166"/> + </dictionary> + <unsigned_int name="nextObjectID">194</unsigned_int> +</object> diff --git a/indra/mac_updater/AutoUpdater.xib b/indra/mac_updater/AutoUpdater.xib deleted file mode 100644 index b29fffba3a..0000000000 --- a/indra/mac_updater/AutoUpdater.xib +++ /dev/null @@ -1,520 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00"> - <data> - <int key="IBDocument.SystemTarget">1070</int> - <string key="IBDocument.SystemVersion">11G63</string> - <string key="IBDocument.InterfaceBuilderVersion">2182</string> - <string key="IBDocument.AppKitVersion">1138.51</string> - <string key="IBDocument.HIToolboxVersion">569.00</string> - <object class="NSMutableDictionary" key="IBDocument.PluginVersions"> - <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="NS.object.0">2182</string> - </object> - <array key="IBDocument.IntegratedClassDependencies"> - <string>NSTextField</string> - <string>NSView</string> - <string>NSWindowTemplate</string> - <string>NSProgressIndicator</string> - <string>NSCustomObject</string> - <string>IBNSLayoutConstraint</string> - <string>NSButtonCell</string> - <string>NSButton</string> - <string>NSUserDefaultsController</string> - <string>NSTextFieldCell</string> - </array> - <array key="IBDocument.PluginDependencies"> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - </array> - <object class="NSMutableDictionary" key="IBDocument.Metadata"> - <string key="NS.key.0">PluginDependencyRecalculationVersion</string> - <integer value="1" key="NS.object.0"/> - </object> - <array class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> - <object class="NSCustomObject" id="1001"> - <string key="NSClassName">NSObject</string> - </object> - <object class="NSCustomObject" id="1003"> - <string key="NSClassName">FirstResponder</string> - </object> - <object class="NSCustomObject" id="1004"> - <string key="NSClassName">NSApplication</string> - </object> - <object class="NSWindowTemplate" id="1005"> - <int key="NSWindowStyleMask">15</int> - <int key="NSWindowBacking">2</int> - <string key="NSWindowRect">{{196, 240}, {402, 120}}</string> - <int key="NSWTFlags">544735232</int> - <string key="NSWindowTitle">Window</string> - <string key="NSWindowClass">NSWindow</string> - <nil key="NSViewClass"/> - <nil key="NSUserInterfaceItemIdentifier"/> - <object class="NSView" key="NSWindowView" id="1006"> - <reference key="NSNextResponder"/> - <int key="NSvFlags">256</int> - <array class="NSMutableArray" key="NSSubviews"> - <object class="NSTextField" id="269124353"> - <reference key="NSNextResponder" ref="1006"/> - <int key="NSvFlags">268</int> - <string key="NSFrame">{{17, 83}, {79, 17}}</string> - <reference key="NSSuperview" ref="1006"/> - <reference key="NSWindow"/> - <reference key="NSNextKeyView" ref="730867742"/> - <string key="NSReuseIdentifierKey">_NS:1505</string> - <bool key="NSEnabled">YES</bool> - <object class="NSTextFieldCell" key="NSCell" id="702170046"> - <int key="NSCellFlags">68288064</int> - <int key="NSCellFlags2">272630784</int> - <string key="NSContents">Initalizing...</string> - <object class="NSFont" key="NSSupport"> - <string key="NSName">LucidaGrande</string> - <double key="NSSize">13</double> - <int key="NSfFlags">1044</int> - </object> - <string key="NSCellIdentifier">_NS:1505</string> - <reference key="NSControlView" ref="269124353"/> - <object class="NSColor" key="NSBackgroundColor"> - <int key="NSColorSpace">6</int> - <string key="NSCatalogName">System</string> - <string key="NSColorName">controlColor</string> - <object class="NSColor" key="NSColor"> - <int key="NSColorSpace">3</int> - <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes> - </object> - </object> - <object class="NSColor" key="NSTextColor"> - <int key="NSColorSpace">6</int> - <string key="NSCatalogName">System</string> - <string key="NSColorName">controlTextColor</string> - <object class="NSColor" key="NSColor"> - <int key="NSColorSpace">3</int> - <bytes key="NSWhite">MAA</bytes> - </object> - </object> - </object> - </object> - <object class="NSProgressIndicator" id="730867742"> - <reference key="NSNextResponder" ref="1006"/> - <int key="NSvFlags">268</int> - <string key="NSFrame">{{18, 55}, {366, 20}}</string> - <reference key="NSSuperview" ref="1006"/> - <reference key="NSWindow"/> - <reference key="NSNextKeyView" ref="302149677"/> - <string key="NSReuseIdentifierKey">_NS:9</string> - <string key="NSHuggingPriority">{250, 250}</string> - <int key="NSpiFlags">16399</int> - <double key="NSMaxValue">100</double> - </object> - <object class="NSButton" id="302149677"> - <reference key="NSNextResponder" ref="1006"/> - <int key="NSvFlags">268</int> - <string key="NSFrame">{{308, 19}, {74, 19}}</string> - <reference key="NSSuperview" ref="1006"/> - <reference key="NSWindow"/> - <reference key="NSNextKeyView"/> - <string key="NSReuseIdentifierKey">_NS:9</string> - <bool key="NSEnabled">YES</bool> - <object class="NSButtonCell" key="NSCell" id="677565961"> - <int key="NSCellFlags">-2080244224</int> - <int key="NSCellFlags2">134217728</int> - <string key="NSContents">Cancel</string> - <object class="NSFont" key="NSSupport"> - <string key="NSName">LucidaGrande</string> - <double key="NSSize">12</double> - <int key="NSfFlags">16</int> - </object> - <string key="NSCellIdentifier">_NS:9</string> - <reference key="NSControlView" ref="302149677"/> - <int key="NSButtonFlags">-2038152961</int> - <int key="NSButtonFlags2">164</int> - <string key="NSAlternateContents"/> - <string key="NSKeyEquivalent"/> - <int key="NSPeriodicDelay">400</int> - <int key="NSPeriodicInterval">75</int> - </object> - </object> - </array> - <string key="NSFrameSize">{402, 120}</string> - <reference key="NSSuperview"/> - <reference key="NSWindow"/> - <reference key="NSNextKeyView" ref="269124353"/> - </object> - <string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string> - <string key="NSMaxSize">{10000000000000, 10000000000000}</string> - <bool key="NSWindowIsRestorable">YES</bool> - </object> - <object class="NSCustomObject" id="492080840"> - <string key="NSClassName">MacUpdaterAppDelegate</string> - </object> - <object class="NSUserDefaultsController" id="21008314"> - <bool key="NSSharedInstance">YES</bool> - </object> - </array> - <object class="IBObjectContainer" key="IBDocument.Objects"> - <array class="NSMutableArray" key="connectionRecords"> - <object class="IBConnectionRecord"> - <object class="IBBindingConnection" key="connection"> - <string key="label">title: values</string> - <reference key="source" ref="1005"/> - <reference key="destination" ref="21008314"/> - <object class="NSNibBindingConnector" key="connector"> - <reference key="NSSource" ref="1005"/> - <reference key="NSDestination" ref="21008314"/> - <string key="NSLabel">title: values</string> - <string key="NSBinding">title</string> - <string key="NSKeyPath">values</string> - <int key="NSNibBindingConnectorVersion">2</int> - </object> - </object> - <int key="connectionID">41</int> - </object> - </array> - <object class="IBMutableOrderedSet" key="objectRecords"> - <array key="orderedObjects"> - <object class="IBObjectRecord"> - <int key="objectID">0</int> - <array key="object" id="0"/> - <reference key="children" ref="1000"/> - <nil key="parent"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-2</int> - <reference key="object" ref="1001"/> - <reference key="parent" ref="0"/> - <string key="objectName">File's Owner</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-1</int> - <reference key="object" ref="1003"/> - <reference key="parent" ref="0"/> - <string key="objectName">First Responder</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-3</int> - <reference key="object" ref="1004"/> - <reference key="parent" ref="0"/> - <string key="objectName">Application</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">1</int> - <reference key="object" ref="1005"/> - <array class="NSMutableArray" key="children"> - <reference ref="1006"/> - </array> - <reference key="parent" ref="0"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">2</int> - <reference key="object" ref="1006"/> - <array class="NSMutableArray" key="children"> - <reference ref="269124353"/> - <reference ref="730867742"/> - <object class="IBNSLayoutConstraint" id="463541650"> - <reference key="firstItem" ref="269124353"/> - <int key="firstAttribute">5</int> - <int key="relation">0</int> - <reference key="secondItem" ref="1006"/> - <int key="secondAttribute">5</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <object class="IBNSLayoutConstraint" id="772497817"> - <reference key="firstItem" ref="730867742"/> - <int key="firstAttribute">5</int> - <int key="relation">0</int> - <reference key="secondItem" ref="1006"/> - <int key="secondAttribute">5</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <object class="IBNSLayoutConstraint" id="929212820"> - <reference key="firstItem" ref="1006"/> - <int key="firstAttribute">6</int> - <int key="relation">0</int> - <reference key="secondItem" ref="730867742"/> - <int key="secondAttribute">6</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <reference ref="302149677"/> - <object class="IBNSLayoutConstraint" id="813415053"> - <reference key="firstItem" ref="1006"/> - <int key="firstAttribute">6</int> - <int key="relation">0</int> - <reference key="secondItem" ref="302149677"/> - <int key="secondAttribute">6</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <object class="IBNSLayoutConstraint" id="178579609"> - <reference key="firstItem" ref="269124353"/> - <int key="firstAttribute">3</int> - <int key="relation">0</int> - <reference key="secondItem" ref="1006"/> - <int key="secondAttribute">3</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <object class="IBNSLayoutConstraint" id="594621082"> - <reference key="firstItem" ref="730867742"/> - <int key="firstAttribute">3</int> - <int key="relation">0</int> - <reference key="secondItem" ref="269124353"/> - <int key="secondAttribute">4</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">8</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">6</int> - <float key="scoringTypeFloat">24</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - <object class="IBNSLayoutConstraint" id="658067790"> - <reference key="firstItem" ref="1006"/> - <int key="firstAttribute">4</int> - <int key="relation">0</int> - <reference key="secondItem" ref="302149677"/> - <int key="secondAttribute">4</int> - <float key="multiplier">1</float> - <object class="IBNSLayoutSymbolicConstant" key="constant"> - <double key="value">20</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">8</int> - <float key="scoringTypeFloat">29</float> - <int key="contentType">3</int> - <reference key="containingView" ref="1006"/> - </object> - </array> - <reference key="parent" ref="1005"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">3</int> - <reference key="object" ref="269124353"/> - <array class="NSMutableArray" key="children"> - <reference ref="702170046"/> - </array> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">4</int> - <reference key="object" ref="702170046"/> - <reference key="parent" ref="269124353"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">8</int> - <reference key="object" ref="730867742"/> - <array class="NSMutableArray" key="children"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">20</int> - <reference key="object" ref="463541650"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">22</int> - <reference key="object" ref="302149677"/> - <array class="NSMutableArray" key="children"> - <reference ref="677565961"/> - <object class="IBNSLayoutConstraint" id="981064020"> - <reference key="firstItem" ref="302149677"/> - <int key="firstAttribute">7</int> - <int key="relation">0</int> - <nil key="secondItem"/> - <int key="secondAttribute">0</int> - <float key="multiplier">1</float> - <object class="IBLayoutConstant" key="constant"> - <double key="value">74</double> - </object> - <float key="priority">1000</float> - <int key="scoringType">3</int> - <float key="scoringTypeFloat">9</float> - <int key="contentType">1</int> - <reference key="containingView" ref="302149677"/> - </object> - </array> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">23</int> - <reference key="object" ref="677565961"/> - <reference key="parent" ref="302149677"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">31</int> - <reference key="object" ref="772497817"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">32</int> - <reference key="object" ref="929212820"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">35</int> - <reference key="object" ref="813415053"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">36</int> - <reference key="object" ref="981064020"/> - <reference key="parent" ref="302149677"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">37</int> - <reference key="object" ref="178579609"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">38</int> - <reference key="object" ref="594621082"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">39</int> - <reference key="object" ref="658067790"/> - <reference key="parent" ref="1006"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">40</int> - <reference key="object" ref="21008314"/> - <reference key="parent" ref="0"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">42</int> - <reference key="object" ref="492080840"/> - <reference key="parent" ref="0"/> - </object> - </array> - </object> - <dictionary class="NSMutableDictionary" key="flattenedProperties"> - <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="1.IBWindowTemplateEditedContentRect">{{357, 418}, {480, 270}}</string> - <integer value="1" key="1.NSWindowTemplate.visibleAtLaunch"/> - <array class="NSMutableArray" key="2.IBNSViewMetadataConstraints"> - <reference ref="463541650"/> - <reference ref="772497817"/> - <reference ref="929212820"/> - <reference ref="813415053"/> - <reference ref="178579609"/> - <reference ref="594621082"/> - <reference ref="658067790"/> - </array> - <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="20.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <array class="NSMutableArray" key="22.IBNSViewMetadataConstraints"> - <reference ref="981064020"/> - </array> - <boolean value="NO" key="22.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> - <string key="22.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <boolean value="NO" key="3.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> - <string key="3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="31.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="32.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="35.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="36.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="37.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="38.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="39.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="4.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="40.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <string key="42.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - <boolean value="NO" key="8.IBNSViewMetadataTranslatesAutoresizingMaskIntoConstraints"/> - <string key="8.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string> - </dictionary> - <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/> - <nil key="activeLocalization"/> - <dictionary class="NSMutableDictionary" key="localizations"/> - <nil key="sourceID"/> - <int key="maxID">42</int> - </object> - <object class="IBClassDescriber" key="IBDocument.Classes"> - <array class="NSMutableArray" key="referencedPartialClassDescriptions"> - <object class="IBPartialClassDescription"> - <string key="className">MacUpdaterAppDelegate</string> - <string key="superclassName">NSObject</string> - <object class="NSMutableDictionary" key="actions"> - <string key="NS.key.0">cancel:</string> - <string key="NS.object.0">id</string> - </object> - <object class="NSMutableDictionary" key="actionInfosByName"> - <string key="NS.key.0">cancel:</string> - <object class="IBActionInfo" key="NS.object.0"> - <string key="name">cancel:</string> - <string key="candidateClassName">id</string> - </object> - </object> - <dictionary class="NSMutableDictionary" key="outlets"> - <string key="mProgressBar">NSProgressIndicator</string> - <string key="mProgressText">NSTextField</string> - <string key="window">NSWindow</string> - </dictionary> - <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName"> - <object class="IBToOneOutletInfo" key="mProgressBar"> - <string key="name">mProgressBar</string> - <string key="candidateClassName">NSProgressIndicator</string> - </object> - <object class="IBToOneOutletInfo" key="mProgressText"> - <string key="name">mProgressText</string> - <string key="candidateClassName">NSTextField</string> - </object> - <object class="IBToOneOutletInfo" key="window"> - <string key="name">window</string> - <string key="candidateClassName">NSWindow</string> - </object> - </dictionary> - <object class="IBClassDescriptionSource" key="sourceIdentifier"> - <string key="majorKey">IBProjectSource</string> - <string key="minorKey">./Classes/MacUpdaterAppDelegate.h</string> - </object> - </object> - </array> - </object> - <int key="IBDocument.localizationMode">0</int> - <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string> - <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool> - <int key="IBDocument.defaultPropertyAccessControl">3</int> - <bool key="IBDocument.UseAutolayout">YES</bool> - </data> -</archive> diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt index 7382e912bf..00dcedecaa 100644 --- a/indra/mac_updater/CMakeLists.txt +++ b/indra/mac_updater/CMakeLists.txt @@ -18,14 +18,10 @@ include_directories( ) set(mac_updater_SOURCE_FILES - main.m - MacUpdaterAppDelegate.mm mac_updater.cpp ) set(mac_updater_HEADER_FILES - MacUpdaterAppDelegate.h - mac_updater.h CMakeLists.txt ) @@ -36,7 +32,7 @@ list(APPEND mac_updater_SOURCE_FILES ${mac_updater_HEADER_FILES}) set(mac_updater_RESOURCE_FILES - AutoUpdater.nib + AutoUpdater.nib/ ) set_source_files_properties( ${mac_updater_RESOURCE_FILES} @@ -52,19 +48,13 @@ add_executable(mac-updater set_target_properties(mac-updater PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/MacUpdater-Info.plist + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ) -find_library(COCOA_LIBRARY Cocoa) -find_library(IOKIT_LIBRARY IOKit) - target_link_libraries(mac-updater ${LLVFS_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${COCOA_LIBRARIES} - ${BOOST_FILESYSTEM_LIBRARY} - ${IOKIT_LIBRARY} ${CURL_LIBRARIES} ${CARES_LIBRARIES} ${LLCOMMON_LIBRARIES} @@ -72,16 +62,10 @@ target_link_libraries(mac-updater add_custom_command( TARGET mac-updater POST_BUILD -# COMMAND ${CMAKE_COMMAND} -# ARGS -# -E -# copy_directory -# ${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdater.nib -# ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-updater.app/Contents/Resources/AutoUpdater.nib COMMAND ${CMAKE_COMMAND} ARGS -E - copy + copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/AutoUpdater.nib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-updater.app/Contents/Resources/AutoUpdater.nib ) diff --git a/indra/mac_updater/MacUpdater-Info.plist b/indra/mac_updater/MacUpdater-Info.plist deleted file mode 100644 index 92137095ff..0000000000 --- a/indra/mac_updater/MacUpdater-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>mac-updater</string> - <key>CFBundleGetInfoString</key> - <string></string> - <key>CFBundleIconFile</key> - <string></string> - <key>CFBundleIdentifier</key> - <string>com.secondlife.indra.autoupdater</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string></string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1.0.0</string> - <key>NSMainNibFile</key> - <string>AutoUpdater</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> diff --git a/indra/mac_updater/MacUpdaterAppDelegate.h b/indra/mac_updater/MacUpdaterAppDelegate.h deleted file mode 100644 index c051214bb8..0000000000 --- a/indra/mac_updater/MacUpdaterAppDelegate.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file MacUpdaterAppDelegate.h - * @brief - * - * $LicenseInfo:firstyear=2006&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$ - */ - - -#import <Cocoa/Cocoa.h> -#include <iostream> -#include "mac_updater.h" - -#ifndef LL_MAC_UPDATE_DELEGATE_H -#define LL_MAC_UPDATE_DELEGATE_H - -@interface MacUpdaterAppDelegate : NSObject <NSApplicationDelegate> -{ - IBOutlet NSProgressIndicator *mProgressBar; - IBOutlet NSTextField *mProgressText; -} -- (void)setWindow:(NSWindow *)newWindow; -- (NSWindow *)window; -- (IBAction)cancel:(id)sender; -- (void) setProgress:(int)cur max:(int) max; -- (void) setProgressText:(const std::string&)str; -- (int) parse_args:(NSArray *) args; -- (void)stopAlert; -- (void)stopAlertDidEnd:(NSAlert *)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo; - - -NSWindow *_window; -bool mAnimated; -double mProgressPercentage; -@property (assign) IBOutlet NSWindow *window; -LLMacUpdater mUpdater; - -@end - -#endif //LL_MAC_UPDATE_DELEGATE_H - - diff --git a/indra/mac_updater/MacUpdaterAppDelegate.mm b/indra/mac_updater/MacUpdaterAppDelegate.mm deleted file mode 100644 index b6f95eef7e..0000000000 --- a/indra/mac_updater/MacUpdaterAppDelegate.mm +++ /dev/null @@ -1,265 +0,0 @@ -/** - * @file MacUpdaterAppDelegate.mm - * @brief - * - * $LicenseInfo:firstyear=2006&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$ - */ - -#import "MacUpdaterAppDelegate.h" -#include "llvfs_objc.h" -#include <string.h> -#include <boost/filesystem.hpp> - -@implementation MacUpdaterAppDelegate - -MacUpdaterAppDelegate *gWindow; -bool gCancelled = false; -bool gFailure =false; - - -//@synthesize window = _window; -- (void)setWindow:(NSWindow *)window -{ - _window = window; -} - -- (NSWindow *)window -{ - return _window; -} - -- (id)init -{ - self = [super init]; - if (self) { - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - mAnimated = false; - mProgressPercentage = 0.0; - NSArray *arguments = [[NSProcessInfo processInfo] arguments]; - - [self parse_args:arguments]; - gWindow = self; - - mUpdater.doUpdate(); - [pool drain]; - [pool release]; - } - return self; -} - -- (void)dealloc -{ - [super dealloc]; -} - -std::string* NSToString( NSString *ns_str ) -{ - return ( new std::string([ns_str UTF8String]) ); -} - - -- (void) setProgress:(int)cur max:(int) max -{ - bool indeterminate = false; - if (max==0) - { - indeterminate = true; - } - else - { - double percentage = ((double)cur / (double)max) * 100.0; - [mProgressBar setDoubleValue:percentage]; - } - [mProgressBar setIndeterminate:indeterminate]; -} - -- (void) setProgressText:(const std::string& )str -{ - [mProgressText setStringValue:[NSString stringWithUTF8String:str.c_str()]]; -} - -void sendDone() -{ - [ [ (id) gWindow window ] close]; -} - -void sendStopAlert() -{ - [ gWindow stopAlert ]; -} - -void setProgress(int cur, int max) -{ - [ (id) gWindow setProgress:cur max:max]; -} - -void setProgressText(const std::string& str) -{ - [ (id) gWindow setProgressText:str]; -} - -void sendProgress(int cur, int max, const std::string str) -{ - setProgress(cur,max); - setProgressText(str); -} - -bool copyDir(const std::string& src_dir, const std::string& dest_dir) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString* file = [NSString stringWithCString:src_dir.c_str() - encoding:[NSString defaultCStringEncoding]]; - NSString* toParent = [NSString stringWithCString:dest_dir.c_str() - encoding:[NSString defaultCStringEncoding]]; - NSError* error = nil; - - bool result = [[NSFileManager defaultManager] copyItemAtPath: file toPath: toParent error:&error]; - - if (!result) { - NSLog(@"Error during copy: %@", [error localizedDescription]); - } - [pool release]; - - return result; -} - -- (int) parse_args:(NSArray *) args -{ - int i; - int argc = [args count]; - - mUpdater.mApplicationPath = NSToString( [args objectAtIndex:0] ); - - for( i = 1; i < argc; i++ ) - { - NSString* ns_arg = [args objectAtIndex:i]; - const char *arg = [ns_arg UTF8String]; - - if ((!strcmp(arg, "-url")) && (i < argc)) - { - mUpdater.mUpdateURL = NSToString( [args objectAtIndex:(++i)] ); - } - else if ((!strcmp(arg, "-name")) && (i < argc)) - { - mUpdater.mProductName = NSToString( [args objectAtIndex:(++i)] ); - } - else if ((!strcmp(arg, "-bundleid")) && (i < argc)) - { - mUpdater.mBundleID = NSToString( [args objectAtIndex:(++i)] ); - } - else if ((!strcmp(arg, "-dmg")) && (i < argc)) - { - mUpdater.mDmgFile = NSToString( [args objectAtIndex:(++i)] ); - } - else if ((!strcmp(arg, "-marker")) && (i < argc)) - { - mUpdater.mMarkerPath = NSToString( [args objectAtIndex:(++i)] ); - } - } - return 0; -} - -bool isDirWritable(const std::string& dir_name) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *fullPath = [NSString stringWithCString:dir_name.c_str() - encoding:[NSString defaultCStringEncoding]]; - - NSFileManager *fm = [NSFileManager defaultManager]; - bool result = [fm isWritableFileAtPath:fullPath]; - [pool release]; - - return result; -} - -std::string* getUserTrashFolder() -{ - std::string *result; - - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *trash_str=[NSHomeDirectory() stringByAppendingPathComponent:@".Trash"]; - - result = NSToString( trash_str ); - - [pool release]; - return result; - -} - -bool isFSRefViewerBundle(const std::string& targetURL) -{ - bool result = false; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *fullPath = [NSString stringWithCString:targetURL.c_str() - encoding:[NSString defaultCStringEncoding]]; - NSBundle *targetBundle = [NSBundle bundleWithPath:fullPath]; - NSString *targetBundleStr = [targetBundle bundleIdentifier]; - NSString *sourceBundleStr = [NSString stringWithCString:mUpdater.mBundleID->c_str() - encoding:[NSString defaultCStringEncoding]]; - - result = [targetBundleStr isEqualToString:sourceBundleStr]; - - if(!result) - { - std::cout << "Target bundle ID mismatch." << std::endl; - } - - [pool release]; - - return result; -} - - -- (IBAction)cancel:(id)sender -{ - gCancelled = true; - sendDone(); -} - -- (void)stopAlert -{ - NSAlert *alert = [[NSAlert alloc] init]; - [alert setAlertStyle:NSInformationalAlertStyle]; - [alert setMessageText:@"Error"]; - [alert setInformativeText:@"An error occurred while updating Second Life. Please download the latest version from www.secondlife.com."]; - - [alert beginSheetModalForWindow:_window - modalDelegate:self - - didEndSelector:@selector(stopAlertDidEnd:returnCode: - contextInfo:) - contextInfo:nil]; - } - - - (void)stopAlertDidEnd:(NSAlert *)alert - returnCode:(int)returnCode contextInfo:(void *)contextInfo -{ - [alert release]; -} - - -@end diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index fc9565d63d..aa45c5d23f 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -27,8 +27,6 @@ #include "linden_common.h" #include <boost/format.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem.hpp> #include <libgen.h> #include <sys/types.h> @@ -36,6 +34,7 @@ #include <unistd.h> #include <curl/curl.h> +#include <pthread.h> #include "llerror.h" #include "lltimer.h" @@ -44,566 +43,1177 @@ #include "llstring.h" +#include <Carbon/Carbon.h> + #include "llerrorcontrol.h" -#include "mac_updater.h" -#include <sstream> + +enum +{ + kEventClassCustom = 'Cust', + kEventCustomProgress = 'Prog', + kEventParamCustomCurValue = 'Cur ', + kEventParamCustomMaxValue = 'Max ', + kEventParamCustomText = 'Text', + kEventCustomDone = 'Done', +}; + +WindowRef gWindow = NULL; +EventHandlerRef gEventHandler = NULL; +OSStatus gFailure = noErr; +Boolean gCancelled = false; + +const char *gUpdateURL; +const char *gProductName; +const char *gBundleID; +const char *gDmgFile; +const char *gMarkerPath; + +void *updatethreadproc(void*); pthread_t updatethread; -LLMacUpdater* LLMacUpdater::sInstance = NULL; +OSStatus setProgress(int cur, int max) +{ + OSStatus err; + ControlRef progressBar = NULL; + ControlID id; + + id.signature = 'prog'; + id.id = 0; + + err = GetControlByID(gWindow, &id, &progressBar); + if(err == noErr) + { + Boolean indeterminate; + + if(max == 0) + { + indeterminate = true; + err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate); + } + else + { + double percentage = (double)cur / (double)max; + SetControlMinimum(progressBar, 0); + SetControlMaximum(progressBar, 100); + SetControlValue(progressBar, (SInt16)(percentage * 100)); + + indeterminate = false; + err = SetControlData(progressBar, kControlEntireControl, kControlProgressBarIndeterminateTag, sizeof(Boolean), (Ptr)&indeterminate); + + Draw1Control(progressBar); + } + } + + return(err); +} + +OSStatus setProgressText(CFStringRef text) +{ + OSStatus err; + ControlRef progressText = NULL; + ControlID id; + + id.signature = 'what'; + id.id = 0; + + err = GetControlByID(gWindow, &id, &progressText); + if(err == noErr) + { + err = SetControlData(progressText, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), (Ptr)&text); + Draw1Control(progressText); + } + + return(err); +} + +OSStatus sendProgress(long cur, long max, CFStringRef text = NULL) +{ + OSStatus result; + EventRef evt; + + result = CreateEvent( + NULL, + kEventClassCustom, + kEventCustomProgress, + 0, + kEventAttributeNone, + &evt); + + // This event needs to be targeted at the window so it goes to the window's handler. + if(result == noErr) + { + EventTargetRef target = GetWindowEventTarget(gWindow); + result = SetEventParameter ( + evt, + kEventParamPostTarget, + typeEventTargetRef, + sizeof(target), + &target); + } + + if(result == noErr) + { + result = SetEventParameter ( + evt, + kEventParamCustomCurValue, + typeLongInteger, + sizeof(cur), + &cur); + } + + if(result == noErr) + { + result = SetEventParameter ( + evt, + kEventParamCustomMaxValue, + typeLongInteger, + sizeof(max), + &max); + } + + if(result == noErr) + { + if(text != NULL) + { + result = SetEventParameter ( + evt, + kEventParamCustomText, + typeCFStringRef, + sizeof(text), + &text); + } + } + + if(result == noErr) + { + // Send the event + PostEventToQueue( + GetMainEventQueue(), + evt, + kEventPriorityStandard); + + } + + return(result); +} + +OSStatus sendDone(void) +{ + OSStatus result; + EventRef evt; + + result = CreateEvent( + NULL, + kEventClassCustom, + kEventCustomDone, + 0, + kEventAttributeNone, + &evt); + + // This event needs to be targeted at the window so it goes to the window's handler. + if(result == noErr) + { + EventTargetRef target = GetWindowEventTarget(gWindow); + result = SetEventParameter ( + evt, + kEventParamPostTarget, + typeEventTargetRef, + sizeof(target), + &target); + } + + if(result == noErr) + { + // Send the event + PostEventToQueue( + GetMainEventQueue(), + evt, + kEventPriorityStandard); -LLMacUpdater::LLMacUpdater(): - mUpdateURL (NULL), - mProductName (NULL), - mBundleID (NULL), - mDmgFile (NULL), - mMarkerPath (NULL) + } + + return(result); +} + +OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) { - sInstance = this; + OSStatus result = eventNotHandledErr; + OSStatus err; + UInt32 evtClass = GetEventClass(event); + UInt32 evtKind = GetEventKind(event); + + if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) + { + HICommand cmd; + err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); + + if(err == noErr) + { + switch(cmd.commandID) + { + case kHICommandCancel: + gCancelled = true; +// QuitAppModalLoopForWindow(gWindow); + result = noErr; + break; + } + } + } + else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomProgress)) + { + // Request to update the progress dialog + long cur = 0; + long max = 0; + CFStringRef text = NULL; + (void) GetEventParameter(event, kEventParamCustomCurValue, typeLongInteger, NULL, sizeof(cur), NULL, &cur); + (void) GetEventParameter(event, kEventParamCustomMaxValue, typeLongInteger, NULL, sizeof(max), NULL, &max); + (void) GetEventParameter(event, kEventParamCustomText, typeCFStringRef, NULL, sizeof(text), NULL, &text); + + err = setProgress(cur, max); + if(err == noErr) + { + if(text != NULL) + { + setProgressText(text); + } + } + + result = noErr; + } + else if((evtClass == kEventClassCustom) && (evtKind == kEventCustomDone)) + { + // We're done. Exit the modal loop. + QuitAppModalLoopForWindow(gWindow); + result = noErr; + } + + return(result); } -void LLMacUpdater::doUpdate() +#if 0 +size_t curl_download_callback(void *data, size_t size, size_t nmemb, + void *user_data) { - // We assume that all the logs we're looking for reside on the current drive + S32 bytes = size * nmemb; + char *cdata = (char *) data; + for (int i =0; i < bytes; i += 1) + { + gServerResponse.append(cdata[i]); + } + return bytes; +} +#endif + +int curl_progress_callback_func(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + int max = (int)(dltotal / 1024.0); + int cur = (int)(dlnow / 1024.0); + sendProgress(cur, max); + + if(gCancelled) + return(1); + + return(0); +} + +int parse_args(int argc, char **argv) +{ + int j; + + for (j = 1; j < argc; j++) + { + if ((!strcmp(argv[j], "-url")) && (++j < argc)) + { + gUpdateURL = argv[j]; + } + else if ((!strcmp(argv[j], "-name")) && (++j < argc)) + { + gProductName = argv[j]; + } + else if ((!strcmp(argv[j], "-bundleid")) && (++j < argc)) + { + gBundleID = argv[j]; + } + else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) + { + gDmgFile = argv[j]; + } + else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) + { + gMarkerPath = argv[j];; + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + // We assume that all the logs we're looking for reside on the current drive gDirUtilp->initAppDirs("SecondLife"); - + LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - + // Rename current log file to ".old" std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log.old"); std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log"); LLFile::rename(log_file.c_str(), old_log_file.c_str()); - + // Set the log file to updater.log LLError::logToFile(log_file); - - if ((mUpdateURL == NULL) && (mDmgFile == NULL)) + + ///////////////////////////////////////// + // + // Process command line arguments + // + gUpdateURL = NULL; + gProductName = NULL; + gBundleID = NULL; + gDmgFile = NULL; + gMarkerPath = NULL; + parse_args(argc, argv); + if ((gUpdateURL == NULL) && (gDmgFile == NULL)) { llinfos << "Usage: mac_updater -url <url> | -dmg <dmg file> [-name <product_name>] [-program <program_name>]" << llendl; exit(1); } else { - llinfos << "Update url is: " << mUpdateURL << llendl; - if (mProductName) + llinfos << "Update url is: " << gUpdateURL << llendl; + if (gProductName) { - llinfos << "Product name is: " << *mProductName << llendl; + llinfos << "Product name is: " << gProductName << llendl; } else { - mProductName = new std::string("Second Life"); + gProductName = "Second Life"; } - if (mBundleID) + if (gBundleID) { - llinfos << "Bundle ID is: " << *mBundleID << llendl; + llinfos << "Bundle ID is: " << gBundleID << llendl; } else { - mBundleID = new std::string("com.secondlife.indra.viewer"); + gBundleID = "com.secondlife.indra.viewer"; } } - llinfos << "Starting " << *mProductName << " Updater" << llendl; - - pthread_create(&updatethread, - NULL, - &sUpdatethreadproc, - NULL); - - + llinfos << "Starting " << gProductName << " Updater" << llendl; + + // Real UI... + OSStatus err; + IBNibRef nib = NULL; + + err = CreateNibReference(CFSTR("AutoUpdater"), &nib); + + char windowTitle[MAX_PATH]; /* Flawfinder: ignore */ + snprintf(windowTitle, sizeof(windowTitle), "%s Updater", gProductName); + CFStringRef windowTitleRef = NULL; + windowTitleRef = CFStringCreateWithCString(NULL, windowTitle, kCFStringEncodingUTF8); + + if(err == noErr) + { + err = CreateWindowFromNib(nib, CFSTR("Updater"), &gWindow); + } + + if (err == noErr) + { + err = SetWindowTitleWithCFString(gWindow, windowTitleRef); + } + CFRelease(windowTitleRef); + + if(err == noErr) + { + // Set up an event handler for the window. + EventTypeSpec handlerEvents[] = + { + { kEventClassCommand, kEventCommandProcess }, + { kEventClassCustom, kEventCustomProgress }, + { kEventClassCustom, kEventCustomDone } + }; + InstallStandardEventHandler(GetWindowEventTarget(gWindow)); + InstallWindowEventHandler( + gWindow, + NewEventHandlerUPP(dialogHandler), + GetEventTypeCount (handlerEvents), + handlerEvents, + 0, + &gEventHandler); + } + + if(err == noErr) + { + ShowWindow(gWindow); + SelectWindow(gWindow); + } + + if(err == noErr) + { + pthread_create(&updatethread, + NULL, + &updatethreadproc, + NULL); + + } + + if(err == noErr) + { + RunAppModalLoopForWindow(gWindow); + } + void *threadresult; - + pthread_join(updatethread, &threadresult); - - if(gCancelled || gFailure) + + if(!gCancelled && (gFailure != noErr)) { - sendStopAlert(); - - if(mMarkerPath != 0) + // Something went wrong. Since we always just tell the user to download a new version, we don't really care what. + AlertStdCFStringAlertParamRec params; + SInt16 retval_mac = 1; + DialogRef alert = NULL; + OSStatus err; + + params.version = kStdCFStringAlertVersionOne; + params.movable = false; + params.helpButton = false; + params.defaultText = (CFStringRef)kAlertDefaultOKText; + params.cancelText = 0; + params.otherText = 0; + params.defaultButton = 1; + params.cancelButton = 0; + params.position = kWindowDefaultPosition; + params.flags = 0; + + err = CreateStandardAlert( + kAlertStopAlert, + CFSTR("Error"), + CFSTR("An error occurred while updating Second Life. Please download the latest version from www.secondlife.com."), + ¶ms, + &alert); + + if(err == noErr) + { + err = RunStandardAlert( + alert, + NULL, + &retval_mac); + } + + if(gMarkerPath != 0) { // Create a install fail marker that can be used by the viewer to // detect install problems. - std::ofstream stream(mMarkerPath->c_str()); + std::ofstream stream(gMarkerPath); if(stream) stream << -1; } exit(-1); } else { exit(0); } + + if(gWindow != NULL) + { + DisposeWindow(gWindow); + } - return; + if(nib != NULL) + { + DisposeNibReference(nib); + } + + return 0; } -//SPATTERS TODO this should be moved to lldir_mac.cpp -const std::string LLMacUpdater::walkParents( signed int depth, const std::string& childpath ) +bool isDirWritable(FSRef &dir) { - boost::filesystem::path fullpath(childpath.c_str()); - - while (depth > 0 && fullpath.has_parent_path()) - { - fullpath = boost::filesystem::path(fullpath.parent_path()); - --depth; - } - - return fullpath.string(); -} + bool result = false; + + // Test for a writable directory by creating a directory, then deleting it again. + // This is kinda lame, but will pretty much always give the right answer. + + OSStatus err = noErr; + char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ -//#if 0 -//size_t curl_download_callback(void *data, size_t size, size_t nmemb, -// void *user_data) -//{ -// S32 bytes = size * nmemb; -// char *cdata = (char *) data; -// for (int i =0; i < bytes; i += 1) -// { -// gServerResponse.append(cdata[i]); -// } -// return bytes; -//} -//#endif + err = FSRefMakePath(&dir, (UInt8*)temp, sizeof(temp)); -int curl_progress_callback_func(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow) -{ - int max = (int)(dltotal / 1024.0); - int cur = (int)(dlnow / 1024.0); - setProgress(cur, max); - - if(gCancelled) - return(1); + if(err == noErr) + { + strncat(temp, "/.test_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); + + if(mkdtemp(temp) != NULL) + { + // We were able to make the directory. This means the directory is writable. + result = true; + + // Clean up. + rmdir(temp); + } + } - return(0); -} +#if 0 + // This seemed like a good idea, but won't tell us if we're on a volume mounted read-only. + UInt8 perm; + err = FSGetUserPrivilegesPermissions(&targetParentRef, &perm, NULL); + if(err == noErr) + { + if(perm & kioACUserNoMakeChangesMask) + { + // Parent directory isn't writable. + llinfos << "Target parent directory not writable." << llendl; + err = -1; + replacingTarget = false; + } + } +#endif -bool LLMacUpdater::isApplication(const std::string& app_str) -{ - return !(bool) app_str.compare( app_str.length()-4, 4, ".app"); + return result; } - -// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. -bool LLMacUpdater::findAppBundleOnDiskImage(const boost::filesystem::path& dir_path, - boost::filesystem::path& path_found) + +static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) { - if ( !boost::filesystem::exists( dir_path ) ) return false; - - boost::filesystem::directory_iterator end_itr; - - for ( boost::filesystem::directory_iterator itr( dir_path ); - itr != end_itr; - ++itr ) - { - if ( boost::filesystem::is_directory(itr->status()) ) - { - std::string dir_name = itr->path().string(); - if ( isApplication(dir_name) ) - { - if(isFSRefViewerBundle(dir_name)) - { - llinfos << dir_name << " is the one" << llendl; - - path_found = itr->path(); - return true; - } - } - } - } - return false; + llutf16string string16((U16*)&(src->unicode), src->length); + std::string result = utf16str_to_utf8str(string16); + return result; } -bool LLMacUpdater::verifyDirectory(const boost::filesystem::path* directory, bool isParent) +int restoreObject(const char* aside, const char* target, const char* path, const char* object) { - bool replacingTarget; - std::string app_str = directory->string(); - - if (boost::filesystem::is_directory(*directory)) - { - // This is fine, just means we're not replacing anything. - replacingTarget = true; - } - else - { - replacingTarget = isParent; - } - - //Check that the directory is writeable. - if(!isDirWritable(app_str)) - { - // Parent directory isn't writable. - llinfos << "Target directory not writable." << llendl; - replacingTarget = false; - } - return replacingTarget; + char source[PATH_MAX] = ""; /* Flawfinder: ignore */ + char dest[PATH_MAX] = ""; /* Flawfinder: ignore */ + snprintf(source, sizeof(source), "%s/%s/%s", aside, path, object); + snprintf(dest, sizeof(dest), "%s/%s", target, path); + FSRef sourceRef; + FSRef destRef; + OSStatus err; + err = FSPathMakeRef((UInt8 *)source, &sourceRef, NULL); + if(err != noErr) return false; + err = FSPathMakeRef((UInt8 *)dest, &destRef, NULL); + if(err != noErr) return false; + + llinfos << "Copying " << source << " to " << dest << llendl; + + err = FSCopyObjectSync( + &sourceRef, + &destRef, + NULL, + NULL, + kFSFileOperationOverwrite); + + if(err != noErr) return false; + return true; } - -bool LLMacUpdater::getViewerDir(boost::filesystem::path &app_dir) + +// Replace any mention of "Second Life" with the product name. +void filterFile(const char* filename) { - std::string app_dir_str; - - //Walk up 6 levels from the App Updater's installation point. - app_dir_str = walkParents( 6, *mApplicationPath ); - - app_dir = boost::filesystem::path(app_dir_str); - - //Check to see that the directory's name ends in .app Lame but it's the best thing we have to go on. - //If it's not there, we're going to default to /Applications/VIEWERNAME - if (!isApplication(app_dir_str)) - { - llinfos << "Target search failed, defaulting to /Applications/" << *mProductName << ".app." << llendl; - std::string newpath = std::string("/Applications/") + mProductName->c_str(); - app_dir = boost::filesystem::path(newpath); - } - return verifyDirectory(&app_dir); + char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ + // First copy the target's version, so we can run it through sed. + snprintf(temp, sizeof(temp), "cp '%s' '%s.tmp'", filename, filename); + system(temp); /* Flawfinder: ignore */ + + // Now run it through sed. + snprintf(temp, sizeof(temp), + "sed 's/Second Life/%s/g' '%s.tmp' > '%s'", gProductName, filename, filename); + system(temp); /* Flawfinder: ignore */ } -bool LLMacUpdater::downloadDMG(const std::string& dmgName, boost::filesystem::path* temp_dir) +static bool isFSRefViewerBundle(FSRef *targetRef) { - LLFILE *downloadFile = NULL; - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ + bool result = false; + CFURLRef targetURL = NULL; + CFBundleRef targetBundle = NULL; + CFStringRef targetBundleID = NULL; + CFStringRef sourceBundleID = NULL; - chdir(temp_dir->string().c_str()); - - snprintf(temp, sizeof(temp), "SecondLife.dmg"); - - downloadFile = LLFile::fopen(temp, "wb"); /* Flawfinder: ignore */ - if(downloadFile == NULL) - { - return false; - } - - bool success = false; - - CURL *curl = curl_easy_init(); - - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_download_callback); - curl_easy_setopt(curl, CURLOPT_FILE, downloadFile); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &curl_progress_callback_func); - curl_easy_setopt(curl, CURLOPT_URL, mUpdateURL); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - - sendProgress(0, 1, std::string("Downloading...")); - - CURLcode result = curl_easy_perform(curl); - - curl_easy_cleanup(curl); - - if(gCancelled) - { - llinfos << "User cancel, bailing out."<< llendl; - goto close_file; - } - - if(result != CURLE_OK) - { - llinfos << "Error " << result << " while downloading disk image."<< llendl; - goto close_file; - } - - fclose(downloadFile); - downloadFile = NULL; - - success = true; - -close_file: - // Close disk image file if necessary - if(downloadFile != NULL) + targetURL = CFURLCreateFromFSRef(NULL, targetRef); + + if(targetURL == NULL) { - llinfos << "Closing download file." << llendl; - - fclose(downloadFile); - downloadFile = NULL; + llinfos << "Error creating target URL." << llendl; } - - return success; -} - -bool LLMacUpdater::doMount(const std::string& dmgName, char* deviceNode, const boost::filesystem::path& temp_dir) -{ - char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ - - sendProgress(0, 0, std::string("Mounting image...")); - chdir(temp_dir.string().c_str()); - std::string mnt_dir = temp_dir.string() + std::string("/mnt"); - LLFile::mkdir(mnt_dir.c_str(), 0700); - - // NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder, - // but if our cleanup fails, this makes it much harder for the user to unmount the image. - std::string mountOutput; - boost::format cmdFormat("hdiutil attach %s -mountpoint mnt"); - cmdFormat % dmgName; - FILE* mounter = popen(cmdFormat.str().c_str(), "r"); /* Flawfinder: ignore */ - - if(mounter == NULL) - { - llinfos << "Failed to mount disk image, exiting."<< llendl; - return false; - } - - // We need to scan the output from hdiutil to find the device node it uses to attach the disk image. - // If we don't have this information, we can't detach it later. - while(mounter != NULL) - { - size_t len = fread(temp, 1, sizeof(temp)-1, mounter); - temp[len] = 0; - mountOutput.append(temp); - if(len < sizeof(temp)-1) - { - // End of file or error. - int result = pclose(mounter); - if(result != 0) - { - // NOTE: We used to abort here, but pclose() started returning - // -1, possibly when the size of the DMG passed a certain point - llinfos << "Unexpected result closing pipe: " << result << llendl; - } - mounter = NULL; - } - } - - if(!mountOutput.empty()) - { - const char *s = mountOutput.c_str(); - const char *prefix = "/dev/"; - char *sub = strstr(s, prefix); - - if(sub != NULL) - { - sub += strlen(prefix); /* Flawfinder: ignore */ - sscanf(sub, "%1023s", deviceNode); /* Flawfinder: ignore */ - } - } - - if(deviceNode[0] != 0) - { - llinfos << "Disk image attached on /dev/" << deviceNode << llendl; - } - else - { - llinfos << "Disk image device node not found!" << llendl; - return false; - } - - return true; + else + { + targetBundle = CFBundleCreate(NULL, targetURL); + } + + if(targetBundle == NULL) + { + llinfos << "Failed to create target bundle." << llendl; + } + else + { + targetBundleID = CFBundleGetIdentifier(targetBundle); + } + + if(targetBundleID == NULL) + { + llinfos << "Couldn't retrieve target bundle ID." << llendl; + } + else + { + sourceBundleID = CFStringCreateWithCString(NULL, gBundleID, kCFStringEncodingUTF8); + if(CFStringCompare(sourceBundleID, targetBundleID, 0) == kCFCompareEqualTo) + { + // This is the bundle we're looking for. + result = true; + } + else + { + llinfos << "Target bundle ID mismatch." << llendl; + } + } + + // Don't release targetBundleID -- since we don't retain it, it's released when targetBundle is released. + if(targetURL != NULL) + CFRelease(targetURL); + if(targetBundle != NULL) + CFRelease(targetBundle); + + return result; } -bool LLMacUpdater::moveApplication (const boost::filesystem::path& app_dir, - const boost::filesystem::path& temp_dir, - boost::filesystem::path& aside_dir) +// Search through the directory specified by 'parent' for an item that appears to be a Second Life viewer. +static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app) { - try - { - //Grab filename from installdir append to tempdir move set aside_dir to moved path. - std::string install_str = app_dir.parent_path().string(); - std::string temp_str = temp_dir.string(); - std::string app_str = app_dir.filename().string(); - aside_dir = boost::filesystem::path( boost::filesystem::operator/(temp_dir,app_str) ); - std::cout << "Attempting to move " << app_dir.string() << " to " << aside_dir.string() << std::endl; - - boost::filesystem::rename(app_dir, aside_dir); - } - catch(boost::filesystem::filesystem_error e) - { - llinfos << "Application move failed." << llendl; - return false; - } - return true; -} + FSIterator iterator; + bool found = false; -bool LLMacUpdater::doInstall(const boost::filesystem::path& app_dir, - const boost::filesystem::path& temp_dir, - boost::filesystem::path& mount_dir, - bool replacingTarget) -{ - std::string temp_name = temp_dir.string() + std::string("/mnt"); - - llinfos << "Disk image mount point is: " << temp_name << llendl; - - mount_dir = boost::filesystem::path(temp_name.c_str()); - - if (! boost::filesystem::exists ( mount_dir ) ) - { - llinfos << "Couldn't make FSRef to disk image mount point." << llendl; - return false; - } - - sendProgress(0, 0, std::string("Searching for the app bundle...")); - - boost::filesystem::path source_dir; - - if ( !findAppBundleOnDiskImage(mount_dir, source_dir) ) - { - llinfos << "Couldn't find application bundle on mounted disk image." << llendl; - return false; - } - else - { - llinfos << "found the bundle." << llendl; - } - - sendProgress(0, 0, std::string("Preparing to copy files...")); - - // this will hold the name of the destination target - boost::filesystem::path aside_dir; - - if(replacingTarget) - { - - if (! moveApplication (app_dir, temp_dir, aside_dir) ) - { - llwarns << "failed to move aside old version." << llendl; - return false; - } - } - - sendProgress(0, 0, std::string("Copying files...")); - - llinfos << "Starting copy..." << llendl; - // If we were replacingTarget, we've moved the app to a temp directory. - // Otherwise the destination should be empty. - // We have mounted the DMG as a volume so we should be able to just - // move the app from the volume to the destination and everything will just work. - - - // Copy the new version from the disk image to the target location. - - //The installer volume is mounted read-only so we can't move. Instead copy and then unmount. - if (! copyDir(source_dir.string(), app_dir.string()) ) - { - llwarns << "Failed to copy " << source_dir.string() << " to " << app_dir.string() << llendl; - - // Something went wrong during the copy. Attempt to put the old version back and bail. - boost::filesystem::rename(app_dir, aside_dir); - return false; - - } - - // The update has succeeded. Clear the cache directory. - - sendProgress(0, 0, std::string("Clearing cache...")); - - llinfos << "Clearing cache..." << llendl; - - gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); - - llinfos << "Clear complete." << llendl; - - return true; -} + OSErr err = FSOpenIterator( parent, kFSIterateFlat, &iterator ); + if(!err) + { + do + { + ItemCount actualObjects = 0; + Boolean containerChanged = false; + FSCatalogInfo info; + FSRef ref; + HFSUniStr255 unicodeName; + err = FSGetCatalogInfoBulk( + iterator, + 1, + &actualObjects, + &containerChanged, + kFSCatInfoNodeFlags, + &info, + &ref, + NULL, + &unicodeName ); + + if(actualObjects == 0) + break; + + if(!err) + { + // Call succeeded and not done with the iteration. + std::string name = HFSUniStr255_to_utf8str(&unicodeName); + + llinfos << "Considering \"" << name << "\"" << llendl; + + if(info.nodeFlags & kFSNodeIsDirectoryMask) + { + // This is a directory. See if it's a .app + if(name.find(".app") != std::string::npos) + { + // Looks promising. Check to see if it has the right bundle identifier. + if(isFSRefViewerBundle(&ref)) + { + llinfos << name << " is the one" << llendl; + // This is the one. Return it. + *app = ref; + found = true; + break; + } else { + llinfos << name << " is not the bundle we are looking for; move along" << llendl; + } -bool mkTempDir(boost::filesystem::path& temp_dir) -{ - char temp_str[PATH_MAX] = "/tmp/SecondLifeUpdate_XXXXXX"; - - if(mkdtemp(temp_str) == NULL) - { - return false; - } - - temp_dir = boost::filesystem::path(temp_str); - - return true; + } + } + } + } + while(!err); + + llinfos << "closing the iterator" << llendl; + + FSCloseIterator(iterator); + + llinfos << "closed" << llendl; + } + + if(!err && !found) + err = fnfErr; + + return err; } -void* LLMacUpdater::updatethreadproc(void*) +void *updatethreadproc(void*) { char tempDir[PATH_MAX] = ""; /* Flawfinder: ignore */ + FSRef tempDirRef; char temp[PATH_MAX] = ""; /* Flawfinder: ignore */ // *NOTE: This buffer length is used in a scanf() below. char deviceNode[1024] = ""; /* Flawfinder: ignore */ - - bool replacingTarget = false; - - boost::filesystem::path app_dir; - boost::filesystem::path temp_dir; - boost::filesystem::path mount_dir; - - // Attempt to get a reference to the Second Life application bundle containing this updater. - // Any failures during this process will cause us to default to updating /Applications/Second Life.app + LLFILE *downloadFile = NULL; + OSStatus err; + ProcessSerialNumber psn; + char target[PATH_MAX] = ""; /* Flawfinder: ignore */ + FSRef targetRef; + FSRef targetParentRef; + FSVolumeRefNum targetVol; + FSRef trashFolderRef; + Boolean replacingTarget = false; + memset(&tempDirRef, 0, sizeof(tempDirRef)); + memset(&targetRef, 0, sizeof(targetRef)); + memset(&targetParentRef, 0, sizeof(targetParentRef)); + try - { - replacingTarget = getViewerDir( app_dir ); - - if (!mkTempDir(temp_dir)) - { - throw 0; - } - - //In case the dir doesn't exist, try to create it. If create fails, verify it exists. - if (! boost::filesystem::create_directory(app_dir)) - { - - - if(isFSRefViewerBundle(app_dir.string())) - { - // This is the bundle we're looking for. - replacingTarget = true; - } - else - { - throw 0; - } - } - - if ( !verifyDirectory(&app_dir, true) ) - { - // We're so hosed. - llinfos << "Applications directory not found, giving up." << llendl; - throw 0; - } + { + // Attempt to get a reference to the Second Life application bundle containing this updater. + // Any failures during this process will cause us to default to updating /Applications/Second Life.app + { + FSRef myBundle; + + err = GetCurrentProcess(&psn); + if(err == noErr) + { + err = GetProcessBundleLocation(&psn, &myBundle); + } + + if(err == noErr) + { + // Sanity check: Make sure the name of the item referenced by targetRef is "Second Life.app". + FSRefMakePath(&myBundle, (UInt8*)target, sizeof(target)); + + llinfos << "Updater bundle location: " << target << llendl; + } + + // Our bundle should be in Second Life.app/Contents/Resources/AutoUpdater.app + // so we need to go up 3 levels to get the path to the main application bundle. + if(err == noErr) + { + err = FSGetCatalogInfo(&myBundle, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); + } + if(err == noErr) + { + err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); + } + if(err == noErr) + { + err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetRef); + } + + // And once more to get the parent of the target + if(err == noErr) + { + err = FSGetCatalogInfo(&targetRef, kFSCatInfoNone, NULL, NULL, NULL, &targetParentRef); + } + + if(err == noErr) + { + FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); + llinfos << "Path to target: " << target << llendl; + } + + // Sanity check: make sure the target is a bundle with the right identifier + if(err == noErr) + { + // Assume the worst... + err = -1; + + if(isFSRefViewerBundle(&targetRef)) + { + // This is the bundle we're looking for. + err = noErr; + replacingTarget = true; + } + } + + // Make sure the target's parent directory is writable. + if(err == noErr) + { + if(!isDirWritable(targetParentRef)) + { + // Parent directory isn't writable. + llinfos << "Target parent directory not writable." << llendl; + err = -1; + replacingTarget = false; + } + } + + if(err != noErr) + { + Boolean isDirectory; + llinfos << "Target search failed, defaulting to /Applications/" << gProductName << ".app." << llendl; + + // Set up the parent directory + err = FSPathMakeRef((UInt8*)"/Applications", &targetParentRef, &isDirectory); + if((err != noErr) || (!isDirectory)) + { + // We're so hosed. + llinfos << "Applications directory not found, giving up." << llendl; + throw 0; + } + + snprintf(target, sizeof(target), "/Applications/%s.app", gProductName); + + memset(&targetRef, 0, sizeof(targetRef)); + err = FSPathMakeRef((UInt8*)target, &targetRef, NULL); + if(err == fnfErr) + { + // This is fine, just means we're not replacing anything. + err = noErr; + replacingTarget = false; + } + else + { + replacingTarget = true; + } + + // Make sure the target's parent directory is writable. + if(err == noErr) + { + if(!isDirWritable(targetParentRef)) + { + // Parent directory isn't writable. + llinfos << "Target parent directory not writable." << llendl; + err = -1; + replacingTarget = false; + } + } + + } + + // If we haven't fixed all problems by this point, just bail. + if(err != noErr) + { + llinfos << "Unable to pick a target, giving up." << llendl; + throw 0; + } + } + + // Find the volID of the volume the target resides on + { + FSCatalogInfo info; + err = FSGetCatalogInfo( + &targetParentRef, + kFSCatInfoVolume, + &info, + NULL, + NULL, + NULL); + + if(err != noErr) + throw 0; + + targetVol = info.volume; + } + + // Find the temporary items and trash folders on that volume. + err = FSFindFolder( + targetVol, + kTrashFolderType, + true, + &trashFolderRef); + + if(err != noErr) + throw 0; + +#if 0 // *HACK for DEV-11935 see below for details. + + FSRef tempFolderRef; + + err = FSFindFolder( + targetVol, + kTemporaryFolderType, + true, + &tempFolderRef); + + if(err != noErr) + throw 0; + + err = FSRefMakePath(&tempFolderRef, (UInt8*)temp, sizeof(temp)); + + if(err != noErr) + throw 0; + +#else + + // *HACK for DEV-11935 the above kTemporaryFolderType query was giving + // back results with path names that seem to be too long to be used as + // mount points. I suspect this incompatibility was introduced in the + // Leopard 10.5.2 update, but I have not verified this. + char const HARDCODED_TMP[] = "/tmp"; + strncpy(temp, HARDCODED_TMP, sizeof(HARDCODED_TMP)); + +#endif // 0 *HACK for DEV-11935 // Skip downloading the file if the dmg was passed on the command line. std::string dmgName; - if(mDmgFile != NULL) { - //Create a string from the mDmgFile then a dir reference to that. - //change to that directory and begin install. - - boost::filesystem::path dmg_path(*mDmgFile); - - dmgName = dmg_path.string(); - std::string* dmgPath = new std::string(dmg_path.parent_path().string()); - if ( !boost::filesystem::exists( dmg_path.parent_path() ) ) { - llinfos << "Path " << *dmgPath << " is not writeable. Aborting." << llendl; - throw 0; - } - - chdir(dmgPath->c_str()); + if(gDmgFile != NULL) { + dmgName = basename((char *)gDmgFile); + char * dmgDir = dirname((char *)gDmgFile); + strncpy(tempDir, dmgDir, sizeof(tempDir)); + err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); + if(err != noErr) throw 0; + chdir(tempDir); + goto begin_install; } else { // Continue on to download file. dmgName = "SecondLife.dmg"; - - - if (!downloadDMG(dmgName, &temp_dir)) - { - throw 0; - } - } - - if (!doMount(dmgName, deviceNode, temp_dir)) - { - throw 0; - } - - if (!doInstall( app_dir, temp_dir, mount_dir, replacingTarget )) - { - throw 0; - } + } + + + strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1); + if(mkdtemp(temp) == NULL) + { + throw 0; + } + + strncpy(tempDir, temp, sizeof(tempDir)); + temp[sizeof(tempDir) - 1] = '\0'; + + llinfos << "tempDir is " << tempDir << llendl; + + err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL); + + if(err != noErr) + throw 0; + + chdir(tempDir); + + snprintf(temp, sizeof(temp), "SecondLife.dmg"); + + downloadFile = LLFile::fopen(temp, "wb"); /* Flawfinder: ignore */ + if(downloadFile == NULL) + { + throw 0; + } + + { + CURL *curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + // curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curl_download_callback); + curl_easy_setopt(curl, CURLOPT_FILE, downloadFile); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, &curl_progress_callback_func); + curl_easy_setopt(curl, CURLOPT_URL, gUpdateURL); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + + sendProgress(0, 1, CFSTR("Downloading...")); + + CURLcode result = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + if(gCancelled) + { + llinfos << "User cancel, bailing out."<< llendl; + throw 0; + } + + if(result != CURLE_OK) + { + llinfos << "Error " << result << " while downloading disk image."<< llendl; + throw 0; + } + + fclose(downloadFile); + downloadFile = NULL; + } + + begin_install: + sendProgress(0, 0, CFSTR("Mounting image...")); + LLFile::mkdir("mnt", 0700); + + // NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder, + // but if our cleanup fails, this makes it much harder for the user to unmount the image. + std::string mountOutput; + boost::format cmdFormat("hdiutil attach %s -mountpoint mnt"); + cmdFormat % dmgName; + FILE* mounter = popen(cmdFormat.str().c_str(), "r"); /* Flawfinder: ignore */ + + if(mounter == NULL) + { + llinfos << "Failed to mount disk image, exiting."<< llendl; + throw 0; + } + + // We need to scan the output from hdiutil to find the device node it uses to attach the disk image. + // If we don't have this information, we can't detach it later. + while(mounter != NULL) + { + size_t len = fread(temp, 1, sizeof(temp)-1, mounter); + temp[len] = 0; + mountOutput.append(temp); + if(len < sizeof(temp)-1) + { + // End of file or error. + int result = pclose(mounter); + if(result != 0) + { + // NOTE: We used to abort here, but pclose() started returning + // -1, possibly when the size of the DMG passed a certain point + llinfos << "Unexpected result closing pipe: " << result << llendl; + } + mounter = NULL; + } + } + + if(!mountOutput.empty()) + { + const char *s = mountOutput.c_str(); + const char *prefix = "/dev/"; + char *sub = strstr(s, prefix); + + if(sub != NULL) + { + sub += strlen(prefix); /* Flawfinder: ignore */ + sscanf(sub, "%1023s", deviceNode); /* Flawfinder: ignore */ + } + } + + if(deviceNode[0] != 0) + { + llinfos << "Disk image attached on /dev/" << deviceNode << llendl; + } + else + { + llinfos << "Disk image device node not found!" << llendl; + throw 0; + } + + // Get an FSRef to the new application on the disk image + FSRef sourceRef; + FSRef mountRef; + snprintf(temp, sizeof(temp), "%s/mnt", tempDir); + + llinfos << "Disk image mount point is: " << temp << llendl; + err = FSPathMakeRef((UInt8 *)temp, &mountRef, NULL); + if(err != noErr) + { + llinfos << "Couldn't make FSRef to disk image mount point." << llendl; + throw 0; + } + + sendProgress(0, 0, CFSTR("Searching for the app bundle...")); + err = findAppBundleOnDiskImage(&mountRef, &sourceRef); + if(err != noErr) + { + llinfos << "Couldn't find application bundle on mounted disk image." << llendl; + throw 0; + } + else + { + llinfos << "found the bundle." << llendl; + } + + sendProgress(0, 0, CFSTR("Preparing to copy files...")); + + FSRef asideRef; + char aside[MAX_PATH]; /* Flawfinder: ignore */ + + // this will hold the name of the destination target + CFStringRef appNameRef; + + if(replacingTarget) + { + // Get the name of the target we're replacing + HFSUniStr255 appNameUniStr; + err = FSGetCatalogInfo(&targetRef, 0, NULL, &appNameUniStr, NULL, NULL); + if(err != noErr) + throw 0; + appNameRef = FSCreateStringFromHFSUniStr(NULL, &appNameUniStr); + + // Move aside old version (into work directory) + err = FSMoveObject(&targetRef, &tempDirRef, &asideRef); + if(err != noErr) + { + llwarns << "failed to move aside old version (error code " << + err << ")" << llendl; + throw 0; + } + + // Grab the path for later use. + err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside)); + } + else + { + // Construct the name of the target based on the product name + char appName[MAX_PATH]; /* Flawfinder: ignore */ + snprintf(appName, sizeof(appName), "%s.app", gProductName); + appNameRef = CFStringCreateWithCString(NULL, appName, kCFStringEncodingUTF8); + } + + sendProgress(0, 0, CFSTR("Copying files...")); + + llinfos << "Starting copy..." << llendl; + + // Copy the new version from the disk image to the target location. + err = FSCopyObjectSync( + &sourceRef, + &targetParentRef, + appNameRef, + &targetRef, + kFSFileOperationDefaultOptions); + + // Grab the path for later use. + err = FSRefMakePath(&targetRef, (UInt8*)target, sizeof(target)); + if(err != noErr) + throw 0; + + llinfos << "Copy complete. Target = " << target << llendl; + + if(err != noErr) + { + // Something went wrong during the copy. Attempt to put the old version back and bail. + (void)FSDeleteObject(&targetRef); + if(replacingTarget) + { + (void)FSMoveObject(&asideRef, &targetParentRef, NULL); + } + throw 0; + } + else + { + // The update has succeeded. Clear the cache directory. + + sendProgress(0, 0, CFSTR("Clearing cache...")); + + llinfos << "Clearing cache..." << llendl; + + gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*"); + + llinfos << "Clear complete." << llendl; + + } } catch(...) { if(!gCancelled) - gFailure = true; + if(gFailure == noErr) + gFailure = -1; } // Failures from here on out are all non-fatal and not reported. - sendProgress(0, 3, std::string("Cleaning up...")); + sendProgress(0, 3, CFSTR("Cleaning up...")); - setProgress(1, 3); + // Close disk image file if necessary + if(downloadFile != NULL) + { + llinfos << "Closing download file." << llendl; + + fclose(downloadFile); + downloadFile = NULL; + } + + sendProgress(1, 3); // Unmount image if(deviceNode[0] != 0) { @@ -613,61 +1223,35 @@ void* LLMacUpdater::updatethreadproc(void*) system(temp); /* Flawfinder: ignore */ } - setProgress(2, 3); - std::string *trash_str=getUserTrashFolder(); + sendProgress(2, 3); // Move work directory to the trash if(tempDir[0] != 0) { llinfos << "Moving work directory to the trash." << llendl; - - try - { - boost::filesystem::path trash_dir(*trash_str); - boost::filesystem::rename(mount_dir, trash_dir); - } - catch(boost::filesystem::filesystem_error e) - { - llwarns << "Failed to move " << mount_dir.string() << " to " << *trash_str << llendl; - return (NULL); - } + + FSRef trashRef; + OSStatus err = FSMoveObjectToTrashSync(&tempDirRef, &trashRef, 0); + if(err != noErr) { + llwarns << "failed to move files to trash, (error code " << + err << ")" << llendl; + } } - std::string app_name_str = app_dir.string(); - - if(!gCancelled && !gFailure && !app_name_str.empty()) + if(!gCancelled && !gFailure && (target[0] != 0)) { - //SPATTERS todo is there no better way to do this than system calls? llinfos << "Touching application bundle." << llendl; - - std::stringstream touch_str; - touch_str << "touch '" << app_name_str << "'"; - - system(touch_str.str().c_str()); /* Flawfinder: ignore */ + snprintf(temp, sizeof(temp), "touch '%s'", target); + system(temp); /* Flawfinder: ignore */ llinfos << "Launching updated application." << llendl; - - std::stringstream open_str; - - open_str << "open '" << app_name_str << "'"; - system(open_str.str().c_str()); /* Flawfinder: ignore */ + snprintf(temp, sizeof(temp), "open '%s'", target); + system(temp); /* Flawfinder: ignore */ } sendDone(); - return (NULL); + return(NULL); } - -//static -void* LLMacUpdater::sUpdatethreadproc(void* vptr) -{ - if (!sInstance) - { - llerrs << "LLMacUpdater not instantiated before use. Aborting." << llendl; - return (NULL); - } - return sInstance->updatethreadproc(vptr); -} - diff --git a/indra/mac_updater/main.m b/indra/mac_updater/main.m deleted file mode 100644 index aa3776a87d..0000000000 --- a/indra/mac_updater/main.m +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file main.m - * @brief - * - * $LicenseInfo:firstyear=2006&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$ - */ - -#import <Cocoa/Cocoa.h> - -int main(int argc, char *argv[]) -{ - int retVal = NSApplicationMain(argc, (const char **)argv); - - return retVal; -} |