summaryrefslogtreecommitdiff
path: root/indra/win_crash_logger/win_crash_logger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/win_crash_logger/win_crash_logger.cpp')
-rw-r--r--indra/win_crash_logger/win_crash_logger.cpp874
1 files changed, 23 insertions, 851 deletions
diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp
index 266940741b..c6b4ff1c34 100644
--- a/indra/win_crash_logger/win_crash_logger.cpp
+++ b/indra/win_crash_logger/win_crash_logger.cpp
@@ -35,98 +35,22 @@
// Must be first include, precompiled headers.
#include "stdafx.h"
-#include "linden_common.h"
-#include "llcontrol.h"
-#include "resource.h"
+#include <stdlib.h>
-#include <direct.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <wininet.h>
+#include "llcrashloggerwindows.h"
-#include "indra_constants.h" // CRASH_BEHAVIOR_ASK, CRASH_SETTING_NAME
-#include "llerror.h"
-#include "lltimer.h"
-#include "lldir.h"
-#include "llstring.h"
-#include "lldxhardware.h"
-
-LLControlGroup gCrashSettings; // saved at end of session
-
-// Constants
-#define MAX_LOADSTRING 100
-const char* const SETTINGS_FILE_HEADER = "version";
-const S32 SETTINGS_FILE_VERSION = 101;
-
-// Functions
-LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
-bool handle_button_click(WORD button_id);
-S32 load_crash_behavior_setting();
-bool save_crash_behavior_setting(S32 crash_behavior);
-void send_crash_report();
-void write_debug(const char *str);
-void write_debug(std::string& str);
-
-// 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
-
-LLString gUserText; // User's description of the problem
-time_t gStartTime = 0;
-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?
-BOOL gCrashInPreviousExec = FALSE;
-FILE *gDebugFile = NULL;
-LLString gUserserver;
-WCHAR gProductName[512];
//
// Implementation
//
-// Include product name in the window caption.
-void ProcessCaption(HWND hWnd)
-{
- TCHAR templateText[1024]; /* Flawfinder: ignore */
- TCHAR finalText[2048]; /* Flawfinder: ignore */
- GetWindowText(hWnd, templateText, sizeof(templateText));
- swprintf(finalText, templateText, gProductName); /* Flawfinder: ignore */
- SetWindowText(hWnd, finalText);
-}
-
-
-// Include product name in the diaog item text.
-void ProcessDlgItemText(HWND hWnd, int nIDDlgItem)
-{
- TCHAR templateText[1024]; /* Flawfinder: ignore */
- TCHAR finalText[2048]; /* Flawfinder: ignore */
- GetDlgItemText(hWnd, nIDDlgItem, templateText, sizeof(templateText));
- swprintf(finalText, templateText, gProductName); /* Flawfinder: ignore */
- SetDlgItemText(hWnd, nIDDlgItem, finalText);
-}
-
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
llinfos << "Starting crash reporter" << llendl;
- // We assume that all the logs we're looking for reside on the current drive
- gDirUtilp->initAppDirs("SecondLife");
-
- // Default to the product name "Second Life" (this is overridden by the -name argument)
- swprintf(gProductName, L"Second Life"); /* Flawfinder: ignore */
-
- gCrashSettings.declareS32(CRASH_BEHAVIOR_SETTING, CRASH_BEHAVIOR_ASK, "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;
- S32 crash_behavior = load_crash_behavior_setting();
// In Win32, we need to generate argc and argv ourselves...
// Note: GetCommandLine() returns a potentially return a LPTSTR
@@ -139,7 +63,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
const S32 MAX_ARGS = 100;
int argc = 0;
- char *argv[MAX_ARGS]; /* Flawfinder: ignore */
+ char *argv[MAX_ARGS];
char *token = NULL;
if( cmd_line_including_exe_name[0] == '\"' )
@@ -159,7 +83,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
{
argv[argc++] = token;
/* Get next token: */
- if (*(token + strlen(token) + 1) == '\"') /* Flawfinder: ignore */
+ if (*(token + strlen(token) + 1) == '\"')
{
token = strtok( NULL, "\"");
}
@@ -169,784 +93,32 @@ int APIENTRY WinMain(HINSTANCE hInstance,
}
}
- S32 i;
- for (i=0; i<argc; i++)
- {
- if(!strcmp(argv[i], "-previous"))
- {
- llinfos << "Previous execution did not remove SecondLife.exec_marker" << llendl;
- gCrashInPreviousExec = TRUE;
- }
-
- if(!strcmp(argv[i], "-dialog"))
- {
- llinfos << "Show the user dialog" << llendl;
- crash_behavior = CRASH_BEHAVIOR_ASK;
- }
-
- if(!strcmp(argv[i], "-user"))
- {
- if ((i + 1) < argc)
- {
- i++;
- gUserserver = argv[i];
- llinfos << "Got userserver " << gUserserver << llendl;
- }
- }
-
- if(!strcmp(argv[i], "-name"))
- {
- if ((i + 1) < argc)
- {
- i++;
-
- mbstowcs(gProductName, argv[i], sizeof(gProductName)/sizeof(gProductName[0]));
- gProductName[ sizeof(gProductName)/sizeof(gProductName[0]) - 1 ] = 0;
- llinfos << "Got product name " << argv[i] << llendl;
- }
- }
- }
-
- // If user doesn't want to send, bail out
- if (crash_behavior == CRASH_BEHAVIOR_NEVER_SEND)
- {
- llinfos << "Crash behavior is never_send, quitting" << llendl;
- return 0;
- }
-
- // Get the current time
- time(&gStartTime);
-
- llinfos << "Loading dialogs" << llendl;
-
- // Store instance handle in our global variable
- hInst = hInstance;
-
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, 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 = hInst;
- 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 );
-
- // 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)
-
- gHwndProgress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS), 0, NULL);
- ProcessCaption(gHwndProgress);
- ShowWindow(gHwndProgress, SW_HIDE );
-
- if (crash_behavior == CRASH_BEHAVIOR_ALWAYS_SEND)
- {
- ShowWindow(gHwndProgress, SW_SHOW );
- send_crash_report();
- return 0;
- }
-
- if (crash_behavior == CRASH_BEHAVIOR_ASK)
- {
- gHwndReport = CreateDialog(hInst, MAKEINTRESOURCE(IDD_REPORT), 0, NULL);
-
- // Include the product name in the caption and various dialog items.
- ProcessCaption(gHwndReport);
- ProcessDlgItemText(gHwndReport, IDC_STATIC_WHATINFO);
- ProcessDlgItemText(gHwndReport, IDC_STATIC_MOTIVATION);
-
- // Update the header to include whether or not we crashed on the last run.
- WCHAR header[2048];
- if (gCrashInPreviousExec)
- {
- swprintf(header, L"%s appears to have crashed or frozen the last time it ran.", gProductName); /* Flawfinder: ignore */
- }
- else
- {
- swprintf(header, L"%s appears to have crashed.", gProductName); /* Flawfinder: ignore */
- }
- SetDlgItemText(gHwndReport, IDC_STATIC_HEADER, header);
- ShowWindow(gHwndReport, SW_SHOW );
-
- MSG msg;
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- else
- {
- llwarns << "Unknown crash behavior " << crash_behavior << llendl;
- return 1;
- }
-}
-
-
-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
- PostQuitMessage(0);
- return 0;
- }
-
- return DefWindowProc(hwnd, message, wParam, lParam);
-}
-
-
-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;
- }
- }
- bool success = save_crash_behavior_setting(crash_behavior);
- if (!success)
- {
- llwarns << "Failed to save crash settings" << llendl;
- }
-
- // We're done with this dialog.
- gFirstDialog = FALSE;
-
- // Send the crash report if requested
- if (button_id == IDOK)
- {
- // Don't let users type anything. They believe the reports
- // get read by humans, and get angry when we don't respond. JC
- //WCHAR wbuffer[20000];
- //GetDlgItemText(gHwndReport, // handle to dialog box
- // IDC_EDIT1, // control identifier
- // wbuffer, // pointer to buffer for text
- // 20000 // maximum size of string
- // );
- //gUserText = wstring_to_utf8str(utf16str_to_wstring(wbuffer)).c_str();
- //llinfos << gUserText << llendl;
-
- // Activate and show the window.
- ShowWindow(gHwndProgress, SW_SHOW);
- // Try doing this second to make the progress window go frontmost.
- ShowWindow(gHwndReport, SW_HIDE);
-
- send_crash_report();
- }
-
- // Quit the app
- PostQuitMessage(0);
-
- return true;
-}
-
-
-class LLFileEncoder
-{
-public:
- LLFileEncoder(const char *formname, const char *filename);
- ~LLFileEncoder();
-
- BOOL isValid() const { return mIsValid; }
- LLString encodeURL(const S32 max_length = 0);
-public:
- BOOL mIsValid;
- LLString mFilename;
- LLString mFormname;
- S32 mBufLength;
- U8 *mBuf;
-};
-
-LLString encode_string(const char *formname, const LLString &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-- )
+ LLCrashLoggerWindows app;
+ bool ok = app.parseCommandOptions(argc, argv);
+ if(!ok)
{
- update_messages();
- ms_sleep(1000 / CYCLES_PER_SECOND);
- }
-}
-
-
-void show_progress(const char* 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 send_crash_report()
-{
- update_messages();
- show_progress("Starting up...");
- update_messages();
-
- const S32 SL_MAX_SIZE = 100000; // Maximum size of the Second Life log file.
-
- update_messages();
-
- // Lots of silly variable, replicated for each log file.
- std::string db_file_name; // debug.log
- std::string sl_file_name; // SecondLife.log
- std::string md_file_name; // minidump (SecondLife.dmp) file name
- std::string st_file_name; // stats.log file
- std::string si_file_name; // settings.ini file
- std::string ml_file_name; // message.log file
-
- LLFileEncoder *db_filep = NULL;
- LLFileEncoder *sl_filep = NULL;
- LLFileEncoder *st_filep = NULL;
- LLFileEncoder *md_filep = NULL;
- LLFileEncoder *si_filep = NULL;
- LLFileEncoder *ml_filep = NULL;
-
- // DX hardware probe blocks, so we can't cancel during it
- SetCursor(gCursorWait);
-
- // Need to do hardware detection before we grab the files, otherwise we don't send the debug log updates
- // to the server (including the list of hardware).
- update_messages();
- show_progress("Detecting hardware, please wait...");
- update_messages();
- gDXHardware.setWriteDebugFunc(write_debug);
- gDXHardware.getInfo(FALSE);
- update_messages();
- gDXHardware.dumpDevices();
- update_messages();
- fclose(gDebugFile);
- gDebugFile = NULL;
-
- // At this point we're responsive enough the user could click the close button
- SetCursor(gCursorArrow);
-
- ///////////////////////////////////
- //
- // We do the parsing for the debug_info file first, as that will
- // give us the location of the SecondLife.log file.
- //
-
- // Figure out the filename of the debug log
- db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
- db_filep = new LLFileEncoder("DB", db_file_name.c_str());
-
- // Get the filename of the SecondLife.log file
- // *NOTE: This buffer size is hard coded into scanf() below.
- char tmp_sl_name[256]; /* Flawfinder: ignore */
- tmp_sl_name[0] = '\0';
-
- update_messages();
- show_progress("Looking for files...");
- update_messages();
-
- // Look for it in the debug_info.log file
- if (db_filep->isValid())
- {
- sscanf(
- (const char*)db_filep->mBuf,
- "SL Log: %255[^\r\n]",
- tmp_sl_name);
- }
- else
- {
- delete db_filep;
- db_filep = NULL;
- }
-
- if (gCrashInPreviousExec)
- {
- // If we froze, the crash log this time around isn't useful. Use the
- // old one.
- sl_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old");
- }
- else if (tmp_sl_name[0])
- {
- // If debug_info.log gives us a valid log filename, use that.
- sl_file_name = tmp_sl_name;
- llinfos << "Using log file from debug log " << sl_file_name << llendl;
- }
- else
- {
- // Figure out the filename of the default second life log
- sl_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
- }
-
- // Now we get the SecondLife.log file if it's there
- sl_filep = new LLFileEncoder("SL", sl_file_name.c_str());
- if (!sl_filep->isValid())
- {
- delete sl_filep;
- sl_filep = NULL;
- }
-
- update_messages();
- show_progress("Looking for stats file...");
- update_messages();
-
- st_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
- st_filep = new LLFileEncoder("ST", st_file_name.c_str());
- if (!st_filep->isValid())
- {
- delete st_filep;
- st_filep = NULL;
- }
-
- si_file_name = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.ini");
- si_filep = new LLFileEncoder("SI", si_file_name.c_str());
- if (!si_filep->isValid())
- {
- delete si_filep;
- si_filep = NULL;
- }
-
- // Now we get the minidump
- md_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.dmp");
- md_filep = new LLFileEncoder("MD", md_file_name.c_str());
- if (!md_filep->isValid())
- {
- delete md_filep;
- md_filep = NULL;
- }
-
- // Now we get the message log
- ml_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"message.log");
- ml_filep = new LLFileEncoder("ML", ml_file_name.c_str());
- if (!ml_filep->isValid())
- {
- delete ml_filep;
- ml_filep = NULL;
- }
-
- LLString post_data;
- LLString tmp_url_buf;
-
- // Append the userserver
- tmp_url_buf = encode_string("USER", gUserserver);
- post_data += tmp_url_buf;
- llinfos << "PostData:" << post_data << llendl;
-
- if (gCrashInPreviousExec)
- {
- post_data.append(1, '&');
- tmp_url_buf = encode_string("EF", "Y");
- post_data += tmp_url_buf;
- }
-
- update_messages();
- show_progress("Encoding data");
- update_messages();
- if (db_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = db_filep->encodeURL();
- post_data += tmp_url_buf;
- llinfos << "Sending DB log file" << llendl;
- }
- else
- {
- llinfos << "Not sending DB log file" << llendl;
- }
- show_progress("Encoding data.");
- update_messages();
-
- if (sl_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = sl_filep->encodeURL(SL_MAX_SIZE);
- post_data += tmp_url_buf;
- llinfos << "Sending SL log file" << llendl;
- }
- else
- {
- llinfos << "Not sending SL log file" << llendl;
- }
- show_progress("Encoding data..");
- update_messages();
-
- if (st_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = st_filep->encodeURL(SL_MAX_SIZE);
- post_data += tmp_url_buf;
- llinfos << "Sending stats log file" << llendl;
- }
- else
- {
- llinfos << "Not sending stats log file" << llendl;
- }
- show_progress("Encoding data...");
- update_messages();
-
- if (md_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = md_filep->encodeURL();
- post_data += tmp_url_buf;
- llinfos << "Sending minidump log file" << llendl;
- }
- else
- {
- llinfos << "Not sending minidump log file" << llendl;
- }
- show_progress("Encoding data....");
- update_messages();
-
- if (si_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = si_filep->encodeURL();
- post_data += tmp_url_buf;
- llinfos << "Sending settings log file" << llendl;
- }
- else
- {
- llinfos << "Not sending settings.ini file" << llendl;
- }
- show_progress("Encoding data....");
- update_messages();
-
- if (ml_filep)
- {
- post_data.append(1, '&');
- tmp_url_buf = ml_filep->encodeURL(SL_MAX_SIZE);
- post_data += tmp_url_buf;
- llinfos << "Sending message log file" << llendl;
- }
- else
- {
- llinfos << "Not sending message.log file" << llendl;
- }
- show_progress("Encoding data....");
- update_messages();
-
- if (gUserText.size())
- {
- post_data.append(1, '&');
- tmp_url_buf = encode_string("UN", gUserText);
- post_data += tmp_url_buf;
- }
-
- delete db_filep;
- db_filep = NULL;
- delete sl_filep;
- sl_filep = NULL;
- delete md_filep;
- md_filep = NULL;
-
- // Post data to web server
- const S32 BUFSIZE = 65536;
- HINTERNET hinet, hsession, hrequest;
- char data[BUFSIZE]; /* Flawfinder: ignore */
- unsigned long bytes_read;
-
- llinfos << "Connecting to crash report server" << llendl;
- update_messages();
- show_progress("Connecting to server...");
- update_messages();
-
- // Init wininet subsystem
- hinet = InternetOpen(L"LindenCrashReporter", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
- if (hinet == NULL)
- {
- llinfos << "Couldn't open connection" << llendl;
- sleep_and_pump_messages( 5 );
-// return FALSE;
- }
-
- hsession = InternetConnect(hinet,
- L"secondlife.com",
- INTERNET_DEFAULT_HTTP_PORT,
- NULL,
- NULL,
- INTERNET_SERVICE_HTTP,
- NULL,
- NULL);
-
- if (!hsession)
- {
- llinfos << "Couldn't talk to crash report server" << llendl;
- }
-
- hrequest = HttpOpenRequest(hsession, L"POST", L"/cgi-bin/viewer_crash_reporter2", NULL, L"", NULL, 0, 0);
- if (!hrequest)
- {
- llinfos << "Couldn't open crash report URL!" << llendl;
+ llwarns << "Unable to parse command line." << llendl;
}
- llinfos << "Transmitting data" << llendl;
- llinfos << "Bytes: " << (post_data.size()) << llendl;
-
- update_messages();
- show_progress("Transmitting data...");
- update_messages();
-
- BOOL ok = HttpSendRequest(hrequest, NULL, 0, (void *)(post_data.c_str()), post_data.size());
- if (!ok)
- {
- llinfos << "Error posting data!" << llendl;
- sleep_and_pump_messages( 5 );
- }
-
- llinfos << "Response from crash report server:" << llendl;
- do
- {
- if (InternetReadFile(hrequest, data, BUFSIZE, &bytes_read))
- {
- if (bytes_read == 0)
- {
- // If InternetFileRead returns TRUE AND bytes_read == 0
- // we've successfully downloaded the entire file
- break;
- }
- else
- {
- data[bytes_read] = 0;
- llinfos << data << llendl;
- }
- }
- else
- {
- llinfos << "Couldn't read file!" << llendl;
- sleep_and_pump_messages( 5 );
-// return FALSE;
- }
- } while(TRUE);
-
- InternetCloseHandle(hrequest);
- InternetCloseHandle(hsession);
- InternetCloseHandle(hinet);
- update_messages();
- show_progress("Done.");
- sleep_and_pump_messages( 3 );
-// return TRUE;
-}
-
-LLFileEncoder::LLFileEncoder(const char *form_name, const char *filename)
-{
- mFormname = form_name;
- mFilename = filename;
- mIsValid = FALSE;
- mBuf = NULL;
-
- int res;
-
- llstat stat_data;
- res = LLFile::stat(mFilename.c_str(), &stat_data);
- if (res)
- {
- llwarns << "File " << mFilename << " is missing!" << llendl;
- return;
- }
-
- FILE *fp = NULL;
- S32 buf_size = 0;
- S32 count = 0;
- while (count < 5)
- {
- buf_size = stat_data.st_size;
- fp = LLFile::fopen(mFilename.c_str(), "rb"); /* Flawfinder: ignore */
- if (!fp)
- {
- llwarns << "Can't open file " << mFilename << ", wait for a second" << llendl;
- // Couldn't open the file, wait a bit and try again
- count++;
- ms_sleep(1000);
- }
- else
- {
- break;
- }
- }
- if (!fp)
- {
- return;
- }
- U8 *buf = new U8[buf_size + 1];
- fread(buf, 1, buf_size, fp);
- fclose(fp);
-
- mBuf = buf;
- mBufLength = buf_size;
-
- mIsValid = TRUE;
-}
-
-LLFileEncoder::~LLFileEncoder()
-{
- if (mBuf)
- {
- delete mBuf;
- mBuf = NULL;
- }
-}
-
-LLString LLFileEncoder::encodeURL(const S32 max_length)
-{
- LLString result = mFormname;
- result.append(1, '=');
-
- S32 i = 0;
-
- if (max_length)
- {
- if (mBufLength > max_length)
- {
- i = mBufLength - max_length;
- }
- }
-
- S32 url_buf_size = 3*mBufLength + 1;
- char *url_buf = new char[url_buf_size];
-
- S32 cur_pos = 0;
- for (; i < mBufLength; i++)
+ app.setHandle(hInstance);
+ ok = app.init();
+ if(!ok)
{
- S32 byte_val = mBuf[i];
- sprintf(url_buf + cur_pos, "%%%02x", byte_val);
- cur_pos += 3;
+ llwarns << "Unable to initialize application." << llendl;
+ return -1;
}
- url_buf[i*3] = 0;
- result.append(url_buf);
- delete[] url_buf;
- return result;
-}
-
-LLString encode_string(const char *formname, const LLString &str)
-{
- LLString result = formname;
- result.append(1, '=');
- // Not using LLString because of bad performance issues
- S32 buf_size = str.size();
- S32 url_buf_size = 3*str.size() + 1;
- char *url_buf = new char[url_buf_size];
+ // Run the application main loop
+ if(!LLApp::isQuitting()) app.mainLoop();
- S32 cur_pos = 0;
- S32 i;
- for (i = 0; i < buf_size; i++)
+ if (!app.isError())
{
- sprintf(url_buf + cur_pos, "%%%02x", str[i]);
- cur_pos += 3;
+ //
+ // We don't want to do cleanup here if the error handler got called -
+ // the assumption is that the error handler is responsible for doing
+ // app cleanup if there was a problem.
+ //
+ app.cleanup();
}
- url_buf[i*3] = 0;
-
- result.append(url_buf);
- delete[] url_buf;
- return result;
-}
-
-void write_debug(const char *str)
-{
- if (!gDebugFile)
- {
- std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
- llinfos << "Opening debug file " << debug_filename << llendl;
- gDebugFile = LLFile::fopen(debug_filename.c_str(), "a+"); /* Flawfinder: ignore */
- if (!gDebugFile)
- {
- fprintf(stderr, "Couldn't open %s: debug log to stderr instead.\n", debug_filename.c_str());
- gDebugFile = stderr;
- }
- }
- fprintf(gDebugFile, str); /* Flawfinder: ignore */
- fflush(gDebugFile);
-}
-
-void write_debug(std::string& str)
-{
- write_debug(str.c_str());
-}
-
-S32 load_crash_behavior_setting()
-{
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-
- gCrashSettings.loadFromFile(filename);
-
- S32 value = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
-
- if (value < CRASH_BEHAVIOR_ASK || CRASH_BEHAVIOR_NEVER_SEND < value) return CRASH_BEHAVIOR_ASK;
-
- return value;
-}
-
-bool save_crash_behavior_setting(S32 crash_behavior)
-{
- if (crash_behavior < CRASH_BEHAVIOR_ASK) return false;
- if (crash_behavior > CRASH_BEHAVIOR_NEVER_SEND) return false;
-
- gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, crash_behavior);
- std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
-
- gCrashSettings.saveToFile(filename, FALSE);
-
- return true;
+ return 0;
}