diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index fc7b0a878..8b71ccf51 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -75,7 +75,6 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts) add_custom_target(viewer) -add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llui) @@ -87,28 +86,6 @@ add_subdirectory(${LIBS_OPEN_PREFIX}plugins) # add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) #endif (NOT LINUX) -if (LINUX) - add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) - add_dependencies(viewer linux-crash-logger-strip-target) -elseif (DARWIN) - #add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) - #add_subdirectory(${VIEWER_PREFIX}mac_updater) - add_dependencies(viewer mac-crash-logger) - #add_dependencies(viewer mac-updater) -elseif (WINDOWS) - add_subdirectory(${VIEWER_PREFIX}win_crash_logger) - # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake - if (EXISTS ${VIEWER_DIR}win_setup) - add_subdirectory(${VIEWER_DIR}win_setup) - endif (EXISTS ${VIEWER_DIR}win_setup) - add_subdirectory(${VIEWER_PREFIX}win_updater) - add_dependencies(viewer windows-updater) - add_dependencies(viewer windows-crash-logger) -elseif (SOLARIS) - add_subdirectory(solaris_crash_logger) - add_dependencies(viewer solaris-crash-logger) -endif (LINUX) - add_subdirectory(${VIEWER_PREFIX}newview/statemachine) add_subdirectory(${VIEWER_PREFIX}newview) add_dependencies(viewer secondlife-bin) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4391a8985..5ff1b0399 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -61,7 +61,6 @@ set(cmake_SOURCE_FILES LLAudio.cmake LLCharacter.cmake LLCommon.cmake - LLCrashLogger.cmake LLImage.cmake LLImageJ2COJ.cmake LLInventory.cmake diff --git a/indra/cmake/LLCrashLogger.cmake b/indra/cmake/LLCrashLogger.cmake deleted file mode 100644 index f2cb83eb8..000000000 --- a/indra/cmake/LLCrashLogger.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLCRASHLOGGER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llcrashlogger - ) - -set(LLCRASHLOGGER_LIBRARIES llcrashlogger) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt deleted file mode 100644 index d885e3704..000000000 --- a/indra/linux_crash_logger/CMakeLists.txt +++ /dev/null @@ -1,72 +0,0 @@ -# -*- cmake -*- - -project(linux_crash_logger) - -include(00-Common) -include(LLCommon) -include(LLCrashLogger) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLXML) -include(Linking) -include(UI) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCRASHLOGGER_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) - -set(linux_crash_logger_SOURCE_FILES - linux_crash_logger.cpp - llcrashloggerlinux.cpp - ) - -set(linux_crash_logger_HEADER_FILES - CMakeLists.txt - - llcrashloggerlinux.h - ) - -set_source_files_properties(${linux_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND linux_crash_logger_SOURCE_FILES - ${linux_crash_logger_HEADER_FILES} - ) - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") - -add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES}) - -target_link_libraries(linux-crash-logger - ${LLCRASHLOGGER_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLUI_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${UI_LIBRARIES} - ${DB_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ${CURL_LIBRARIES} - ${APR_LIBRARIES} - ${APRUTIL_LIBRARIES} - ${CRYPTO_LIBRARIES} - rt - ) - -add_custom_command( - OUTPUT linux-crash-logger-stripped - COMMAND strip - ARGS --strip-debug -o linux-crash-logger-stripped linux-crash-logger - DEPENDS linux-crash-logger - ) - -add_custom_target(linux-crash-logger-strip-target ALL - DEPENDS linux-crash-logger-stripped) diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp deleted file mode 100644 index 97eec851b..000000000 --- a/indra/linux_crash_logger/linux_crash_logger.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file linux_crash_logger.cpp - * @brief Linux crash logger implementation - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llcrashloggerlinux.h" - -int main(int argc, char **argv) -{ - LLCrashLoggerLinux app; - app.parseCommandOptions(argc, argv); - app.init(); - app.mainLoop(); - app.cleanup(); - return 0; -} - - diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp deleted file mode 100644 index 039b70ec4..000000000 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file llcrashloggerlinux.cpp - * @brief Linux crash logger implementation - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llcrashloggerlinux.h" - -#include - -#include "linden_common.h" - -#include "boost/tokenizer.hpp" - -#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME -#include "llerror.h" -#include "llfile.h" -#include "lltimer.h" -#include "llstring.h" -#include "lldir.h" -#include "llsdserialize.h" - -#if LL_GTK -# include "gtk/gtk.h" -#endif // LL_GTK - -#define MAX_LOADSTRING 100 - -// These need to be localized. -static const char dialog_text[] = -"Second Life appears to have crashed or frozen last time it ran.\n" -"This crash reporter collects information about your computer's hardware, operating system, and some Second Life logs, all of which are used for debugging purposes only.\n" -"\n" -"Send crash report?"; - -static const char dialog_title[] = -"Second Life Crash Logger"; - -#if LL_GTK -static void response_callback (GtkDialog *dialog, - gint arg1, - gpointer user_data) -{ - gint *response = (gint*)user_data; - *response = arg1; - gtk_widget_destroy(GTK_WIDGET(dialog)); - gtk_main_quit(); -} -#endif // LL_GTK - -static BOOL do_ask_dialog(void) -{ -#if LL_GTK - gtk_disable_setlocale(); - if (!gtk_init_check(NULL, NULL)) { - llinfos << "Could not initialize GTK for 'ask to send crash report' dialog; not sending report." << llendl; - return FALSE; - } - - GtkWidget *win = NULL; - GtkDialogFlags flags = GTK_DIALOG_MODAL; - GtkMessageType messagetype = GTK_MESSAGE_QUESTION; - GtkButtonsType buttons = GTK_BUTTONS_YES_NO; - gint response = GTK_RESPONSE_NONE; - - win = gtk_message_dialog_new(NULL, - flags, messagetype, buttons, - "%s", dialog_text); - gtk_window_set_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); - gtk_window_set_title(GTK_WINDOW(win), dialog_title); - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - gtk_widget_show_all (win); - gtk_main(); - - return (GTK_RESPONSE_OK == response || - GTK_RESPONSE_YES == response || - GTK_RESPONSE_APPLY == response); -#else - return FALSE; -#endif // LL_GTK -} - -LLCrashLoggerLinux::LLCrashLoggerLinux(void) -{ -} - -LLCrashLoggerLinux::~LLCrashLoggerLinux(void) -{ -} - -void LLCrashLoggerLinux::gatherPlatformSpecificFiles() -{ - mFileMap["CrashLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log").c_str(); -} - -bool LLCrashLoggerLinux::mainLoop() -{ - bool send_logs = true; - if(CRASH_BEHAVIOR_ASK == getCrashBehavior()) - { - send_logs = do_ask_dialog(); - } - else if(CRASH_BEHAVIOR_NEVER_SEND == getCrashBehavior()) - { - send_logs = false; - } - - if(send_logs) - { - sendCrashLogs(); - } - return true; -} - -void LLCrashLoggerLinux::updateApplication(const std::string& message) -{ - LLCrashLogger::updateApplication(message); -} diff --git a/indra/linux_crash_logger/llcrashloggerlinux.h b/indra/linux_crash_logger/llcrashloggerlinux.h deleted file mode 100644 index 937d547f8..000000000 --- a/indra/linux_crash_logger/llcrashloggerlinux.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file llcrashloggerlinux.h - * @brief Linux crash logger definition - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLCRASHLOGGERLINUX_H -#define LLCRASHLOGGERLINUX_H - -#include "linden_common.h" -#include "llcrashlogger.h" -#include "llstring.h" - -class LLCrashLoggerLinux : public LLCrashLogger -{ -public: - LLCrashLoggerLinux(void); - ~LLCrashLoggerLinux(void); - virtual bool mainLoop(); - virtual void updateApplication(const std::string& = LLStringUtil::null); - virtual void gatherPlatformSpecificFiles(); -}; - -#endif diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt deleted file mode 100644 index 61191b37c..000000000 --- a/indra/llcrashlogger/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# -*- cmake -*- - -project(llcrashlogger) - -include(00-Common) -include(LLCommon) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLXML) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) - -set(llcrashlogger_SOURCE_FILES - llcrashlogger.cpp - llcrashlock.cpp - ) - -set(llcrashlogger_HEADER_FILES - CMakeLists.txt - - llcrashlogger.h - llcrashlock.h - ) - -set_source_files_properties(${llcrashlogger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES}) - -add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES}) -add_dependencies(llcrashlogger prepare) diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp deleted file mode 100644 index 82033f73e..000000000 --- a/indra/llcrashlogger/llcrashlock.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @file llformat.cpp - * @date January 2007 - * @brief string formatting utility - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llcrashlock.h" -#include "lldir.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llnametable.h" -#include "llframetimer.h" -#include -#include -#include -#include - - -#if LL_WINDOWS //For windows platform. -#include -#include - -/* -namespace { - inline DWORD getpid() { - return GetCurrentProcessId(); - } -} -*/ - -bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname) -{ - std::wstring wpname; - wpname = std::wstring(pname.begin(), pname.end()); - - HANDLE snapshot; - PROCESSENTRY32 pe32; - - bool matched = false; - - snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snapshot == INVALID_HANDLE_VALUE) - { - return false; - } - else - { - pe32.dwSize = sizeof(PROCESSENTRY32); - if (Process32First(snapshot, &pe32)) - { - do { - std::wstring wexecname = pe32.szExeFile; - std::string execname = std::string(wexecname.begin(), wexecname.end()); - if (!wpname.compare(pe32.szExeFile)) - { - if (pid == (U32)pe32.th32ProcessID) - { - matched = true; - break; - } - } - } while (Process32Next(snapshot, &pe32)); - } - } - - CloseHandle(snapshot); - return matched; -} - -#else //Everyone Else -bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname) -{ - //Will boost.process ever become a reality? - std::stringstream cmd; - - cmd << "pgrep '" << pname << "' | grep '^" << pid << "$'"; - return (!system(cmd.str().c_str())); -} -#endif //Everyone else. - - -LLCrashLock::LLCrashLock() : mCleanUp(true), mWaitingPID(0) -{ -} - -void LLCrashLock::setCleanUp(bool cleanup) -{ - mCleanUp = cleanup; //Allow cleanup to be disabled for debugging. -} - -LLSD LLCrashLock::getLockFile(std::string filename) -{ - LLSD lock_sd = LLSD::emptyMap(); - - llifstream ifile(filename); - - if (ifile.is_open()) - { - LLSDSerialize::fromXML(lock_sd, ifile); - ifile.close(); - } - - return lock_sd; -} - -bool LLCrashLock::putLockFile(std::string filename, const LLSD& data) -{ - bool result = true; - llofstream ofile(filename); - - if (!LLSDSerialize::toXML(data,ofile)) - { - result=false; - } - ofile.close(); - return result; -} - -bool LLCrashLock::requestMaster( F32 timeout ) -{ - if (mMaster.empty()) - { - mMaster = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "crash_master.lock"); - } - - LLSD lock_sd=getLockFile(mMaster); - - if (lock_sd.has("pid")) - { - mWaitingPID = lock_sd["pid"].asInteger(); - if ( isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()) ) - { - mTimer.resetWithExpiry(timeout); - return false; - } - } - - U32 pid = getpid(); - lock_sd["pid"] = (LLSD::Integer)pid; - return putLockFile(mMaster,lock_sd); -} - -bool LLCrashLock::checkMaster() -{ - if (mWaitingPID) - { - return (!isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename())); - } - return false; -} - -bool LLCrashLock::isWaiting() -{ - return !mTimer.hasExpired(); -} - -void LLCrashLock::releaseMaster() -{ - //Yeeeeeeehaw - unlink(mMaster.c_str()); -} - -LLSD LLCrashLock::getProcessList() -{ - if (mDumpTable.empty()) - { - mDumpTable= gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "crash_table.lock"); - } - return getLockFile(mDumpTable); -} - -//static -bool LLCrashLock::fileExists(std::string filename) -{ - return boost::filesystem::exists(filename.c_str()); -} - -void LLCrashLock::cleanupProcess(std::string proc_dir) -{ - boost::filesystem::remove_all(proc_dir); -} - -bool LLCrashLock::putProcessList(const LLSD& proc_sd) -{ - return putLockFile(mDumpTable,proc_sd); -} diff --git a/indra/llcrashlogger/llcrashlock.h b/indra/llcrashlogger/llcrashlock.h deleted file mode 100644 index cde183272..000000000 --- a/indra/llcrashlogger/llcrashlock.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file llpidlock.h - * @brief Maintainence of disk locking files for crash reporting - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_CRASHLOCK_H -#define LL_CRASHLOCK_H - -#include "llframetimer.h" - -class LLSD; - -#if !LL_WINDOWS //For non-windows platforms. -#include -#endif - -//Crash reporter will now be kicked off by the viewer but otherwise -//run independent of the viewer. - -class LLCrashLock -{ -public: - LLCrashLock(); - bool requestMaster( F32 timeout=300.0); //Wait until timeout for master lock. - bool checkMaster(); //True if available. False if not. - void releaseMaster( ); //Release master lockfile. - bool isLockPresent(std::string filename); //Check if lockfile exists. - bool isProcessAlive(U32 pid, const std::string& pname); //Check if pid is alive. - bool isWaiting(); //Waiting for master lock to be released. - LLSD getProcessList(); //Get next process pid/dir pairs - void cleanupProcess(std::string proc_dir); //Remove from list, clean up working dir. - bool putProcessList(const LLSD& processlist); //Write pid/dir pairs back to disk. - static bool fileExists(std::string filename); - - - //getters - S32 getPID(); - - //setters - void setCleanUp(bool cleanup=true); - void setSaveName(std::string savename); -private: - LLSD getLockFile(std::string filename); - bool putLockFile(std::string filename, const LLSD& data); - bool mCleanUp; - std::string mMaster; - std::string mDumpTable; - U32 mWaitingPID; //The process we're waiting on if any. - LLFrameTimer mTimer; -}; - -#endif // LL_CRASHLOCK_H diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt deleted file mode 100644 index daf3e1085..000000000 --- a/indra/mac_crash_logger/CMakeLists.txt +++ /dev/null @@ -1,76 +0,0 @@ -# -*- cmake -*- - -project(mac_crash_logger) - -include(00-Common) -include(LLCommon) -include(LLCrashLogger) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLXML) -include(Linking) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCRASHLOGGER_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) - -set(mac_crash_logger_SOURCE_FILES - mac_crash_logger.cpp - llcrashloggermac.cpp - ) - -set(mac_crash_logger_HEADER_FILES - CMakeLists.txt - - llcrashloggermac.h - ) - -set_source_files_properties(${mac_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) -list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_HEADER_FILES}) - -set(mac_crash_logger_RESOURCE_FILES - CrashReporter.nib/ - ) -set_source_files_properties( - ${mac_crash_logger_RESOURCE_FILES} - PROPERTIES - HEADER_FILE_ONLY TRUE - ) -SOURCE_GROUP("Resources" FILES ${mac_crash_logger_RESOURCE_FILES}) -list(APPEND mac_crash_logger_SOURCE_FILES ${mac_crash_logger_RESOURCE_FILES}) - -add_executable(mac-crash-logger - MACOSX_BUNDLE - ${mac_crash_logger_SOURCE_FILES}) - -set_target_properties(mac-crash-logger - PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist - ) - -target_link_libraries(mac-crash-logger - ${LLCRASHLOGGER_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) - -add_custom_command( - TARGET mac-crash-logger POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/CrashReporter.nib - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/mac-crash-logger.app/Contents/Resources/CrashReporter.nib - ) - diff --git a/indra/mac_crash_logger/CrashReporter.nib/classes.nib b/indra/mac_crash_logger/CrashReporter.nib/classes.nib deleted file mode 100644 index c4b887e72..000000000 --- a/indra/mac_crash_logger/CrashReporter.nib/classes.nib +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IBVersion - 1 - - diff --git a/indra/mac_crash_logger/CrashReporter.nib/info.nib b/indra/mac_crash_logger/CrashReporter.nib/info.nib deleted file mode 100644 index 06805c0e4..000000000 --- a/indra/mac_crash_logger/CrashReporter.nib/info.nib +++ /dev/null @@ -1,18 +0,0 @@ - - - - - IBFramework Version - 629 - IBLastKnownRelativeProjectPath - ../../build-darwin-i386/SecondLife.xcodeproj - IBOldestOS - 5 - IBOpenObjects - - IBSystem Version - 9E17 - targetFramework - IBCarbonFramework - - diff --git a/indra/mac_crash_logger/CrashReporter.nib/objects.xib b/indra/mac_crash_logger/CrashReporter.nib/objects.xib deleted file mode 100644 index 634d1c532..000000000 --- a/indra/mac_crash_logger/CrashReporter.nib/objects.xib +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - ok - Send Report - 414 273 434 378 - - - not! - 2 - Don't Send - 414 390 434 487 - - - Second Life appears to have crashed or frozen the last time it ran. This crash reporter collects information about your computer's hardware configuration, operating system, and some Second Life logs, all of which are used for debugging purposes only. In the space below, please briefly describe what you were doing or trying to do just prior to the crash. Thank you for your help! This report is NOT read by Customer Support. If you have billing or other questions, please go to: http://www.secondlife.com/support/ If you don't wish to send Linden Lab a crash report, press Cancel. - 20 20 231 487 - - - 2 - 3 - 7 - Second Life Crash Logger - - - - - - - text - TRUE - 242 23 391 484 - - - remb - Remember This Choice - 415 20 433 186 - - - 0 0 454 507 - - 257 653 711 1160 - 0 0 768 1024 - - - - - - - - - - - - - - - - CrashReporter - - File's Owner - - - IBCarbonFramework - 194 - diff --git a/indra/mac_crash_logger/Info.plist b/indra/mac_crash_logger/Info.plist deleted file mode 100644 index f48293e82..000000000 --- a/indra/mac_crash_logger/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - mac-crash-logger - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleIdentifier - com.secondlife.indra.crashreporter - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 1.0.0 - - diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp deleted file mode 100644 index 16efa4fe2..000000000 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/** - * @file llcrashloggermac.cpp - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - - -#include "llcrashloggermac.h" - -#include -#include -#include - -#include "boost/tokenizer.hpp" - -#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME -#include "llerror.h" -#include "llfile.h" -#include "lltimer.h" -#include "llstring.h" -#include "lldir.h" -#include "llsdserialize.h" - -#define MAX_LOADSTRING 100 -const char* const SETTINGS_FILE_HEADER = "version"; -const S32 SETTINGS_FILE_VERSION = 101; - -// Windows Message Handlers - -BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog? -LLFILE *gDebugFile = NULL; - -WindowRef gWindow = NULL; -EventHandlerRef gEventHandler = NULL; -std::string gUserNotes = ""; -bool gSendReport = false; -bool gRememberChoice = false; -IBNibRef nib = NULL; - -OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - 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) - { - //Get the value of the checkbox - ControlID id; - ControlRef checkBox = NULL; - id.signature = 'remb'; - id.id = 0; - err = GetControlByID(gWindow, &id, &checkBox); - - if(err == noErr) - { - if(GetControl32BitValue(checkBox) == kControlCheckBoxCheckedValue) - { - gRememberChoice = true; - } - else - { - gRememberChoice = false; - } - } - switch(cmd.commandID) - { - case kHICommandOK: - { - char buffer[65535]; /* Flawfinder: ignore */ - Size size = sizeof(buffer) - 1; - ControlRef textField = NULL; - - id.signature = 'text'; - id.id = 0; - - err = GetControlByID(gWindow, &id, &textField); - if(err == noErr) - { - // Get the user response text - err = GetControlData(textField, kControlNoPart, kControlEditTextTextTag, size, (Ptr)buffer, &size); - } - if(err == noErr) - { - // Make sure the string is terminated. - buffer[size] = 0; - gUserNotes = buffer; - - llinfos << buffer << llendl; - } - - // Send the report. - - QuitAppModalLoopForWindow(gWindow); - gSendReport = true; - result = noErr; - } - break; - - case kHICommandCancel: - QuitAppModalLoopForWindow(gWindow); - result = noErr; - break; - default: - result = eventNotHandledErr; - } - } - } - - return(result); -} - - -LLCrashLoggerMac::LLCrashLoggerMac(void) -{ -} - -LLCrashLoggerMac::~LLCrashLoggerMac(void) -{ -} - -bool LLCrashLoggerMac::init(void) -{ - bool ok = LLCrashLogger::init(); - if(!ok) return false; - if(mCrashBehavior != CRASH_BEHAVIOR_ASK) return true; - - // Real UI... - OSStatus err; - - err = CreateNibReference(CFSTR("CrashReporter"), &nib); - - if(err == noErr) - { - err = CreateWindowFromNib(nib, CFSTR("CrashReporter"), &gWindow); - } - - if(err == noErr) - { - // Set focus to the edit text area - ControlRef textField = NULL; - ControlID id; - - id.signature = 'text'; - id.id = 0; - - // Don't set err if any of this fails, since it's non-critical. - if(GetControlByID(gWindow, &id, &textField) == noErr) - { - SetKeyboardFocus(gWindow, textField, kControlFocusNextPart); - } - } - - if(err == noErr) - { - ShowWindow(gWindow); - } - - if(err == noErr) - { - // Set up an event handler for the window. - EventTypeSpec handlerEvents[] = - { - { kEventClassCommand, kEventCommandProcess } - }; - - InstallWindowEventHandler( - gWindow, - NewEventHandlerUPP(dialogHandler), - GetEventTypeCount (handlerEvents), - handlerEvents, - 0, - &gEventHandler); - } - return true; -} - -void LLCrashLoggerMac::gatherPlatformSpecificFiles() -{ - updateApplication("Gathering hardware information..."); - char path[MAX_PATH]; - FSRef folder; - - if(FSFindFolder(kUserDomain, kLogsFolderType, false, &folder) == noErr) - { - // folder is an FSRef to ~/Library/Logs/ - if(FSRefMakePath(&folder, (UInt8*)&path, sizeof(path)) == noErr) - { - struct stat dw_stat; - std::string mBuf; - bool isLeopard = false; - // Try the 10.3 path first... - std::string dw_file_name = std::string(path) + std::string("/CrashReporter/Second Life.crash.log"); - int res = stat(dw_file_name.c_str(), &dw_stat); - - if (res) - { - // Try the 10.2 one next... - dw_file_name = std::string(path) + std::string("/Second Life.crash.log"); - res = stat(dw_file_name.c_str(), &dw_stat); - } - - if(res) - { - //10.5: Like 10.3+, except it puts the crash time in the file instead of dividing it up - //using asterisks. Get a directory listing, search for files starting with second life, - //use the last one found. - std::string old_file_name, current_file_name, pathname, mask; - pathname = std::string(path) + std::string("/CrashReporter/"); - mask = "Second Life*"; - while(gDirUtilp->getNextFileInDir(pathname, mask, current_file_name, false)) - { - old_file_name = current_file_name; - } - if(old_file_name != "") - { - dw_file_name = pathname + old_file_name; - res=stat(dw_file_name.c_str(), &dw_stat); - isLeopard = true; - } - } - - if (!res) - { - std::ifstream fp(dw_file_name.c_str()); - std::stringstream str; - if(!fp.is_open()) return; - str << fp.rdbuf(); - mBuf = str.str(); - - if(!isLeopard) - { - // Crash logs consist of a number of entries, one per crash. - // Each entry is preceeded by "**********" on a line by itself. - // We want only the most recent (i.e. last) one. - const char *sep = "**********"; - const char *start = mBuf.c_str(); - const char *cur = start; - const char *temp = strstr(cur, sep); - - while(temp != NULL) - { - // Skip past the marker we just found - cur = temp + strlen(sep); /* Flawfinder: ignore */ - - // and try to find another - temp = strstr(cur, sep); - } - - // If there's more than one entry in the log file, strip all but the last one. - if(cur != start) - { - mBuf.erase(0, cur - start); - } - } - mCrashInfo["CrashLog"] = mBuf; - } - else - { - llwarns << "Couldn't find any CrashReporter files..." << llendl; - } - } - } -} - -bool LLCrashLoggerMac::mainLoop() -{ - OSStatus err = noErr; - - if(err == noErr && mCrashBehavior == CRASH_BEHAVIOR_ASK) - { - RunAppModalLoopForWindow(gWindow); - } - else if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) - { - gSendReport = true; - } - - if(gRememberChoice) - { - if(gSendReport) saveCrashBehaviorSetting(CRASH_BEHAVIOR_ALWAYS_SEND); - else saveCrashBehaviorSetting(CRASH_BEHAVIOR_NEVER_SEND); - } - - if(gSendReport) - { - setUserText(gUserNotes); - sendCrashLogs(); - } - - if(gWindow != NULL) - { - DisposeWindow(gWindow); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - - return true; -} - -void LLCrashLoggerMac::updateApplication(const std::string& message) -{ - LLCrashLogger::updateApplication(); -} - -bool LLCrashLoggerMac::cleanup() -{ - return true; -} diff --git a/indra/mac_crash_logger/llcrashloggermac.h b/indra/mac_crash_logger/llcrashloggermac.h deleted file mode 100644 index a76535afe..000000000 --- a/indra/mac_crash_logger/llcrashloggermac.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file llcrashloggermac.h - * @brief Mac OSX crash logger definition - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LLCRASHLOGGERMAC_H -#define LLCRASHLOGGERMAC_H - -#include "linden_common.h" -#include "llcrashlogger.h" -#include "llstring.h" - -class LLCrashLoggerMac : public LLCrashLogger -{ -public: - LLCrashLoggerMac(void); - ~LLCrashLoggerMac(void); - virtual bool init(); - virtual bool mainLoop(); - virtual void updateApplication(const std::string& message = LLStringUtil::null); - virtual bool cleanup(); - virtual void gatherPlatformSpecificFiles(); -}; - -#endif diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp deleted file mode 100644 index 1f5663d8a..000000000 --- a/indra/mac_crash_logger/mac_crash_logger.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @file mac_crash_logger.cpp - * @brief Mac OSX crash logger implementation - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llcrashloggermac.h" - -int main(int argc, char **argv) -{ - //time(&gLaunchTime); - - llinfos << "Starting Second Life Viewer Crash Reporter" << llendl; - - LLCrashLoggerMac app; - app.parseCommandOptions(argc, argv); - if(!app.init()) - { - return 0; - } - app.mainLoop(); - - return 0; -} diff --git a/indra/mac_updater/AutoUpdater.nib/classes.nib b/indra/mac_updater/AutoUpdater.nib/classes.nib deleted file mode 100644 index ea58db118..000000000 --- a/indra/mac_updater/AutoUpdater.nib/classes.nib +++ /dev/null @@ -1,4 +0,0 @@ -{ -IBClasses = (); -IBVersion = 1; -} diff --git a/indra/mac_updater/AutoUpdater.nib/info.nib b/indra/mac_updater/AutoUpdater.nib/info.nib deleted file mode 100644 index a49a92385..000000000 --- a/indra/mac_updater/AutoUpdater.nib/info.nib +++ /dev/null @@ -1,14 +0,0 @@ - - - - - IBDocumentLocation - 103 138 356 240 0 0 1280 1002 - IBFramework Version - 362.0 - IBSystem Version - 7D24 - targetFramework - IBCarbonFramework - - diff --git a/indra/mac_updater/AutoUpdater.nib/objects.xib b/indra/mac_updater/AutoUpdater.nib/objects.xib deleted file mode 100644 index 310411b71..000000000 --- a/indra/mac_updater/AutoUpdater.nib/objects.xib +++ /dev/null @@ -1,56 +0,0 @@ - - - IBCarbonFramework - - NSApplication - - - - 405 222 533 663 - Second Life Updater - - 0 0 128 441 - - - 20 20 44 421 - what - Initializing… - - - 88 351 108 421 - Cancel - not! - 2 - - - 51 19 70 422 - prog - 50 - - - - FALSE - 2 - 3 - 7 - - - - - - - - - - - - - - - File's Owner - - Updater - - - 194 - diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt deleted file mode 100644 index b769a2e17..000000000 --- a/indra/mac_updater/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -# -*- cmake -*- - -project(mac_updater) - -include(00-Common) -include(CURL) -include(LLCommon) -include(LLVFS) -include(Linking) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ) - -set(mac_updater_SOURCE_FILES - mac_updater.cpp - ) - -set(mac_updater_HEADER_FILES - CMakeLists.txt - ) - -set_source_files_properties(${mac_updater_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND mac_updater_SOURCE_FILES ${mac_updater_HEADER_FILES}) - - -set(mac_updater_RESOURCE_FILES - AutoUpdater.nib/ - ) -set_source_files_properties( - ${mac_updater_RESOURCE_FILES} - PROPERTIES - HEADER_FILE_ONLY TRUE - ) -SOURCE_GROUP("Resources" FILES ${mac_updater_RESOURCE_FILES}) -list(APPEND mac_updater_SOURCE_FILES ${mac_updater_RESOURCE_FILES}) - -add_executable(mac-updater - MACOSX_BUNDLE - ${mac_updater_SOURCE_FILES}) - -set_target_properties(mac-updater - PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist - ) - -target_link_libraries(mac-updater - ${LLVFS_LIBRARIES} - ${CURL_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) - -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 - ) - diff --git a/indra/mac_updater/Info.plist b/indra/mac_updater/Info.plist deleted file mode 100644 index bb27fddb0..000000000 --- a/indra/mac_updater/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - mac-updater - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleIdentifier - com.secondlife.indra.autoupdater - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 1.0.0 - - diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp deleted file mode 100644 index 0fd4615b4..000000000 --- a/indra/mac_updater/mac_updater.cpp +++ /dev/null @@ -1,1204 +0,0 @@ -/** - * @file mac_updater.cpp - * @brief - * - * $LicenseInfo:firstyear=2006&license=viewergpl$ - * - * Copyright (c) 2006-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include -#include -#include - -#include -#include - -#include "llerror.h" -#include "lltimer.h" -#include "lldir.h" -#include "llfile.h" - -#include "llstring.h" - -#include - -#include "llerrorcontrol.h" - -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; - -void *updatethreadproc(void*); - -pthread_t updatethread; - -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); - - } - - return(result); -} - -OSStatus dialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) -{ - 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); -} - -#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 - -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]; - } - } - - 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); - - ///////////////////////////////////////// - // - // Process command line arguments - // - gUpdateURL = NULL; - gProductName = NULL; - gBundleID = NULL; - parse_args(argc, argv); - if (!gUpdateURL) - { - llinfos << "Usage: mac_updater -url [-name ] [-program ]" << llendl; - exit(1); - } - else - { - llinfos << "Update url is: " << gUpdateURL << llendl; - if (gProductName) - { - llinfos << "Product name is: " << gProductName << llendl; - } - else - { - gProductName = "Second Life"; - } - if (gBundleID) - { - llinfos << "Bundle ID is: " << gBundleID << llendl; - } - else - { - gBundleID = "com.secondlife.indra.viewer"; - } - } - - 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 != noErr)) - { - // 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); - } - - } - - // Don't dispose of things, just exit. This keeps the update thread from potentially getting hosed. - exit(0); - - if(gWindow != NULL) - { - DisposeWindow(gWindow); - } - - if(nib != NULL) - { - DisposeNibReference(nib); - } - - return 0; -} - -bool isDirWritable(FSRef &dir) -{ - 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 */ - - err = FSRefMakePath(&dir, (UInt8*)temp, sizeof(temp)); - - 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); - } - } - -#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 - - return result; -} - -static std::string HFSUniStr255_to_utf8str(const HFSUniStr255* src) -{ - llutf16string string16((U16*)&(src->unicode), src->length); - std::string result = utf16str_to_utf8str(string16); - return result; -} - -int restoreObject(const char* aside, const char* target, const char* path, const char* object) -{ - 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; -} - -// Replace any mention of "Second Life" with the product name. -void filterFile(const char* filename) -{ - 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 */ -} - -static bool isFSRefViewerBundle(FSRef *targetRef) -{ - bool result = false; - CFURLRef targetURL = NULL; - CFBundleRef targetBundle = NULL; - CFStringRef targetBundleID = NULL; - CFStringRef sourceBundleID = NULL; - - targetURL = CFURLCreateFromFSRef(NULL, targetRef); - - if(targetURL == NULL) - { - llinfos << "Error creating target URL." << llendl; - } - 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; -} - -// 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) -{ - FSIterator iterator; - bool found = false; - - 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)) - { - // This is the one. Return it. - *app = ref; - found = true; - } - } - } - } - } - while(!err && !found); - - FSCloseIterator(iterator); - } - - if(!err && !found) - err = fnfErr; - - return err; -} - -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 */ - 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 - { - // 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 - - 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; - } - - 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; - FILE* mounter = popen("hdiutil attach SecondLife.dmg -mountpoint mnt", "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; - } - - err = findAppBundleOnDiskImage(&mountRef, &sourceRef); - if(err != noErr) - { - llinfos << "Couldn't find application bundle on mounted disk image." << llendl; - throw 0; - } - - 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) - 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) - if(gFailure == noErr) - gFailure = -1; - } - - // Failures from here on out are all non-fatal and not reported. - sendProgress(0, 3, CFSTR("Cleaning up...")); - - // 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) - { - llinfos << "Detaching disk image." << llendl; - - snprintf(temp, sizeof(temp), "hdiutil detach '%s'", deviceNode); - system(temp); /* Flawfinder: ignore */ - } - - sendProgress(2, 3); - - // Move work directory to the trash - if(tempDir[0] != 0) - { -// chdir("/"); -// FSDeleteObjects(tempDirRef); - - llinfos << "Moving work directory to the trash." << llendl; - - err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL); - -// snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir); -// printf("%s\n", temp); -// system(temp); - } - - if(!gCancelled && !gFailure && (target[0] != 0)) - { - llinfos << "Touching application bundle." << llendl; - - snprintf(temp, sizeof(temp), "touch '%s'", target); - system(temp); /* Flawfinder: ignore */ - - llinfos << "Launching updated application." << llendl; - - snprintf(temp, sizeof(temp), "open '%s'", target); - system(temp); /* Flawfinder: ignore */ - } - - sendDone(); - - return(NULL); -} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 74cbf25a0..6d16d66a1 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -140,6 +140,7 @@ set(viewer_SOURCE_FILES llcompilequeue.cpp llconfirmationmanager.cpp llconsole.cpp + llcrashlogger.cpp llcurrencyuimanager.cpp llcylinder.cpp lldaycyclemanager.cpp @@ -656,6 +657,7 @@ set(viewer_HEADER_FILES llcompilequeue.h llconfirmationmanager.h llconsole.h + llcrashlogger.h llcurrencyuimanager.h llcylinder.h lldaycyclemanager.h @@ -1532,7 +1534,6 @@ if (WINDOWS) if (PACKAGE) add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat) - add_dependencies(package windows-updater windows-crash-logger) endif (PACKAGE) endif (WINDOWS) @@ -1684,7 +1685,6 @@ if (DARWIN) if (PACKAGE) add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME}) - add_dependencies(package mac-updater mac-crash-logger) add_custom_command( TARGET package POST_BUILD diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ceed6ea95..9748e07a8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2199,7 +2199,7 @@ This should be as low as possible, but too low may break functionality Type String Value - + http://crash.singularityviewer.org/submit.php> AFKTimeout diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d4b3aa736..df48dc69a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -86,7 +86,7 @@ #include "llvocache.h" #include "llvopartgroup.h" #include "llfloaterteleporthistory.h" - +#include "llcrashlogger.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -640,6 +640,10 @@ bool LLAppViewer::init() initMaxHeapSize() ; LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")) ; + // Check if we have a crash report to send + LLCrashLogger crashLogger; + crashLogger.checkCrashDump(); + // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues. std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); mDumpPath = logdir; diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/newview/llcrashlogger.cpp similarity index 55% rename from indra/llcrashlogger/llcrashlogger.cpp rename to indra/newview/llcrashlogger.cpp index 97feae14c..862f69588 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/newview/llcrashlogger.cpp @@ -23,13 +23,9 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#include -#include -#include -#include +#include "llviewerprecompiledheaders.h" #include "llcrashlogger.h" -#include "llcrashlock.h" #include "linden_common.h" #include "llstring.h" #include "indra_constants.h" // CRASH_BEHAVIOR_... @@ -46,12 +42,6 @@ #include "llproxy.h" #include "aistatemachine.h" -LLPumpIO* gServicePump; -BOOL gBreak = false; -BOOL gSent = false; - -extern void startEngineThread(void); - class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy crashLoggerResponder_timeout; @@ -64,13 +54,12 @@ public: virtual void error(U32 status, const std::string& reason) { - gBreak = true; + llwarns << "Crash report sending failed: " << reason << llendl; } virtual void result(const LLSD& content) { - gBreak = true; - gSent = true; + llinfos << "Crash report successfully sent" << llendl; } virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const @@ -88,7 +77,6 @@ LLCrashLogger::LLCrashLogger() : mCrashBehavior(CRASH_BEHAVIOR_ALWAYS_SEND), mCrashInPreviousExec(false), mCrashSettings("CrashSettings"), - mSentCrashLogs(false), mCrashHost("") { } @@ -250,32 +238,6 @@ void LLCrashLogger::gatherFiles() gatherPlatformSpecificFiles(); - //Use the debug log to reconstruct the URL to send the crash report to - if(mDebugLog.has("CrashHostUrl")) - { - // Crash log receiver has been manually configured. - mCrashHost = mDebugLog["CrashHostUrl"].asString(); - } - else if(mDebugLog.has("CurrentSimHost")) - { - mCrashHost = "https://"; - mCrashHost += mDebugLog["CurrentSimHost"].asString(); - mCrashHost += ":12043/crash/report"; - } - else if(mDebugLog.has("GridName")) - { - // This is a 'little' hacky, but its the best simple solution. - std::string grid_host = mDebugLog["GridName"].asString(); - LLStringUtil::toLower(grid_host); - - mCrashHost = "https://login."; - mCrashHost += grid_host; - mCrashHost += ".lindenlab.com:12043/crash/report"; - } - - // Use login servers as the alternate, since they are already load balanced and have a known name - mAltCrashHost = "https://login.agni.lindenlab.com:12043/crash/report"; - mCrashInfo["DebugLog"] = mDebugLog; mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log"); @@ -354,80 +316,15 @@ LLSD LLCrashLogger::constructPostData() return mCrashInfo; } -// Singu Note, defiend in indra_constants.h # const char* const CRASH_SETTINGS_FILE = "settings_crash_behavior.xml"; - -S32 LLCrashLogger::loadCrashBehaviorSetting() -{ - // First check user_settings (in the user's home dir) - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); - if (! mCrashSettings.loadFromFile(filename)) - { - // Next check app_settings (in the SL program dir) - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, CRASH_SETTINGS_FILE); - mCrashSettings.loadFromFile(filename); - } - - // If we didn't load any files above, this will return the default - S32 value = mCrashSettings.getS32("CrashSubmitBehavior"); - - // Whatever value we got, make sure it's valid - switch (value) - { - case CRASH_BEHAVIOR_NEVER_SEND: - return CRASH_BEHAVIOR_NEVER_SEND; - case CRASH_BEHAVIOR_ALWAYS_SEND: - return CRASH_BEHAVIOR_ALWAYS_SEND; - } - - return CRASH_BEHAVIOR_ASK; -} - -bool LLCrashLogger::saveCrashBehaviorSetting(S32 crash_behavior) -{ - switch (crash_behavior) - { - case CRASH_BEHAVIOR_ASK: - case CRASH_BEHAVIOR_NEVER_SEND: - case CRASH_BEHAVIOR_ALWAYS_SEND: - break; - default: - return false; - } - - mCrashSettings.setS32("CrashSubmitBehavior", crash_behavior); - std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); - mCrashSettings.saveToFile(filename, FALSE); - - return true; -} - -bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout) -{ - gBreak = false; - for(int i = 0; i < retries; ++i) - { - updateApplication(llformat("%s, try %d...", msg.c_str(), i+1)); - LLHTTPClient::post(host, data, new LLCrashLoggerResponder()); - while(!gBreak) - { - updateApplication(); // No new message, just pump the IO - } - if(gSent) - { - return gSent; - } - } - return gSent; -} bool LLCrashLogger::sendCrashLog(std::string dump_dir) { gDirUtilp->setDumpDir( dump_dir ); std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - "SecondLifeCrashReport"); + "SingularityCrashReport"); std::string report_file = dump_path + ".log"; - + gatherFiles(); LLSD post_data; @@ -438,176 +335,30 @@ bool LLCrashLogger::sendCrashLog(std::string dump_dir) std::ofstream out_file(report_file.c_str()); LLSDSerialize::toPrettyXML(post_data, out_file); out_file.close(); - - bool sent = false; - - //*TODO: Translate - if(mCrashHost != "") - { - sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), 3, 5); - } - - if(!sent) - { - sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5); - } - - mSentCrashLogs = sent; - - return sent; -} -bool LLCrashLogger::sendCrashLogs() -{ + LLHTTPClient::post(mCrashHost, post_data, new LLCrashLoggerResponder()); - //pertinent code from below moved into a subroutine. - LLSD locks = mKeyMaster.getProcessList(); - LLSD newlocks = LLSD::emptyArray(); - - LLSD opts = getOptionData(PRIORITY_COMMAND_LINE); - LLSD rec; - - if ( opts.has("pid") && opts.has("dumpdir") && opts.has("procname") ) - { - rec["pid"]=opts["pid"]; - rec["dumpdir"]=opts["dumpdir"]; - rec["procname"]=opts["procname"]; -#if LL_WINDOWS - locks.append(rec); -#endif - } - - if (locks.isArray()) - { - for (LLSD::array_iterator lock=locks.beginArray(); - lock !=locks.endArray(); - ++lock) - { - if ( (*lock).has("pid") && (*lock).has("dumpdir") && (*lock).has("procname") ) - { - if ( mKeyMaster.isProcessAlive( (*lock)["pid"].asInteger(), (*lock)["procname"].asString() ) ) - { - newlocks.append(*lock); - } - else - { - //TODO: This is a hack but I didn't want to include boost in another file or retest everything related to lldir - if (LLCrashLock::fileExists((*lock)["dumpdir"].asString())) - { - //the viewer cleans up the log directory on clean shutdown - //but is ignorant of the locking table. - if (!sendCrashLog((*lock)["dumpdir"].asString())) - { - newlocks.append(*lock); //Failed to send log so don't delete it. - } - else - { - mCrashInfo["DebugLog"].erase("MinidumpPath"); - - mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString()); - } - } - } - } - else - { - llwarns << "Discarding corrupted entry from lock table." << llendl; - } - } - } -#if !LL_WINDOWS - if (rec) - { - newlocks.append(rec); - } -#endif - - mKeyMaster.putProcessList(newlocks); - return true; -} - -void LLCrashLogger::updateApplication(const std::string& message) -{ - /* Sing TODO - gServicePump->pump(); - gServicePump->callback(); - */ - if (!message.empty()) llinfos << message << llendl; -} - -bool LLCrashLogger::init() -{ - LLCurl::initCurl(); - AIEngine::setMaxCount(100); - - // 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, "")); - - // Default to the product name "Second Life" (this is overridden by the -name argument) - mProductName = "Second Life"; - - // Handle locking - bool locked = mKeyMaster.requestMaster(); //Request maser locking file. wait time is defaulted to 300S - - while (!locked && mKeyMaster.isWaiting()) - { -#if LL_WINDOWS - Sleep(1000); -#else - sleep(1); -#endif - locked = mKeyMaster.checkMaster(); - } - - if (!locked) - { - llwarns << "Unable to get master lock. Another crash reporter may be hung." << llendl; - return false; - } - - // Rename current log file to ".old" - std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old"); - std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log"); - -#if LL_WINDOWS - LLAPRFile::remove(old_log_file); -#endif - - LLFile::rename(log_file.c_str(), old_log_file.c_str()); - - // Set the log file to crashreport.log - LLError::logToFile(log_file); - - mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND, - "Controls behavior when viewer crashes " - "(0 = ask before sending crash report, " - "1 = always send crash report, " - "2 = never send crash report)"); - - llinfos << "Loading crash behavior setting" << llendl; - mCrashBehavior = loadCrashBehaviorSetting(); - - // If user doesn't want to send, bail out - if (mCrashBehavior == CRASH_BEHAVIOR_NEVER_SEND) - { - llinfos << "Crash behavior is never_send, quitting" << llendl; - return false; - } - - AICurlInterface::startCurlThread(&mCrashSettings); - startEngineThread(); - /* Singu Note: not needed for AICurl - gServicePump = new LLPumpIO(gAPRPoolp); - gServicePump->prime(gAPRPoolp); - LLHTTPClient::setPump(*gServicePump); - */ return true; } -// For cleanup code common to all platforms. -void LLCrashLogger::commonCleanup() + +void LLCrashLogger::updateApplication(const std::string& message) { - LLProxy::cleanupClass(); + if (!message.empty()) llinfos << message << llendl; +} + + +void LLCrashLogger::checkCrashDump() +{ + mCrashHost = gSavedSettings.getString("CrashHostUrl"); + std::string dumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "") + "singularity-debug"; + if (gDirUtilp->fileExists(dumpDir)) + { + sendCrashLog(dumpDir); + gDirUtilp->deleteDirAndContents(dumpDir); + } + else + { + llinfos << "No crash dump found frome previous run, not sending report" << LL_ENDL; + } } diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/newview/llcrashlogger.h similarity index 85% rename from indra/llcrashlogger/llcrashlogger.h rename to indra/newview/llcrashlogger.h index 78acc63b6..e23d5330c 100644 --- a/indra/llcrashlogger/llcrashlogger.h +++ b/indra/newview/llcrashlogger.h @@ -33,9 +33,8 @@ #include "llapp.h" #include "llsd.h" #include "llcontrol.h" -#include "llcrashlock.h" -class LLCrashLogger : public LLApp +class LLCrashLogger { public: LLCrashLogger(); @@ -48,17 +47,12 @@ public: virtual void gatherPlatformSpecificFiles() {} bool saveCrashBehaviorSetting(S32 crash_behavior); bool sendCrashLog(std::string dump_dir); - bool sendCrashLogs(); LLSD constructPostData(); virtual void updateApplication(const std::string& message = LLStringUtil::null); - virtual bool init(); - virtual bool mainLoop() = 0; - virtual bool cleanup() = 0; - void commonCleanup(); void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; } S32 getCrashBehavior() { return mCrashBehavior; } - bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout); bool readMinidump(std::string minidump_path); + void checkCrashDump(); protected: S32 mCrashBehavior; @@ -69,10 +63,7 @@ protected: std::string mProductName; LLSD mCrashInfo; std::string mCrashHost; - std::string mAltCrashHost; LLSD mDebugLog; - bool mSentCrashLogs; - LLCrashLock mKeyMaster; }; #endif //LLCRASHLOGGER_H diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 437916c94..44f7dddca 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -339,10 +339,6 @@ class WindowsManifest(ViewerManifest): self.path(path_pair[1]) self.end_prefix() - # pull in the crash logger and updater from other projects - self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], dst="win_crash_logger.exe") - self.path(src='../win_updater/%s/windows-updater.exe' % self.args['configuration'], dst="updater.exe") - def nsi_file_commands(self, install=True): def wpath(path): @@ -545,18 +541,10 @@ class DarwinManifest(ViewerManifest): print "Skipping libfmodex.dylib - not found" pass - # our apps - try: - self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app") - self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app") - except: - pass - # plugin launcher self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin.app", "SLPlugin.app") # dependencies on shared libs - mac_crash_logger_res_path = self.dst_path_of("mac-crash-logger.app/Contents/Resources") slplugin_res_path = self.dst_path_of("SLPlugin.app/Contents/Resources") for libfile in ("libllcommon.dylib", "libapr-1.0.dylib", @@ -717,10 +705,8 @@ class LinuxManifest(ViewerManifest): if self.buildtype().lower()=='release': self.path("secondlife-stripped","bin/"+self.binary_name()) - self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin") else: self.path("secondlife-bin","bin/"+self.binary_name()) - self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin") if self.prefix("res-sdl"): diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt deleted file mode 100644 index 1f31db0b8..000000000 --- a/indra/win_crash_logger/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -# -*- cmake -*- - -project(win_crash_logger) - -include(00-Common) -include(LLCommon) -include(LLCrashLogger) -include(LLMath) -include(LLMessage) -include(LLVFS) -include(LLWindow) -include(LLXML) -include(Linking) -include(LLSharedLibs) -include(GoogleBreakpad) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCRASHLOGGER_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLVFS_INCLUDE_DIRS} - ${BREAKPAD_INCLUDE_DIRECTORIES} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - -set(win_crash_logger_SOURCE_FILES - win_crash_logger.cpp - llcrashloggerwindows.cpp - ) - -set(win_crash_logger_HEADER_FILES - CMakeLists.txt - - llcrashloggerwindows.h - resource.h - StdAfx.h - win_crash_logger.h - ) - -set_source_files_properties(${win_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -set(win_crash_logger_RESOURCE_FILES - ll_icon.ico - ) - -set_source_files_properties(${win_crash_logger_RESOURCE_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -set(win_crash_logger_RESOURCE_FILES - win_crash_logger.rc - ${win_crash_logger_RESOURCE_FILES} - ) - -SOURCE_GROUP("Resource Files" FILES ${win_crash_logger_RESOURCE_FILES}) - -list(APPEND - win_crash_logger_SOURCE_FILES - ${win_crash_logger_HEADER_FILES} - ${win_crash_logger_RESOURCE_FILES} - ) - -# find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR}) - -add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES}) - -target_link_libraries(windows-crash-logger - ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} - ${LLCRASHLOGGER_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${WINDOWS_LIBRARIES} -# ${DXGUID_LIBRARY} - ${GOOGLE_PERFTOOLS_LIBRARIES} - user32 - gdi32 - ole32 - oleaut32 - wininet - Wldap32 - ) - -if (WINDOWS) - set_target_properties(windows-crash-logger - PROPERTIES - LINK_FLAGS "/NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" - ) -endif (WINDOWS) - -# Singu Note: not used by our build -# ll_deploy_sharedlibs_command(windows-crash-logger) diff --git a/indra/win_crash_logger/StdAfx.cpp b/indra/win_crash_logger/StdAfx.cpp deleted file mode 100644 index f56711af7..000000000 --- a/indra/win_crash_logger/StdAfx.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file StdAfx.cpp - * @brief windows crash logger source file for includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - -// stdafx.cpp : source file that includes just the standard includes -// win_crash_logger.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/indra/win_crash_logger/StdAfx.h b/indra/win_crash_logger/StdAfx.h deleted file mode 100644 index 35976658a..000000000 --- a/indra/win_crash_logger/StdAfx.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @file StdAfx.h - * @brief standard system includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) -#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -// Windows Header Files: -#include - -// C RunTime Header Files -#include -#include -#include - -// Local Header Files - -// TODO: reference additional headers your program requires here - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/indra/win_crash_logger/ll_icon.ico b/indra/win_crash_logger/ll_icon.ico deleted file mode 100644 index 566346dfe..000000000 Binary files a/indra/win_crash_logger/ll_icon.ico and /dev/null differ diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp deleted file mode 100644 index e9102b725..000000000 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/** -* @file llcrashloggerwindows.cpp -* @brief Windows crash logger implementation -* -* $LicenseInfo:firstyear=2003&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - -#include "linden_common.h" - -#include "stdafx.h" -#include "resource.h" -#include "llcrashloggerwindows.h" - -#include - -#include "boost/tokenizer.hpp" - -#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME -#include "llerror.h" -#include "llfile.h" -#include "lltimer.h" -#include "llstring.h" -#include "lldxhardware.h" -#include "lldir.h" -#include "llsdserialize.h" -#include "llsdutil.h" - -#include -#include - -#define MAX_LOADSTRING 100 -#define MAX_STRING 2048 -const char* const SETTINGS_FILE_HEADER = "version"; -const S32 SETTINGS_FILE_VERSION = 101; - -// Windows Message Handlers - -// Global Variables: -HINSTANCE hInst= NULL; // current instance -TCHAR szTitle[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text -TCHAR szWindowClass[MAX_LOADSTRING]; /* Flawfinder: ignore */ // The title bar text - -std::string gProductName; -HWND gHwndReport = NULL; // Send/Don't Send dialog -HWND gHwndProgress = NULL; // Progress window -HCURSOR gCursorArrow = NULL; -HCURSOR gCursorWait = NULL; -BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialog? -std::stringstream gDXInfo; -bool gSendLogs = false; - -LLCrashLoggerWindows* LLCrashLoggerWindows::sInstance = NULL; - -//Conversion from char* to wchar* -//Replacement for ATL macros, doesn't allocate memory -//For more info see: http://www.codeguru.com/forum/showthread.php?t=337247 -void ConvertLPCSTRToLPWSTR (const char* pCstring, WCHAR* outStr) -{ - if (pCstring != NULL) - { - int nInputStrLen = strlen (pCstring); - // Double NULL Termination - int nOutputStrLen = MultiByteToWideChar(CP_ACP, 0, pCstring, nInputStrLen, NULL, 0) + 2; - if (outStr) - { - memset (outStr, 0x00, sizeof (WCHAR)*nOutputStrLen); - MultiByteToWideChar (CP_ACP, 0, pCstring, nInputStrLen, outStr, nInputStrLen); - } - } -} - -void write_debug(const char *str) -{ - gDXInfo << str; /* Flawfinder: ignore */ -} - -void write_debug(std::string& str) -{ - write_debug(str.c_str()); -} - -void show_progress(const std::string& message) -{ - std::wstring msg = wstring_to_utf16str(utf8str_to_wstring(message)); - if (gHwndProgress) - { - SendDlgItemMessage(gHwndProgress, // handle to destination window - IDC_LOG, - WM_SETTEXT, // message to send - FALSE, // undo option - (LPARAM)msg.c_str()); - } -} - -void update_messages() -{ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - exit(0); - } - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -void sleep_and_pump_messages( U32 seconds ) -{ - const U32 CYCLES_PER_SECOND = 10; - U32 cycles = seconds * CYCLES_PER_SECOND; - while( cycles-- ) - { - update_messages(); - ms_sleep(1000 / CYCLES_PER_SECOND); - } -} - -// Include product name in the window caption. -void LLCrashLoggerWindows::ProcessCaption(HWND hWnd) -{ - TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */ - TCHAR header[MAX_STRING]; - std::string final; - GetWindowText(hWnd, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); - ConvertLPCSTRToLPWSTR(final.c_str(), header); - SetWindowText(hWnd, header); -} - - -// Include product name in the diaog item text. -void LLCrashLoggerWindows::ProcessDlgItemText(HWND hWnd, int nIDDlgItem) -{ - TCHAR templateText[MAX_STRING]; /* Flawfinder: ignore */ - TCHAR header[MAX_STRING]; - std::string final; - GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText)); - final = llformat(ll_convert_wide_to_string(templateText, CP_ACP).c_str(), gProductName.c_str()); - ConvertLPCSTRToLPWSTR(final.c_str(), header); - SetDlgItemText(hWnd, nIDDlgItem, header); -} - -bool handle_button_click(WORD button_id) -{ - // Is this something other than Send or Don't Send? - if (button_id != IDOK - && button_id != IDCANCEL) - { - return false; - } - - // See if "do this next time" is checked and save state - S32 crash_behavior = CRASH_BEHAVIOR_ASK; - LRESULT result = SendDlgItemMessage(gHwndReport, IDC_CHECK_AUTO, BM_GETCHECK, 0, 0); - if (result == BST_CHECKED) - { - if (button_id == IDOK) - { - crash_behavior = CRASH_BEHAVIOR_ALWAYS_SEND; - } - else if (button_id == IDCANCEL) - { - crash_behavior = CRASH_BEHAVIOR_NEVER_SEND; - } - ((LLCrashLoggerWindows*)LLCrashLogger::instance())->saveCrashBehaviorSetting(crash_behavior); - } - - // We're done with this dialog. - gFirstDialog = FALSE; - - // Send the crash report if requested - if (button_id == IDOK) - { - gSendLogs = TRUE; - WCHAR wbuffer[20000]; - GetDlgItemText(gHwndReport, // handle to dialog box - IDC_EDIT1, // control identifier - wbuffer, // pointer to buffer for text - 20000 // maximum size of string - ); - std::string user_text(ll_convert_wide_to_string(wbuffer, CP_ACP)); - // Activate and show the window. - ShowWindow(gHwndProgress, SW_SHOW); - // Try doing this second to make the progress window go frontmost. - ShowWindow(gHwndReport, SW_HIDE); - ((LLCrashLoggerWindows*)LLCrashLogger::instance())->setUserText(user_text); - ((LLCrashLoggerWindows*)LLCrashLogger::instance())->sendCrashLogs(); - } - // Quit the app - LLApp::setQuitting(); - return true; -} - - -LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) -{ - switch( message ) - { - case WM_CREATE: - return 0; - - case WM_COMMAND: - if( gFirstDialog ) - { - WORD button_id = LOWORD(wParam); - bool handled = handle_button_click(button_id); - if (handled) - { - return 0; - } - } - break; - - case WM_DESTROY: - // Closing the window cancels - LLApp::setQuitting(); - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hwnd, message, wParam, lParam); -} - - -LLCrashLoggerWindows::LLCrashLoggerWindows(void) -{ - if (LLCrashLoggerWindows::sInstance==NULL) - { - sInstance = this; - } -} - -LLCrashLoggerWindows::~LLCrashLoggerWindows(void) -{ - sInstance = NULL; -} - -bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to) -{ - bool res; - const int timerID=37; - SetTimer(NULL, timerID, to, NULL); - res = GetMessage(msg, NULL, 0, 0); - KillTimer(NULL, timerID); - if (!res) - return false; - if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == 1) - return false; //TIMEOUT! You could call SetLastError() or something... - return true; -} - -int LLCrashLoggerWindows::processingLoop() { - const int millisecs=1000; - static int first_connect = 1; - - LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE ); - - MSG msg; - - bool result; - - while (1) - { - result = getMessageWithTimeout(&msg, millisecs); - if ( result ) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - if (first_connect ) - { - if ( mClientsConnected > 0) - { - first_connect = 0; - } - } - else - { - if (mClientsConnected == 0) - { - break; - } - if (!mKeyMaster.isProcessAlive(mPID, mProcName) ) - { - break; - } - } - } - - llinfos << "session ending.." << llendl; - - llinfos << "clients connected :" << mClientsConnected << llendl; - - return 0; -} - - -void LLCrashLoggerWindows::OnClientConnected(void* context, - const google_breakpad::ClientInfo* client_info) -{ - llinfos << "client start. pid = " << client_info->pid() << llendl; - sInstance->mClientsConnected++; - -} - -void LLCrashLoggerWindows::OnClientExited(void* context, - const google_breakpad::ClientInfo* client_info) -{ - llinfos << "client end. pid = " << client_info->pid() << llendl; - sInstance->mClientsConnected--; -} - -/* -void LLCrashLoggerWindows::OnClientDumpRequest(void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path) -{ - ProcessingLock lock; - - if (!file_path) - { - llwarns << "dump with no file path" << llendl; - return; - } - if (!client_info) - { - llwarns << "dump with no client info" << llendl; - return; - } - - LLCrashLoggerWindows* self = static_cast(context); - if (!self) - { - llwarns << "dump with no context" << llendl; - return; - } - - DWORD pid = client_info->pid(); - - -// Send the crash dump using a worker thread. This operation has retry -// logic in case there is no internet connection at the time. -DumpJobInfo* dump_job = new DumpJobInfo(pid, self, map, -dump_location.value()); -if (!::QueueUserWorkItem(&CrashService::AsyncSendDump, -dump_job, WT_EXECUTELONGFUNCTION)) { -LOG(ERROR) << "could not queue job"; -} -} -*/ - -bool LLCrashLoggerWindows::initCrashServer() -{ - //For Breakpad on Windows we need a full Out of Process service to get good data. - //This routine starts up the service on a named pipe that the viewer will then - //communicate with. - using namespace google_breakpad; - - LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE ); - std::string dump_path = options["dumpdir"].asString(); - mClientsConnected = 0; - mPID = options["pid"].asInteger(); - mProcName = options["procname"].asString(); - - std::wostringstream ws; - //Generate a quasi-uniq name for the named pipe. For our purposes - //this is unique-enough with least hassle. Worst case for duplicate name - //is a second instance of the viewer will not do crash reporting. - ws << mCrashReportPipeStr << mPID; - std::wstring wpipe_name = ws.str(); - - std::wstring wdump_path; - wdump_path.assign(dump_path.begin(), dump_path.end()); - - //Pipe naming conventions: http://msdn.microsoft.com/en-us/library/aa365783%28v=vs.85%29.aspx - mCrashHandler = new CrashGenerationServer( (WCHAR *)wpipe_name.c_str(), - NULL, - &LLCrashLoggerWindows::OnClientConnected, this, - NULL, NULL, // &LLCrashLoggerWindows::OnClientDumpRequest, this, - &LLCrashLoggerWindows::OnClientExited, this, - NULL, NULL, - true, &wdump_path); - - if (!mCrashHandler) { - //Failed to start the crash server. - llwarns << "Failed to init crash server." << llendl; - return false; - } - - // Start servicing clients. - if (!mCrashHandler->Start()) { - llwarns << "Failed to start crash server." << llendl; - return false; - } - - return true; -} - -bool LLCrashLoggerWindows::init(void) -{ - initCrashServer(); - bool ok = LLCrashLogger::init(); - if(!ok) return false; - - /* - mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) ); - gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0; - swprintf(gProductName, L"Second Life"); - */ - - llinfos << "Loading dialogs" << llendl; - - // Initialize global strings - LoadString(mhInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); - LoadString(mhInst, IDC_WIN_CRASH_LOGGER, szWindowClass, MAX_LOADSTRING); - - gCursorArrow = LoadCursor(NULL, IDC_ARROW); - gCursorWait = LoadCursor(NULL, IDC_WAIT); - - // Register a window class that will be used by our dialogs - WNDCLASS wndclass; - wndclass.style = CS_HREDRAW | CS_VREDRAW; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = DLGWINDOWEXTRA; // Required, since this is used for dialogs! - wndclass.hInstance = mhInst; - wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE( IDI_WIN_CRASH_LOGGER ) ); - wndclass.hCursor = gCursorArrow; - wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = szWindowClass; - RegisterClass( &wndclass ); - - return true; -} - -void LLCrashLoggerWindows::gatherPlatformSpecificFiles() -{ - updateApplication("Gathering hardware information. App may appear frozen."); - // DX hardware probe blocks, so we can't cancel during it - //Generate our dx_info.log file - SetCursor(gCursorWait); - // At this point we're responsive enough the user could click the close button - SetCursor(gCursorArrow); - //mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); //Not initialized. -} - -bool LLCrashLoggerWindows::mainLoop() -{ - llinfos << "CrashSubmitBehavior is " << mCrashBehavior << llendl; - // Note: parent hwnd is 0 (the desktop). No dlg proc. See Petzold (5th ed) HexCalc example, Chapter 11, p529 - // win_crash_logger.rc has been edited by hand. - // Dialogs defined with CLASS "WIN_CRASH_LOGGER" (must be same as szWindowClass) - gProductName = mProductName; - gHwndProgress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS), 0, NULL); - ProcessCaption(gHwndProgress); - ShowWindow(gHwndProgress, SW_HIDE ); - - if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND) - { - llinfos << "Showing crash report submit progress window." << llendl; - ShowWindow(gHwndProgress, SW_SHOW ); - sendCrashLogs(); - } - else if (mCrashBehavior == CRASH_BEHAVIOR_ASK) - { - gHwndReport = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PREVREPORTBOX), 0, NULL); - // Ignore result - (void) SendDlgItemMessage(gHwndReport, IDC_CHECK_AUTO, BM_SETCHECK, 0, 0); - // Include the product name in the caption and various dialog items. - ProcessCaption(gHwndReport); - ProcessDlgItemText(gHwndReport, IDC_STATIC_MSG); - - // Update the header to include whether or not we crashed on the last run. - std::string headerStr; - TCHAR header[MAX_STRING]; - if (mCrashInPreviousExec) - { - headerStr = llformat("%s appears to have crashed or frozen the last time it ran.", mProductName.c_str()); - } - else - { - headerStr = llformat("%s appears to have crashed.", mProductName.c_str()); - } - ConvertLPCSTRToLPWSTR(headerStr.c_str(), header); - SetDlgItemText(gHwndReport, IDC_STATIC_HEADER, header); - ShowWindow(gHwndReport, SW_SHOW ); - - MSG msg; - memset(&msg, 0, sizeof(msg)); - while (!LLApp::isQuitting() && GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return msg.wParam; - } - else - { - llwarns << "Unknown crash behavior " << mCrashBehavior << llendl; - return 1; - } - return 0; -} - -void LLCrashLoggerWindows::updateApplication(const std::string& message) -{ - LLCrashLogger::updateApplication(message); - if(!message.empty()) show_progress(message); - update_messages(); -} - -bool LLCrashLoggerWindows::cleanup() -{ - if(gSendLogs) - { - if(mSentCrashLogs) show_progress("Done"); - else show_progress("Could not connect to servers, logs not sent"); - sleep_and_pump_messages(3); - } - PostQuitMessage(0); - commonCleanup(); - mKeyMaster.releaseMaster(); - return true; -} - diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h deleted file mode 100644 index 85cafd54c..000000000 --- a/indra/win_crash_logger/llcrashloggerwindows.h +++ /dev/null @@ -1,86 +0,0 @@ -/** -* @file llcrashloggerwindows.h -* @brief Windows crash logger definition -* -* $LicenseInfo:firstyear=2003&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2010, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - -#ifndef LLCRASHLOGGERWINDOWS_H -#define LLCRASHLOGGERWINDOWS_H - -#include "llcrashlogger.h" -#include "windows.h" -#include "llstring.h" - -class LLSD; - -namespace google_breakpad { - class CrashGenerationServer; - class ClientInfo; -} - -class LLCrashLoggerWindows : public LLCrashLogger -{ -public: - LLCrashLoggerWindows(void); - ~LLCrashLoggerWindows(void); - static LLCrashLoggerWindows* sInstance; - - virtual bool init(); - virtual bool mainLoop(); - virtual void updateApplication(const std::string& message = LLStringUtil::null); - virtual bool cleanup(); - virtual void gatherPlatformSpecificFiles(); - void setHandle(HINSTANCE hInst) { mhInst = hInst; } - int clients_connected() const { - return mClientsConnected; - } - bool getMessageWithTimeout(MSG *msg, UINT to); - - // Starts the processing loop. This function does not return unless the - // user is logging off or the user closes the crash service window. The - // return value is a good number to pass in ExitProcess(). - int processingLoop(); -private: - void ProcessDlgItemText(HWND hWnd, int nIDDlgItem); - void ProcessCaption(HWND hWnd); - bool initCrashServer(); - google_breakpad::CrashGenerationServer* mCrashHandler; - static void OnClientConnected(void* context, - const google_breakpad::ClientInfo* client_info); - - /*static void OnClientDumpRequest( - void* context, - const google_breakpad::ClientInfo* client_info, - const std::wstring* file_path);*/ - - static void OnClientExited(void* context, - const google_breakpad::ClientInfo* client_info); - int mClientsConnected; - int mPID; - std::string mProcName; - - HINSTANCE mhInst; - -}; - -#endif diff --git a/indra/win_crash_logger/resource.h b/indra/win_crash_logger/resource.h deleted file mode 100644 index 37a387275..000000000 --- a/indra/win_crash_logger/resource.h +++ /dev/null @@ -1,63 +0,0 @@ -/** -* @file resource.h -* @brief Windows crash logger windows resources -* -* $LicenseInfo:firstyear=2003&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$ -*/ - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by win_crash_logger.rc -// -#define IDC_MYICON 2 -#define IDD_REPORT 9 -#define IDD_WIN_CRASH_LOGGER_DIALOG 102 -#define IDD_ABOUTBOX 103 -#define IDS_APP_TITLE 103 -#define IDM_ABOUT 104 -#define IDM_EXIT 105 -#define IDS_HELLO 106 -#define IDI_WIN_CRASH_LOGGER 107 -#define IDI_SMALL 108 -#define IDC_WIN_CRASH_LOGGER 109 -#define IDR_MAINFRAME 128 -#define IDD_PROGRESS 129 -#define IDD_PREVREPORTBOX 130 -#define IDC_EDIT1 1000 -#define IDC_LOG 1004 -#define IDC_CHECK_AUTO 1006 -#define IDC_STATIC_HEADER 1007 -#define IDC_STATIC_WHATINFO 1008 -#define IDC_STATIC_MOTIVATION 1009 -#define IDC_STATIC_MSG 1010 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 131 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 1011 -#define _APS_NEXT_SYMED_VALUE 110 -#endif -#endif diff --git a/indra/win_crash_logger/snowglobe_icon.ico b/indra/win_crash_logger/snowglobe_icon.ico deleted file mode 100644 index 8ed0fede1..000000000 Binary files a/indra/win_crash_logger/snowglobe_icon.ico and /dev/null differ diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp deleted file mode 100644 index e25e12834..000000000 --- a/indra/win_crash_logger/win_crash_logger.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/** - * @file win_crash_logger.cpp - * @brief Windows crash logger implementation - * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "stdafx.h" -#include -#include "llcrashloggerwindows.h" -#include - - -int APIENTRY WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) -{ - llinfos << "Starting crash reporter." << llendl; - LLCrashLoggerWindows app; - app.setHandle(hInstance); - app.parseCommandOptions(__argc, __argv); - - LLSD options = LLApp::instance()->getOptionData( - LLApp::PRIORITY_COMMAND_LINE); - if (!(options.has("pid") && options.has("dumpdir"))) - { - llwarns << "Insufficient parameters to crash report." << llendl; - } - if (! app.init()) - { - llwarns << "Unable to initialize application." << llendl; - return 1; - } - - app.processingLoop(); - app.mainLoop(); - app.cleanup(); - llinfos << "Crash reporter finished normally." << llendl; - return 0; -} diff --git a/indra/win_crash_logger/win_crash_logger.h b/indra/win_crash_logger/win_crash_logger.h deleted file mode 100644 index 2cc2cf3dc..000000000 --- a/indra/win_crash_logger/win_crash_logger.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file win_crash_logger.h - * @brief Windows crash logger project includes - * - * $LicenseInfo:firstyear=2003&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$ - */ - - -#if !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_) -#define AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#include "resource.h" - - -#endif // !defined(AFX_WIN_CRASH_LOGGER_H__79802F4B_7C37_4F63_A2BB_0768788C3A27__INCLUDED_) diff --git a/indra/win_crash_logger/win_crash_logger.ico b/indra/win_crash_logger/win_crash_logger.ico deleted file mode 100644 index 386883523..000000000 Binary files a/indra/win_crash_logger/win_crash_logger.ico and /dev/null differ diff --git a/indra/win_crash_logger/win_crash_logger.rc b/indra/win_crash_logger/win_crash_logger.rc deleted file mode 100644 index 2819722f6..000000000 --- a/indra/win_crash_logger/win_crash_logger.rc +++ /dev/null @@ -1,188 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -#include "resource.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_WIN_CRASH_LOGGER ICON "ll_icon.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDC_WIN_CRASH_LOGGER MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "E&xit", IDM_EXIT - END - POPUP "&Help" - BEGIN - MENUITEM "&About ...", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_PROGRESS DIALOGEX 100, 100, 234, 33 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - LTEXT "Static",IDC_LOG,7,7,220,8 -END - -IDD_REPORT DIALOGEX 100, 100, 297, 125 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Send",IDOK,198,104,45,15,WS_GROUP - PUSHBUTTON "Don't Send",IDCANCEL,247,104,45,15,WS_GROUP - LTEXT "%s appears to have crashed.",IDC_STATIC_HEADER,4,4,288,14 - LTEXT "This crash reporter collects information about your computer's hardware, operating system, and some %s logs, which are used for debugging purposes only.",IDC_STATIC_WHATINFO,4,23,288,19,NOT WS_GROUP - CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,106,89,13 - LTEXT "Sending crash reports is the best way to help us improve the quality of %s.",IDC_STATIC_MOTIVATION,4,43,288,8 - LTEXT "If you continue to experience this problem, please try:",IDC_STATIC,4,57,251,8 - LTEXT "- Contacting support by visiting http://www.secondlife.com/support",IDC_STATIC,4,67,231,8 -END - -IDD_PREVREPORTBOX DIALOGEX 100, 100, 232, 213 -STYLE DS_SETFONT | DS_SETFOREGROUND | WS_CAPTION | WS_SYSMENU -CAPTION "%s Crash Logger" -CLASS "WIN_CRASH_LOGGER" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Send Report",IDOK,131,193,45,15,WS_GROUP - EDITTEXT IDC_EDIT1,3,100,223,89,ES_MULTILINE | ES_WANTRETURN | WS_VSCROLL - PUSHBUTTON "Don't Send",IDCANCEL,181,193,45,15,WS_GROUP - LTEXT "%s appears to have crashed or frozen the last time it ran.",IDC_STATIC_HEADER,4,4,214,8 - LTEXT "This crash reporter collects information about your computer's",IDC_STATIC,4,17,201,8 - LTEXT "hardware configuration, operating system, and some %s",IDC_STATIC_MSG,4,25,212,8 - LTEXT "logs, all of which are used for debugging purposes only.",IDC_STATIC,4,33,210,8 - LTEXT "In the space below, please briefly describe what you were doing",IDC_STATIC,3,48,208,8 - LTEXT "or trying to do just prior to the crash.",IDC_STATIC,3,56,204,8 - LTEXT "If you don't wish to send Linden Lab a crash report, press Don't Send.",IDC_STATIC,3,90,223,8 - LTEXT "This report is NOT read by customer support. If you have billing or",IDC_STATIC,3,68,208,8 - LTEXT "other questions, please go to: www.secondlife.com/support",IDC_STATIC,3,76,206,8 - CONTROL "Remember this choice",IDC_CHECK_AUTO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,193,89,13 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resource.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_PROGRESS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 227 - TOPMARGIN, 7 - BOTTOMMARGIN, 26 - END - - IDD_REPORT, DIALOG - BEGIN - RIGHTMARGIN, 292 - VERTGUIDE, 4 - BOTTOMMARGIN, 119 - HORZGUIDE, 4 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_APP_TITLE "win_crash_logger" - IDS_HELLO "Hello World!" - IDC_WIN_CRASH_LOGGER "WIN_CRASH_LOGGER" -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/indra/win_updater/CMakeLists.txt b/indra/win_updater/CMakeLists.txt deleted file mode 100644 index dedb7cfcc..000000000 --- a/indra/win_updater/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -# -*- cmake -*- - -project(win_updater) - -include(00-Common) -include(LLCommon) -include(Linking) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ) - -set(win_updater_SOURCE_FILES updater.cpp) - -set(win_updater_HEADER_FILES CMakeLists.txt) - -set_source_files_properties(${win_updater_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND win_updater_SOURCE_FILES ${win_updater_HEADER_FILES}) - -add_executable(windows-updater WIN32 ${win_updater_SOURCE_FILES}) - -target_link_libraries(windows-updater - wininet - user32 - gdi32 - shell32 - ) - -set_target_properties(windows-updater - PROPERTIES - LINK_FLAGS "/NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" - ) diff --git a/indra/win_updater/updater.cpp b/indra/win_updater/updater.cpp deleted file mode 100644 index 3937351d7..000000000 --- a/indra/win_updater/updater.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/** - * @file updater.cpp - * @brief Windows auto-updater - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -// -// Usage: updater -url -// - -// We use dangerous fopen, strtok, mbstowcs, sprintf -// which generates warnings on VC2005. -// *TODO: Switch to fopen_s, strtok_s, etc. -#define _CRT_SECURE_NO_DEPRECATE - -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSIZE 8192 - -int gTotalBytesRead = 0; -DWORD gTotalBytes = -1; -HWND gWindow = NULL; -WCHAR gProgress[256]; -char* gUpdateURL = NULL; - -#if _DEBUG -std::ofstream logfile; -#define DEBUG(expr) logfile << expr << std::endl -#else -#define DEBUG(expr) /**/ -#endif - -char* wchars_to_utf8chars(const WCHAR* in_chars) -{ - int tlen = 0; - const WCHAR* twc = in_chars; - while (*twc++ != 0) - { - tlen++; - } - char* outchars = new char[tlen]; - char* res = outchars; - for (int i=0; i - static RESULT check(const std::string& desc, RESULT result) - { - if (result) - { - // success, show caller - return result; - } - DWORD err = GetLastError(); - std::ostringstream out; - out << desc << " Failed: " << err; - DEBUG(out.str()); - throw InetError(out.str()); - } - - HINTERNET openUrl(const std::wstring& uri) const; - HINTERNET openInet() const; - - HINTERNET mInet, mDownload; -}; - -HINTERNET Fetcher::openInet() const -{ - DEBUG("Calling InternetOpen"); - // Init wininet subsystem - return check("InternetOpen", - InternetOpen(L"LindenUpdater", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0)); -} - -HINTERNET Fetcher::openUrl(const std::wstring& uri) const -{ - DEBUG("Calling InternetOpenUrl: " << wchars_to_utf8chars(uri.c_str())); - return check("InternetOpenUrl", - InternetOpenUrl(mInet, uri.c_str(), NULL, 0, INTERNET_FLAG_NEED_FILE, NULL)); -} - -unsigned long Fetcher::read(char* buffer, size_t bufflen) const -{ - unsigned long bytes_read = 0; - DEBUG("Calling InternetReadFile"); - check("InternetReadFile", - InternetReadFile(mDownload, buffer, bufflen, &bytes_read)); - return bytes_read; -} - -int WINAPI get_url_into_file(const std::wstring& uri, const std::string& path, int *cancelled) -{ - int success = FALSE; - *cancelled = FALSE; - - DEBUG("Opening '" << path << "'"); - - FILE* fp = fopen(path.c_str(), "wb"); /* Flawfinder: ignore */ - - if (!fp) - { - DEBUG("Failed to open '" << path << "'"); - return success; - } - - // Note, ctor can throw, since it uses check() function. - Fetcher fetcher(uri); - gTotalBytes = fetcher.getTotalBytes(); - -/*==========================================================================*| - // nobody uses total_bytes?!? What's this doing here? - DWORD total_bytes = 0; - success = check("InternetQueryDataAvailable", - InternetQueryDataAvailable(hdownload, &total_bytes, 0, 0)); -|*==========================================================================*/ - - success = FALSE; - while(!success && !(*cancelled)) - { - char data[BUFSIZE]; /* Flawfinder: ignore */ - unsigned long bytes_read = fetcher.read(data, sizeof(data)); - - if (!bytes_read) - { - DEBUG("InternetReadFile Read " << bytes_read << " bytes."); - } - - DEBUG("Reading Data, bytes_read = " << bytes_read); - - if (bytes_read == 0) - { - // If InternetFileRead returns TRUE AND bytes_read == 0 - // we've successfully downloaded the entire file - wsprintf(gProgress, L"Download complete."); - success = TRUE; - } - else - { - // write what we've got, then continue - fwrite(data, sizeof(char), bytes_read, fp); - - gTotalBytesRead += int(bytes_read); - - if (gTotalBytes != -1) - wsprintf(gProgress, L"Downloaded: %d%%", 100 * gTotalBytesRead / gTotalBytes); - else - wsprintf(gProgress, L"Downloaded: %dK", gTotalBytesRead / 1024); - - } - - DEBUG("Calling InvalidateRect"); - - // Mark the window as needing redraw (of the whole thing) - InvalidateRect(gWindow, NULL, TRUE); - - // Do the redraw - DEBUG("Calling UpdateWindow"); - UpdateWindow(gWindow); - - DEBUG("Calling PeekMessage"); - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - { - // bail out, user cancelled - *cancelled = TRUE; - } - } - } - - fclose(fp); - return success; -} - -LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) -{ - HDC hdc; // Drawing context - PAINTSTRUCT ps; - - switch(message) - { - case WM_PAINT: - { - hdc = BeginPaint(hwnd, &ps); - - RECT rect; - GetClientRect(hwnd, &rect); - DrawText(hdc, gProgress, -1, &rect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER); - - EndPaint(hwnd, &ps); - return 0; - } - case WM_CLOSE: - case WM_DESTROY: - // Get out of full screen - // full_screen_mode(false); - PostQuitMessage(0); - return 0; - } - return DefWindowProc(hwnd, message, wparam, lparam); -} - -#define win_class_name L"FullScreen" - -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]; - } - } - - // If nothing was set, let the caller know. - if (!gUpdateURL) - { - return 1; - } - return 0; -} - -int WINAPI -WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - // Parse the command line. - LPSTR cmd_line_including_exe_name = GetCommandLineA(); - - const int MAX_ARGS = 100; - int argc = 0; - char* argv[MAX_ARGS]; /* Flawfinder: ignore */ - -#if _DEBUG - logfile.open("updater.log", std::ios_base::out); - DEBUG("Parsing command arguments"); -#endif - - char *token = NULL; - if( cmd_line_including_exe_name[0] == '\"' ) - { - // Exe name is enclosed in quotes - token = strtok( cmd_line_including_exe_name, "\"" ); - argv[argc++] = token; - token = strtok( NULL, " \t," ); - } - else - { - // Exe name is not enclosed in quotes - token = strtok( cmd_line_including_exe_name, " \t," ); - } - - while( (token != NULL) && (argc < MAX_ARGS) ) - { - argv[argc++] = token; - /* Get next token: */ - if (*(token + strlen(token) + 1) == '\"') /* Flawfinder: ignore */ - { - token = strtok( NULL, "\""); - } - else - { - token = strtok( NULL, " \t," ); - } - } - - gUpdateURL = NULL; - - ///////////////////////////////////////// - // - // Process command line arguments - // - - DEBUG("Processing command arguments"); - - // - // Parse the command line arguments - // - int parse_args_result = parse_args(argc, argv); - - WNDCLASSEX wndclassex = { 0 }; - //DEVMODE dev_mode = { 0 }; - - const int WINDOW_WIDTH = 250; - const int WINDOW_HEIGHT = 100; - - wsprintf(gProgress, L"Connecting..."); - - /* Init the WNDCLASSEX */ - wndclassex.cbSize = sizeof(WNDCLASSEX); - wndclassex.style = CS_HREDRAW | CS_VREDRAW; - wndclassex.hInstance = hInstance; - wndclassex.lpfnWndProc = WinProc; - wndclassex.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); - wndclassex.lpszClassName = win_class_name; - - RegisterClassEx(&wndclassex); - - // Get the size of the screen - //EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode); - - gWindow = CreateWindowEx(NULL, win_class_name, - L"Second Life Updater", - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - WINDOW_WIDTH, - WINDOW_HEIGHT, - NULL, NULL, hInstance, NULL); - - ShowWindow(gWindow, nShowCmd); - UpdateWindow(gWindow); - - if (parse_args_result) - { - MessageBox(gWindow, - L"Usage: updater -url [-name ] [-program ] [-silent]", - L"Usage", MB_OK); - return parse_args_result; - } - - // Did we get a userserver to work with? - if (!gUpdateURL) - { - MessageBox(gWindow, L"Please specify the download url from the command line", - L"Error", MB_OK); - return 1; - } - - // Can't feed GetTempPath into GetTempFile directly - char temp_path[MAX_PATH]; /* Flawfinder: ignore */ - if (0 == GetTempPathA(sizeof(temp_path), temp_path)) - { - MessageBox(gWindow, L"Problem with GetTempPath()", - L"Error", MB_OK); - return 1; - } - std::string update_exec_path(temp_path); - update_exec_path.append("Second_Life_Updater.exe"); - - WCHAR update_uri[4096]; - mbstowcs(update_uri, gUpdateURL, sizeof(update_uri)); - - int success = 0; - int cancelled = 0; - - // Actually do the download - try - { - DEBUG("Calling get_url_into_file"); - success = get_url_into_file(update_uri, update_exec_path, &cancelled); - } - catch (const Fetcher::InetError& e) - { - (void)e; - success = FALSE; - DEBUG("Caught: " << e.what()); - } - - // WinInet can't tell us if we got a 404 or not. Therefor, we check - // for the size of the downloaded file, and assume that our installer - // will always be greater than 1MB. - if (gTotalBytesRead < (1024 * 1024) && ! cancelled) - { - MessageBox(gWindow, - L"The Second Life auto-update has failed.\n" - L"The problem may be caused by other software installed \n" - L"on your computer, such as a firewall.\n" - L"Please visit http://secondlife.com/download/ \n" - L"to download the latest version of Second Life.\n", - NULL, MB_OK); - return 1; - } - - if (cancelled) - { - // silently exit - return 0; - } - - if (!success) - { - MessageBox(gWindow, - L"Second Life download failed.\n" - L"Please try again later.", - NULL, MB_OK); - return 1; - } - - // TODO: Make updates silent (with /S to NSIS) - //char params[256]; /* Flawfinder: ignore */ - //sprintf(params, "/S"); /* Flawfinder: ignore */ - //MessageBox(gWindow, - // L"Updating Second Life.\n\nSecond Life will automatically start once the update is complete. This may take a minute...", - // L"Download Complete", - // MB_OK); - -/*==========================================================================*| - // DEV-31680: ShellExecuteA() causes McAfee-GW-Edition and AntiVir - // scanners to flag this executable as a probable virus vector. - // Less than or equal to 32 means failure - if (32 >= (int) ShellExecuteA(gWindow, "open", update_exec_path.c_str(), NULL, - "C:\\", SW_SHOWDEFAULT)) -|*==========================================================================*/ - // from http://msdn.microsoft.com/en-us/library/ms682512(VS.85).aspx - STARTUPINFOA si; - PROCESS_INFORMATION pi; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - - if (! CreateProcessA(update_exec_path.c_str(), // executable file - NULL, // command line - NULL, // process cannot be inherited - NULL, // thread cannot be inherited - FALSE, // do not inherit existing handles - 0, // process creation flags - NULL, // inherit parent's environment - NULL, // inherit parent's current dir - &si, // STARTUPINFO - &pi)) // PROCESS_INFORMATION - { - MessageBox(gWindow, L"Update failed. Please try again later.", NULL, MB_OK); - return 1; - } - - // Give installer some time to open a window - Sleep(1000); - - return 0; -}