1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir #include <cstdio> 28*cdf0e10cSrcweir #include <stdlib.h> 29*cdf0e10cSrcweir #include <sys/utsname.h> 30*cdf0e10cSrcweir #include <_version.h> 31*cdf0e10cSrcweir #include <errno.h> 32*cdf0e10cSrcweir #include <string> 33*cdf0e10cSrcweir #include <string.h> 34*cdf0e10cSrcweir #include <assert.h> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include <sys/socket.h> 37*cdf0e10cSrcweir #include <netdb.h> 38*cdf0e10cSrcweir #include <unistd.h> 39*cdf0e10cSrcweir #include <pwd.h> 40*cdf0e10cSrcweir #include <pthread.h> 41*cdf0e10cSrcweir #include <limits.h> 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir #include <hash_map> 44*cdf0e10cSrcweir #include <vector> 45*cdf0e10cSrcweir #include <string> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #if defined (LINUX) || (FREEBSD) 48*cdf0e10cSrcweir #include <netinet/in.h> 49*cdf0e10cSrcweir #endif 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir typedef int SOCKET; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #define closesocket close 54*cdf0e10cSrcweir #define SOCKET_ERROR -1 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #ifdef SOLARIS 57*cdf0e10cSrcweir const char *basename( const char *filename ) 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir const char *pSlash = strrchr( filename, '/' ); 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir return pSlash ? pSlash + 1 : pSlash; 62*cdf0e10cSrcweir } 63*cdf0e10cSrcweir #endif 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir using namespace std; 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir static bool g_bNoUI = false; 68*cdf0e10cSrcweir static bool g_bSendReport = false; 69*cdf0e10cSrcweir static bool g_bLoadReport = false; 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir static bool g_bDebugMode = false; 72*cdf0e10cSrcweir static int g_signal = 0; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir static string g_strProductKey; 75*cdf0e10cSrcweir static string g_strReportServer; 76*cdf0e10cSrcweir static unsigned short g_uReportPort = 80; 77*cdf0e10cSrcweir static string g_buildid; 78*cdf0e10cSrcweir static string g_strDefaultLanguage; 79*cdf0e10cSrcweir static string g_strXMLFileName; 80*cdf0e10cSrcweir static string g_strPStackFileName; 81*cdf0e10cSrcweir static string g_strChecksumFileName; 82*cdf0e10cSrcweir static string g_strProgramDir; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir static char g_szStackFile[L_tmpnam] = ""; 85*cdf0e10cSrcweir static char g_szDescriptionFile[2048] = ""; 86*cdf0e10cSrcweir static char g_szReportFile[2048] = ""; 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir #define SO_CRASHREPORT_MAIL "so-report@sun.com" 89*cdf0e10cSrcweir #define PSTACK_CMD "pstack %d" 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir #ifdef LINUX 92*cdf0e10cSrcweir #define PMAP_CMD "cat /proc/%d/maps" 93*cdf0e10cSrcweir #else 94*cdf0e10cSrcweir #define PMAP_CMD "pmap %d" 95*cdf0e10cSrcweir #endif 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir #define REPORT_SERVER (g_strReportServer.c_str()) 98*cdf0e10cSrcweir #define REPORT_PORT g_uReportPort 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir static string getprogramdir() 101*cdf0e10cSrcweir { 102*cdf0e10cSrcweir return g_strProgramDir; 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir static const char *getlocale() 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir const char * locale = getenv( "LC_ALL" ); 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir if( NULL == locale ) 110*cdf0e10cSrcweir locale = getenv( "LC_CTYPE" ); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir if( NULL == locale ) 113*cdf0e10cSrcweir locale = getenv( "LANG" ); 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir if( NULL == locale ) 116*cdf0e10cSrcweir locale = "C"; 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir return locale; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir static const char *get_home_dir() 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir struct passwd *ppwd = getpwuid( getuid() ); 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir return ppwd ? (ppwd->pw_dir ? ppwd->pw_dir : "/") : "/"; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir static string trim_string( const string& rString ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir string temp = rString; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir while ( temp.length() && (temp[0] == ' ' || temp[0] == '\t') ) 133*cdf0e10cSrcweir temp.erase( 0, 1 ); 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir string::size_type len = temp.length(); 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir while ( len && (temp[len-1] == ' ' || temp[len-1] == '\t') ) 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir temp.erase( len - 1, 1 ); 140*cdf0e10cSrcweir len = temp.length(); 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir return temp; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir static string xml_encode( const string &rString ) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir string temp = rString; 149*cdf0e10cSrcweir string::size_type pos = 0; 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // First replace all occurences of '&' because it may occur in further 152*cdf0e10cSrcweir // encoded chardters too 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir for( pos = 0; (pos = temp.find( '&', pos )) != string::npos; pos += 4 ) 155*cdf0e10cSrcweir temp.replace( pos, 1, "&" ); 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir for( pos = 0; (pos = temp.find( '<', pos )) != string::npos; pos += 4 ) 158*cdf0e10cSrcweir temp.replace( pos, 1, "<" ); 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir for( pos = 0; (pos = temp.find( '>', pos )) != string::npos; pos += 4 ) 161*cdf0e10cSrcweir temp.replace( pos, 1, ">" ); 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir return temp; 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir static size_t fcopy( FILE *fpout, FILE *fpin ) 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir char buffer[1024]; 169*cdf0e10cSrcweir size_t nBytes; 170*cdf0e10cSrcweir size_t nBytesWritten = 0; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir while ( 0 != (nBytes = fread( buffer, 1, sizeof(buffer), fpin )) ) 173*cdf0e10cSrcweir { 174*cdf0e10cSrcweir nBytesWritten += fwrite( buffer, 1, nBytes, fpout ); 175*cdf0e10cSrcweir } 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir return nBytesWritten; 178*cdf0e10cSrcweir } 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir /* 181*cdf0e10cSrcweir writes the report to a temp-file 182*cdf0e10cSrcweir from which it can be reviewed and sent 183*cdf0e10cSrcweir */ 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir bool write_report( const hash_map< string, string >& rSettings ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir FILE *fp = fopen( tmpnam( g_szReportFile ), "w" ); 188*cdf0e10cSrcweir const char *pszUserType = getenv( "STAROFFICE_USERTYPE" ); 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir fprintf( fp, 191*cdf0e10cSrcweir "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 192*cdf0e10cSrcweir "<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n" 193*cdf0e10cSrcweir "<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\"%s\">\n" 194*cdf0e10cSrcweir "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\"%s\" email=\"%s\">\n" 195*cdf0e10cSrcweir "<reportmail:title>%s</reportmail:title>\n" 196*cdf0e10cSrcweir "<reportmail:attachment name=\"description.txt\" media-type=\"text/plain\" class=\"UserComment\"/>\n" 197*cdf0e10cSrcweir "<reportmail:attachment name=\"stack.txt\" media-type=\"text/plain\" class=\"pstack output\"/>\n" 198*cdf0e10cSrcweir "</reportmail:mail>\n" 199*cdf0e10cSrcweir "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" build=\"%s\" platform=\"%s\" language=\"%s\" exceptiontype=\"%d\" product=\"%s\" procpath=\"%s\"/>\n" 200*cdf0e10cSrcweir , 201*cdf0e10cSrcweir pszUserType ? xml_encode( pszUserType ).c_str() : "", 202*cdf0e10cSrcweir xml_encode(rSettings.find( "CONTACT" )->second).c_str(), 203*cdf0e10cSrcweir xml_encode(rSettings.find( "EMAIL" )->second).c_str(), 204*cdf0e10cSrcweir xml_encode(rSettings.find( "TITLE" )->second).c_str(), 205*cdf0e10cSrcweir g_buildid.length() ? xml_encode( g_buildid ).c_str() : "unknown", 206*cdf0e10cSrcweir _INPATH, 207*cdf0e10cSrcweir g_strDefaultLanguage.c_str(), 208*cdf0e10cSrcweir g_signal, 209*cdf0e10cSrcweir g_strProductKey.length() ? xml_encode(g_strProductKey).c_str() : "unknown", 210*cdf0e10cSrcweir xml_encode(getprogramdir()).c_str() 211*cdf0e10cSrcweir ); 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir struct utsname info; 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir memset( &info, 0, sizeof(info) ); 216*cdf0e10cSrcweir uname( &info ); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir fprintf( fp, 219*cdf0e10cSrcweir "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n" 220*cdf0e10cSrcweir "<systeminfo:System name=\"%s\" version=\"%s\" build=\"%s\" locale=\"%s\"/>\n" 221*cdf0e10cSrcweir , 222*cdf0e10cSrcweir xml_encode( info.sysname ).c_str(), 223*cdf0e10cSrcweir xml_encode( info.version ).c_str(), 224*cdf0e10cSrcweir xml_encode( info.release ).c_str(), 225*cdf0e10cSrcweir xml_encode( getlocale() ).c_str() 226*cdf0e10cSrcweir ); 227*cdf0e10cSrcweir fprintf( fp, "<systeminfo:CPU type=\"%s\"/>\n", xml_encode( info.machine ).c_str() ); 228*cdf0e10cSrcweir fprintf( fp, "</systeminfo:systeminfo>\n" ); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir FILE *fpxml = fopen( g_strXMLFileName.c_str(), "r" ); 231*cdf0e10cSrcweir if ( fpxml ) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir fcopy( fp, fpxml ); 234*cdf0e10cSrcweir fclose( fpxml ); 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir FILE *fpchk = fopen( g_strChecksumFileName.c_str(), "r" ); 238*cdf0e10cSrcweir if ( fpchk ) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir fcopy( fp, fpchk ); 241*cdf0e10cSrcweir fclose( fpchk ); 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir fprintf( fp, "</errormail:errormail>\n" ); 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir fclose( fp ); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir return true; 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir bool write_description( const hash_map< string, string >& rSettings ) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir bool bSuccess = false; 255*cdf0e10cSrcweir FILE *fp = fopen( tmpnam( g_szDescriptionFile ), "w" ); 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir if ( fp ) 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir bSuccess = true; 260*cdf0e10cSrcweir fprintf( fp, "\xEF\xBB\xBF" ); 261*cdf0e10cSrcweir fprintf( fp, "%s\n", rSettings.find( "DESCRIPTION" )->second.c_str() ); 262*cdf0e10cSrcweir fclose( fp ); 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir return bSuccess; 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir #if 0 269*cdf0e10cSrcweir // unused 270*cdf0e10cSrcweir static void printSettings( const hash_map<string,string>& rSettings ) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir printf( "Settings:\n" ); 273*cdf0e10cSrcweir for( hash_map<string,string>::const_iterator it = rSettings.begin(); it != rSettings.end(); ++it ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir printf( "%s=\"%s\"\n", it->first.c_str(), it->second.c_str() ); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir #endif 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir bool save_crash_report( const string& rFileName, const hash_map< string, string >& /*rSettings*/ ) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir bool bSuccess = false; 283*cdf0e10cSrcweir FILE *fpout = fopen( rFileName.c_str(), "w" ); 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir if ( fpout ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir FILE *fpin = fopen( g_szStackFile, "r" ); 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir if ( fpin ) 290*cdf0e10cSrcweir { 291*cdf0e10cSrcweir char buf[1024]; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir while (fgets(buf, sizeof(buf), fpin) != NULL) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir fputs(buf, fpout); 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir bSuccess = true; 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir fclose ( fpin ); 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir fclose( fpout ); 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir 306*cdf0e10cSrcweir return bSuccess; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir bool SendHTTPRequest( 310*cdf0e10cSrcweir FILE *fp, 311*cdf0e10cSrcweir const char *pszServer, 312*cdf0e10cSrcweir unsigned short uPort = 80, 313*cdf0e10cSrcweir const char *pszProxyServer = NULL, 314*cdf0e10cSrcweir unsigned short uProxyPort = 8080 ) 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir bool success = false; 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir struct hostent *hp; 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir if ( pszProxyServer ) 321*cdf0e10cSrcweir hp = gethostbyname( pszProxyServer ); 322*cdf0e10cSrcweir else 323*cdf0e10cSrcweir hp = gethostbyname( pszServer ); 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir if ( hp ) 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir SOCKET s = socket( AF_INET, SOCK_STREAM, 0 ); 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir if ( s ) 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir struct sockaddr_in address; 332*cdf0e10cSrcweir 333*cdf0e10cSrcweir memcpy(&(address.sin_addr.s_addr), *(hp->h_addr_list),sizeof(struct in_addr)); 334*cdf0e10cSrcweir address.sin_family = AF_INET; 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir if ( pszProxyServer ) 337*cdf0e10cSrcweir address.sin_port = ntohs( uProxyPort ); 338*cdf0e10cSrcweir else 339*cdf0e10cSrcweir address.sin_port = ntohs( uPort ); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir if ( 0 == connect( s, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) ) 342*cdf0e10cSrcweir { 343*cdf0e10cSrcweir fseek( fp, 0, SEEK_END ); 344*cdf0e10cSrcweir size_t length = ftell( fp ); 345*cdf0e10cSrcweir fseek( fp, 0, SEEK_SET ); 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir char buffer[2048]; 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir if ( pszProxyServer ) 350*cdf0e10cSrcweir sprintf( buffer, 351*cdf0e10cSrcweir "POST http://%s:%d/soap/servlet/rpcrouter HTTP/1.0\r\n" 352*cdf0e10cSrcweir "Content-Type: text/xml; charset=\"utf-8\"\r\n" 353*cdf0e10cSrcweir "Content-Length: %d\r\n" 354*cdf0e10cSrcweir "SOAPAction: \"\"\r\n\r\n", 355*cdf0e10cSrcweir pszServer, 356*cdf0e10cSrcweir uPort, 357*cdf0e10cSrcweir static_cast<int>(length) 358*cdf0e10cSrcweir ); 359*cdf0e10cSrcweir else 360*cdf0e10cSrcweir sprintf( buffer, 361*cdf0e10cSrcweir "POST /soap/servlet/rpcrouter HTTP/1.0\r\n" 362*cdf0e10cSrcweir "Content-Type: text/xml; charset=\"utf-8\"\r\n" 363*cdf0e10cSrcweir "Content-Length: %d\r\n" 364*cdf0e10cSrcweir "SOAPAction: \"\"\r\n\r\n", 365*cdf0e10cSrcweir static_cast<int>(length) 366*cdf0e10cSrcweir ); 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir if ( g_bDebugMode ) 369*cdf0e10cSrcweir { 370*cdf0e10cSrcweir printf( "*** Sending HTTP request ***\n\n" ); 371*cdf0e10cSrcweir printf( buffer ); 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir if ( SOCKET_ERROR != send( s, buffer, strlen(buffer), 0 ) ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir size_t nBytes; 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir do 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir nBytes = fread( buffer, 1, sizeof(buffer), fp ); 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir if ( nBytes ) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir if ( g_bDebugMode ) 385*cdf0e10cSrcweir fwrite( buffer, 1, nBytes, stdout ); 386*cdf0e10cSrcweir success = SOCKET_ERROR != send( s, buffer, nBytes, 0 ); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir } while( nBytes && success ); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir if ( success ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir if ( g_bDebugMode ) 393*cdf0e10cSrcweir printf( "*** Receiving HTTP response ***\n\n" ); 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir memset( buffer, 0, sizeof(buffer) ); 396*cdf0e10cSrcweir success = SOCKET_ERROR != recv( s, buffer, sizeof(buffer), 0 ); 397*cdf0e10cSrcweir if ( success ) 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir char szHTTPSignature[sizeof(buffer)] = ""; 400*cdf0e10cSrcweir unsigned uHTTPReturnCode = 0; 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir sscanf( buffer, "%s %d ", szHTTPSignature, &uHTTPReturnCode ); 403*cdf0e10cSrcweir success = uHTTPReturnCode == 200; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir if ( g_bDebugMode ) 406*cdf0e10cSrcweir do 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir printf( buffer ); 409*cdf0e10cSrcweir memset( buffer, 0, sizeof(buffer) ); 410*cdf0e10cSrcweir } while ( 0 < recv( s, buffer, sizeof(buffer), 0 ) ); 411*cdf0e10cSrcweir } 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir } 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir closesocket( s ); 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir return success; 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir static void WriteSOAPRequest( FILE *fp ) 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir fprintf( fp, 426*cdf0e10cSrcweir "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 427*cdf0e10cSrcweir "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" 428*cdf0e10cSrcweir "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n" 429*cdf0e10cSrcweir "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n" 430*cdf0e10cSrcweir "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n" 431*cdf0e10cSrcweir "xmlns:rds=\"urn:ReportDataService\"\n" 432*cdf0e10cSrcweir "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n" 433*cdf0e10cSrcweir "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" 434*cdf0e10cSrcweir "<SOAP-ENV:Body>\n" 435*cdf0e10cSrcweir ); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir fprintf( fp, "<rds:submitReport>\n" ); 438*cdf0e10cSrcweir fprintf( fp, "<body xsi:type=\"xsd:string\">This is an autogenerated crash report mail.</body>\n" ); 439*cdf0e10cSrcweir fprintf( fp, "<hash xsi:type=\"apache:Map\">\n" ); 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir FILE *fpin = fopen( g_szReportFile, "r" ); 442*cdf0e10cSrcweir if ( fpin ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir fprintf( fp, 445*cdf0e10cSrcweir "<item>\n" 446*cdf0e10cSrcweir "<key xsi:type=\"xsd:string\">reportmail.xml</key>\n" 447*cdf0e10cSrcweir "<value xsi:type=\"xsd:string\"><![CDATA[" ); 448*cdf0e10cSrcweir fcopy( fp, fpin ); 449*cdf0e10cSrcweir fprintf( fp, "]]></value></item>\n" ); 450*cdf0e10cSrcweir fclose( fpin ); 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir fpin = fopen( g_szDescriptionFile, "r" ); 454*cdf0e10cSrcweir if ( fpin ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir fprintf( fp, 457*cdf0e10cSrcweir "<item>\n" 458*cdf0e10cSrcweir "<key xsi:type=\"xsd:string\">description.txt</key>\n" 459*cdf0e10cSrcweir "<value xsi:type=\"xsd:string\"><![CDATA[" ); 460*cdf0e10cSrcweir fcopy( fp, fpin ); 461*cdf0e10cSrcweir fprintf( fp, "]]></value></item>\n" ); 462*cdf0e10cSrcweir fclose( fpin ); 463*cdf0e10cSrcweir }; 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir fpin = fopen( g_szStackFile, "r" ); 466*cdf0e10cSrcweir if ( fpin ) 467*cdf0e10cSrcweir { 468*cdf0e10cSrcweir fprintf( fp, 469*cdf0e10cSrcweir "<item>\n" 470*cdf0e10cSrcweir "<key xsi:type=\"xsd:string\">stack.txt</key>\n" 471*cdf0e10cSrcweir "<value xsi:type=\"xsd:string\"><![CDATA[" ); 472*cdf0e10cSrcweir fcopy( fp, fpin ); 473*cdf0e10cSrcweir fprintf( fp, "]]></value></item>\n" ); 474*cdf0e10cSrcweir fclose( fpin ); 475*cdf0e10cSrcweir }; 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir fprintf( fp, 478*cdf0e10cSrcweir "</hash>\n" 479*cdf0e10cSrcweir "</rds:submitReport>\n" 480*cdf0e10cSrcweir "</SOAP-ENV:Body>\n" 481*cdf0e10cSrcweir "</SOAP-ENV:Envelope>\n" 482*cdf0e10cSrcweir ); 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir struct RequestParams 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir bool success; 488*cdf0e10cSrcweir FILE *fpin; 489*cdf0e10cSrcweir const char *pServer; 490*cdf0e10cSrcweir unsigned short uPort; 491*cdf0e10cSrcweir const char *pProxyServer; 492*cdf0e10cSrcweir unsigned short uProxyPort; 493*cdf0e10cSrcweir }; 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir bool send_crash_report( const hash_map< string, string >& rSettings ) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir if ( 0 == strcasecmp( rSettings.find( "CONTACT" )->second.c_str(), "true" ) && 499*cdf0e10cSrcweir !trim_string(rSettings.find( "EMAIL" )->second).length() ) 500*cdf0e10cSrcweir { 501*cdf0e10cSrcweir return false; 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir char *endptr = NULL; 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir const char *pProxyServer = rSettings.find( "SERVER" )->second.c_str(); 507*cdf0e10cSrcweir unsigned short uProxyPort = (unsigned short)strtoul( rSettings.find( "PORT" )->second.c_str(), &endptr, 10 ); 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir bool bUseProxy = !strcasecmp( "true", rSettings.find( "USEPROXY" )->second.c_str() ); 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir write_description( rSettings ); 513*cdf0e10cSrcweir write_report( rSettings ); 514*cdf0e10cSrcweir 515*cdf0e10cSrcweir bool bSuccess = false; 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir FILE *fptemp = tmpfile(); 518*cdf0e10cSrcweir if ( fptemp ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir WriteSOAPRequest( fptemp ); 521*cdf0e10cSrcweir fseek( fptemp, 0, SEEK_SET ); 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir bSuccess = SendHTTPRequest( 524*cdf0e10cSrcweir fptemp, 525*cdf0e10cSrcweir REPORT_SERVER, REPORT_PORT, 526*cdf0e10cSrcweir bUseProxy ? pProxyServer : NULL, 527*cdf0e10cSrcweir uProxyPort ? uProxyPort : 8080 528*cdf0e10cSrcweir ); 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir fclose( fptemp ); 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir } 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir unlink( g_szDescriptionFile ); 535*cdf0e10cSrcweir unlink( g_szReportFile ); 536*cdf0e10cSrcweir 537*cdf0e10cSrcweir return bSuccess; 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir static bool append_file( const char *filename, string& rString ) 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir char buf[1024]; 544*cdf0e10cSrcweir bool bSuccess = false; 545*cdf0e10cSrcweir 546*cdf0e10cSrcweir FILE *fp = fopen( filename, "r" ); 547*cdf0e10cSrcweir if ( fp ) 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir bSuccess = true; 550*cdf0e10cSrcweir while (fgets(buf, sizeof(buf), fp) != NULL) 551*cdf0e10cSrcweir { 552*cdf0e10cSrcweir rString.append( buf ); 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir fclose( fp ); 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir return true; 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir string crash_get_details( const hash_map< string, string >& rSettings ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir string aRet; 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir write_description( rSettings ); 565*cdf0e10cSrcweir write_report( rSettings ); 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir aRet.append( rSettings.find( "TITLE" )->second.c_str() ); 568*cdf0e10cSrcweir aRet.append( "\n\n" ); 569*cdf0e10cSrcweir append_file( g_szDescriptionFile, aRet ); 570*cdf0e10cSrcweir aRet.append( "\n\n-------\n\n" ); 571*cdf0e10cSrcweir append_file( g_szReportFile, aRet ); 572*cdf0e10cSrcweir aRet.append( "\n\n-------\n\n" ); 573*cdf0e10cSrcweir append_file( g_szStackFile, aRet ); 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir unlink( g_szDescriptionFile ); 576*cdf0e10cSrcweir unlink( g_szReportFile ); 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir return aRet; 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir // ensure validity of program relative paths 583*cdf0e10cSrcweir static void setup_program_dir( const char* progname ) 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir char szCanonicProgPath[PATH_MAX]; 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir if ( realpath( progname, szCanonicProgPath ) ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir string aDir = szCanonicProgPath; 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir size_t pos = aDir.rfind( '/' ); 593*cdf0e10cSrcweir // FIXME: search PATH if necessary 594*cdf0e10cSrcweir assert( pos != string::npos ); 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir g_strProgramDir = aDir.substr( 0, pos + 1 ); 597*cdf0e10cSrcweir aDir.erase( pos ); 598*cdf0e10cSrcweir chdir( aDir.c_str() ); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir //************************************************************************* 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir static long setup_commandline_arguments( int argc, char** argv, int *pSignal ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir long pid = 0; 607*cdf0e10cSrcweir int signal = 0; 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir for ( int n = 1; n < argc; n++ ) 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir if ( 0 == strcmp( argv[n], "-p" ) ) 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir if ( ++n < argc ) 614*cdf0e10cSrcweir pid = strtol( argv[n], NULL, 0 ); 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-s" ) ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir if ( ++n < argc ) 619*cdf0e10cSrcweir signal = strtol( argv[n], NULL, 0 ); 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-debug" ) ) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir g_bDebugMode = true; 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-xml" ) ) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir if ( ++n < argc ) 628*cdf0e10cSrcweir g_strXMLFileName = argv[n]; 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-stack" ) ) 631*cdf0e10cSrcweir { 632*cdf0e10cSrcweir if ( ++n < argc ) 633*cdf0e10cSrcweir g_strPStackFileName = argv[n]; 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-chksum" ) ) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir if ( ++n < argc ) 638*cdf0e10cSrcweir g_strChecksumFileName = argv[n]; 639*cdf0e10cSrcweir } 640*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-noui" ) ) 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir g_bNoUI = true; 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-send" ) ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir g_bSendReport = true; 647*cdf0e10cSrcweir } 648*cdf0e10cSrcweir else if ( 0 == strcmp( argv[n], "-load" ) ) 649*cdf0e10cSrcweir { 650*cdf0e10cSrcweir g_bLoadReport = true; 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir else if ( argv[n] && strlen(argv[n]) ) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir printf( 655*cdf0e10cSrcweir "\n%s crash_report %s\n\n" \ 656*cdf0e10cSrcweir "/?, -h[elp] %s\n\n" \ 657*cdf0e10cSrcweir "%-20s %s\n\n", 658*cdf0e10cSrcweir "%MSG_CMDLINE_USAGE%", 659*cdf0e10cSrcweir "%MSG_PARAM_PROCESSID%", 660*cdf0e10cSrcweir "%MSG_PARAM_HELP_DESCRIPTION%", 661*cdf0e10cSrcweir "%MSG_PARAM_PROCESSID%", 662*cdf0e10cSrcweir "%MSG_PARAM_PROCESSID_DESCRIPTION%" 663*cdf0e10cSrcweir ); 664*cdf0e10cSrcweir break; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir *pSignal = signal; 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir return pid; 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir //************************************************************************* 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir static bool read_line( FILE *fp, string& rLine ) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir char szBuffer[1024]; 678*cdf0e10cSrcweir bool bSuccess = false; 679*cdf0e10cSrcweir bool bEOL = false; 680*cdf0e10cSrcweir string line; 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir 683*cdf0e10cSrcweir while ( !bEOL && fgets( szBuffer, sizeof(szBuffer), fp ) ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir int len = strlen(szBuffer); 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir bSuccess = true; 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir while ( len && szBuffer[len - 1] == '\n' ) 690*cdf0e10cSrcweir { 691*cdf0e10cSrcweir szBuffer[--len] = 0; 692*cdf0e10cSrcweir bEOL = true; 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir line.append( szBuffer ); 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir rLine = line; 699*cdf0e10cSrcweir return bSuccess; 700*cdf0e10cSrcweir } 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir static string get_script_string( const char *pFileName, const char *pKeyName ) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir FILE *fp = fopen( pFileName, "r" ); 705*cdf0e10cSrcweir string retValue; 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir if ( fp ) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir string line; 710*cdf0e10cSrcweir string section; 711*cdf0e10cSrcweir 712*cdf0e10cSrcweir while ( read_line( fp, line ) ) 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir line = trim_string( line ); 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir string::size_type iEqualSign = line.find( '=', 0 ); 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir if ( iEqualSign != string::npos ) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir string keyname = line.substr( 0, iEqualSign ); 722*cdf0e10cSrcweir keyname = trim_string( keyname ); 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir string value = line.substr( iEqualSign + 1, string::npos ); 725*cdf0e10cSrcweir value = trim_string( value ); 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir if ( value.length() && '\"' == value[0] ) 728*cdf0e10cSrcweir { 729*cdf0e10cSrcweir value.erase( 0, 1 ); 730*cdf0e10cSrcweir 731*cdf0e10cSrcweir string::size_type iQuotes = value.find( '"', 0 ); 732*cdf0e10cSrcweir 733*cdf0e10cSrcweir if ( iQuotes != string::npos ) 734*cdf0e10cSrcweir value.erase( iQuotes ); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir if ( 0 == strcasecmp( keyname.c_str(), pKeyName ) ) 738*cdf0e10cSrcweir { 739*cdf0e10cSrcweir retValue = value; 740*cdf0e10cSrcweir break; 741*cdf0e10cSrcweir } 742*cdf0e10cSrcweir } 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir fclose( fp ); 746*cdf0e10cSrcweir } 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir return retValue; 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir static string get_profile_string( const char *pFileName, const char *pSectionName, const char *pKeyName, const char *pDefault = NULL ) 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir FILE *fp = fopen( pFileName, "r" ); 754*cdf0e10cSrcweir string retValue = pDefault ? pDefault : ""; 755*cdf0e10cSrcweir 756*cdf0e10cSrcweir if ( fp ) 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir string line; 759*cdf0e10cSrcweir string section; 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir while ( read_line( fp, line ) ) 762*cdf0e10cSrcweir { 763*cdf0e10cSrcweir line = trim_string( line ); 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir if ( line.length() && line[0] == '[' ) 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir line.erase( 0, 1 ); 768*cdf0e10cSrcweir string::size_type end = line.find( ']', 0 ); 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir if ( string::npos != end ) 771*cdf0e10cSrcweir section = trim_string( line.substr( 0, end ) ); 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir else 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir string::size_type iEqualSign = line.find( '=', 0 ); 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir if ( iEqualSign != string::npos ) 779*cdf0e10cSrcweir { 780*cdf0e10cSrcweir string keyname = line.substr( 0, iEqualSign ); 781*cdf0e10cSrcweir keyname = trim_string( keyname ); 782*cdf0e10cSrcweir 783*cdf0e10cSrcweir string value = line.substr( iEqualSign + 1, string::npos ); 784*cdf0e10cSrcweir value = trim_string( value ); 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir if ( 787*cdf0e10cSrcweir 0 == strcasecmp( section.c_str(), pSectionName ) && 788*cdf0e10cSrcweir 0 == strcasecmp( keyname.c_str(), pKeyName ) 789*cdf0e10cSrcweir ) 790*cdf0e10cSrcweir { 791*cdf0e10cSrcweir retValue = value; 792*cdf0e10cSrcweir break; 793*cdf0e10cSrcweir } 794*cdf0e10cSrcweir } 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir fclose( fp ); 799*cdf0e10cSrcweir } 800*cdf0e10cSrcweir 801*cdf0e10cSrcweir return retValue; 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir 804*cdf0e10cSrcweir static string get_environment_string( const char *pEnvName ) 805*cdf0e10cSrcweir { 806*cdf0e10cSrcweir const char *pEnvValue = getenv( pEnvName ); 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir if ( pEnvValue ) 809*cdf0e10cSrcweir return pEnvValue; 810*cdf0e10cSrcweir else 811*cdf0e10cSrcweir return ""; 812*cdf0e10cSrcweir } 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir static string read_from_file( const string& rFileName ) 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir string content; 817*cdf0e10cSrcweir FILE *fp = fopen( rFileName.c_str(), "r" ); 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir if ( fp ) 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir char buffer[256 + 1]; 822*cdf0e10cSrcweir size_t nBytesRead; 823*cdf0e10cSrcweir 824*cdf0e10cSrcweir while( 0 != ( nBytesRead = fread( buffer, 1, sizeof(buffer) - 1, fp ) ) ) 825*cdf0e10cSrcweir { 826*cdf0e10cSrcweir buffer[nBytesRead] = 0; 827*cdf0e10cSrcweir content += buffer; 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir 830*cdf0e10cSrcweir fclose( fp ); 831*cdf0e10cSrcweir } 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir return content; 834*cdf0e10cSrcweir } 835*cdf0e10cSrcweir 836*cdf0e10cSrcweir #define RCFILE ".crash_reportrc" 837*cdf0e10cSrcweir #define XMLFILE ".crash_report_frames" 838*cdf0e10cSrcweir #define CHKFILE ".crash_report_checksum" 839*cdf0e10cSrcweir #define LCKFILE ".crash_report_unsent" 840*cdf0e10cSrcweir #define PRVFILE ".crash_report_preview" 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir static void load_crash_data() 843*cdf0e10cSrcweir { 844*cdf0e10cSrcweir g_strXMLFileName = get_home_dir(); 845*cdf0e10cSrcweir g_strXMLFileName += "/"; 846*cdf0e10cSrcweir g_strXMLFileName += string(XMLFILE); 847*cdf0e10cSrcweir 848*cdf0e10cSrcweir g_strChecksumFileName = get_home_dir(); 849*cdf0e10cSrcweir g_strChecksumFileName += "/"; 850*cdf0e10cSrcweir g_strChecksumFileName += string(CHKFILE); 851*cdf0e10cSrcweir } 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir static bool write_crash_data() 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir bool success = true; 856*cdf0e10cSrcweir string sFile = get_home_dir(); 857*cdf0e10cSrcweir 858*cdf0e10cSrcweir sFile += "/"; 859*cdf0e10cSrcweir sFile += string(XMLFILE); 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir FILE *fp = fopen( sFile.c_str(), "w" ); 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir if ( fp ) 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir FILE *fpin = fopen( g_strXMLFileName.c_str(), "r" ); 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir if ( fpin ) 868*cdf0e10cSrcweir { 869*cdf0e10cSrcweir fcopy( fp, fpin ); 870*cdf0e10cSrcweir fclose( fpin ); 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir fclose( fp ); 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir sFile = get_home_dir(); 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir sFile += "/"; 879*cdf0e10cSrcweir sFile += string(CHKFILE); 880*cdf0e10cSrcweir 881*cdf0e10cSrcweir fp = fopen( sFile.c_str(), "w" ); 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir if ( fp ) 884*cdf0e10cSrcweir { 885*cdf0e10cSrcweir FILE *fpin = fopen( g_strChecksumFileName.c_str(), "r" ); 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir if ( fpin ) 888*cdf0e10cSrcweir { 889*cdf0e10cSrcweir fcopy( fp, fpin ); 890*cdf0e10cSrcweir fclose( fpin ); 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir 893*cdf0e10cSrcweir fclose( fp ); 894*cdf0e10cSrcweir } 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir sFile = get_home_dir(); 897*cdf0e10cSrcweir 898*cdf0e10cSrcweir sFile += "/"; 899*cdf0e10cSrcweir sFile += string(LCKFILE); 900*cdf0e10cSrcweir 901*cdf0e10cSrcweir fp = fopen( sFile.c_str(), "w" ); 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir if ( fp ) 904*cdf0e10cSrcweir { 905*cdf0e10cSrcweir fprintf( fp, "Unsent\n" ); 906*cdf0e10cSrcweir fclose( fp ); 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir return success; 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir #if 0 913*cdf0e10cSrcweir // unused 914*cdf0e10cSrcweir static bool write_settings( const hash_map< string, string >& rSettings ) 915*cdf0e10cSrcweir { 916*cdf0e10cSrcweir bool success = false; 917*cdf0e10cSrcweir string sRCFile = get_home_dir(); 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir sRCFile += "/"; 920*cdf0e10cSrcweir sRCFile += string(RCFILE); 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir FILE *fp = fopen( sRCFile.c_str(), "w" ); 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir if ( fp ) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir fprintf( fp, "[Options]\n" ); 927*cdf0e10cSrcweir fprintf( fp, "UseProxy=%s\n", rSettings.find( "USEPROXY" )->second.c_str() ); 928*cdf0e10cSrcweir fprintf( fp, "ProxyServer=%s\n", rSettings.find( "SERVER" )->second.c_str() ); 929*cdf0e10cSrcweir fprintf( fp, "ProxyPort=%s\n", rSettings.find( "PORT" )->second.c_str() ); 930*cdf0e10cSrcweir fprintf( fp, "ReturnAddress=%s\n", rSettings.find( "EMAIL" )->second.c_str() ); 931*cdf0e10cSrcweir fprintf( fp, "AllowContact=%s\n", rSettings.find( "CONTACT" )->second.c_str() ); 932*cdf0e10cSrcweir fclose( fp ); 933*cdf0e10cSrcweir } 934*cdf0e10cSrcweir 935*cdf0e10cSrcweir return success; 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir #endif 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir static void read_settings( hash_map< string, string >& rSettings ) 940*cdf0e10cSrcweir { 941*cdf0e10cSrcweir string sRCFile = get_home_dir(); 942*cdf0e10cSrcweir 943*cdf0e10cSrcweir sRCFile += "/"; 944*cdf0e10cSrcweir sRCFile += string(RCFILE); 945*cdf0e10cSrcweir 946*cdf0e10cSrcweir rSettings[ "EMAIL" ] = get_profile_string( sRCFile.c_str(), "Options", "ReturnAddress" ); 947*cdf0e10cSrcweir rSettings[ "SERVER" ] = get_profile_string( sRCFile.c_str(), "Options", "ProxyServer" ); 948*cdf0e10cSrcweir rSettings[ "PORT" ] = get_profile_string( sRCFile.c_str(), "Options", "ProxyPort" ); 949*cdf0e10cSrcweir rSettings[ "USEPROXY" ] = get_profile_string( sRCFile.c_str(), "Options", "UseProxy" ); 950*cdf0e10cSrcweir rSettings[ "CONTACT" ] = get_profile_string( sRCFile.c_str(), "Options", "AllowContact" ); 951*cdf0e10cSrcweir rSettings[ "DESCRIPTION" ] = ""; 952*cdf0e10cSrcweir rSettings[ "TITLE" ] = ""; 953*cdf0e10cSrcweir } 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir static void read_settings_from_environment( hash_map< string, string >& rSettings ) 956*cdf0e10cSrcweir { 957*cdf0e10cSrcweir string strEnv; 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_RETURNADDRESS" ); 960*cdf0e10cSrcweir if ( strEnv.length() ) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir rSettings[ "EMAIL" ] = strEnv; 963*cdf0e10cSrcweir if ( !(rSettings.find( "CONTACT" )->second).length() ) 964*cdf0e10cSrcweir rSettings[ "CONTACT" ] = "true"; 965*cdf0e10cSrcweir } 966*cdf0e10cSrcweir else if ( !(rSettings.find( "CONTACT" )->second).length() ) 967*cdf0e10cSrcweir rSettings[ "CONTACT" ] = "false"; 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_HTTPPROXYSERVER" ); 971*cdf0e10cSrcweir if ( strEnv.length() ) 972*cdf0e10cSrcweir rSettings[ "SERVER" ] = strEnv; 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_HTTPPROXYPORT" ); 975*cdf0e10cSrcweir if ( strEnv.length() ) 976*cdf0e10cSrcweir rSettings[ "PORT" ] = strEnv; 977*cdf0e10cSrcweir 978*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_HTTPCONNECTIONTYPE" ); 979*cdf0e10cSrcweir if ( strEnv.length() ) 980*cdf0e10cSrcweir rSettings[ "USEPROXY" ] = 0 == strcasecmp( strEnv.c_str(), "MANUALPROXY" ) ? "true" : "false"; 981*cdf0e10cSrcweir 982*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_BODYFILE" ); 983*cdf0e10cSrcweir if ( strEnv.length() ) 984*cdf0e10cSrcweir rSettings[ "DESCRIPTION" ] = read_from_file( strEnv ); 985*cdf0e10cSrcweir 986*cdf0e10cSrcweir strEnv = get_environment_string( "ERRORREPORT_SUBJECT" ); 987*cdf0e10cSrcweir if ( strEnv.length() ) 988*cdf0e10cSrcweir rSettings[ "TITLE" ] = strEnv; 989*cdf0e10cSrcweir } 990*cdf0e10cSrcweir 991*cdf0e10cSrcweir static bool setup_version() 992*cdf0e10cSrcweir { 993*cdf0e10cSrcweir if ( !getenv( "PRODUCTNAME" ) ) 994*cdf0e10cSrcweir { 995*cdf0e10cSrcweir string productkey = get_profile_string( "bootstraprc", "Bootstrap", "ProductKey" ); 996*cdf0e10cSrcweir 997*cdf0e10cSrcweir g_strProductKey = productkey; 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir if ( productkey.length() ) 1000*cdf0e10cSrcweir { 1001*cdf0e10cSrcweir static string productname; 1002*cdf0e10cSrcweir static string productversion; 1003*cdf0e10cSrcweir string::size_type iSpace = productkey.find( ' ', 0 ); 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir if ( string::npos != iSpace ) 1006*cdf0e10cSrcweir { 1007*cdf0e10cSrcweir productname = productkey.substr( 0, iSpace ); 1008*cdf0e10cSrcweir productversion = productkey.substr( iSpace + 1, string::npos ); 1009*cdf0e10cSrcweir } 1010*cdf0e10cSrcweir else 1011*cdf0e10cSrcweir productname = productkey; 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir productname.insert( 0, "PRODUCTNAME=" ); 1014*cdf0e10cSrcweir putenv( (char *)productname.c_str() ); 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir productversion.insert( 0, "PRODUCTVERSION=" ); 1017*cdf0e10cSrcweir putenv( (char *)productversion.c_str() ); 1018*cdf0e10cSrcweir } 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir g_buildid = get_profile_string( "versionrc", "Version", "BuildId" ); 1022*cdf0e10cSrcweir g_strDefaultLanguage = get_script_string( "instdb.ins", "DefaultLanguage" ); 1023*cdf0e10cSrcweir 1024*cdf0e10cSrcweir g_strReportServer = get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportServer" ); 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir string strReportPort = get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportPort", "80" ); 1027*cdf0e10cSrcweir char *endptr = NULL; 1028*cdf0e10cSrcweir unsigned short uReportPort = (unsigned short)strtoul( strReportPort.c_str(), &endptr, 10 ); 1029*cdf0e10cSrcweir g_uReportPort = uReportPort ? uReportPort : 80; 1030*cdf0e10cSrcweir 1031*cdf0e10cSrcweir return 0 != g_strReportServer.length(); 1032*cdf0e10cSrcweir } 1033*cdf0e10cSrcweir 1034*cdf0e10cSrcweir #if 0 1035*cdf0e10cSrcweir // Use gconftool-2 to determine if gnome accessiblity is enabled 1036*cdf0e10cSrcweir // unused 1037*cdf0e10cSrcweir static bool get_accessibility_state() 1038*cdf0e10cSrcweir { 1039*cdf0e10cSrcweir bool bAccessible = false; 1040*cdf0e10cSrcweir FILE *fin = popen( "gconftool-2 -g /desktop/gnome/interface/accessibility", "r"); 1041*cdf0e10cSrcweir 1042*cdf0e10cSrcweir if ( fin ) 1043*cdf0e10cSrcweir { 1044*cdf0e10cSrcweir char buffer[sizeof("true")]; 1045*cdf0e10cSrcweir 1046*cdf0e10cSrcweir bAccessible = fgets( buffer, sizeof(buffer), fin ) && 0 == strcmp( buffer, "true" ); 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir pclose( fin ); 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir 1051*cdf0e10cSrcweir return bAccessible; 1052*cdf0e10cSrcweir } 1053*cdf0e10cSrcweir #endif 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir int main( int argc, char** argv ) 1056*cdf0e10cSrcweir { 1057*cdf0e10cSrcweir freopen( "/dev/null", "w", stderr ); 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir setup_program_dir( argv[0] ); 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir // Don't start if accessiblity is enabled or report server is not given 1062*cdf0e10cSrcweir 1063*cdf0e10cSrcweir if ( setup_version() ) 1064*cdf0e10cSrcweir { 1065*cdf0e10cSrcweir /*long pid =*/ setup_commandline_arguments( argc, argv, &g_signal ); 1066*cdf0e10cSrcweir 1067*cdf0e10cSrcweir if ( g_bLoadReport ) 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir load_crash_data(); 1070*cdf0e10cSrcweir } 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir if ( g_bSendReport ) 1073*cdf0e10cSrcweir { 1074*cdf0e10cSrcweir hash_map< string, string > aDialogSettings; 1075*cdf0e10cSrcweir 1076*cdf0e10cSrcweir read_settings( aDialogSettings ); 1077*cdf0e10cSrcweir read_settings_from_environment( aDialogSettings ); 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir send_crash_report( aDialogSettings ); 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir else 1082*cdf0e10cSrcweir { 1083*cdf0e10cSrcweir hash_map< string, string > aDialogSettings; 1084*cdf0e10cSrcweir 1085*cdf0e10cSrcweir read_settings( aDialogSettings ); 1086*cdf0e10cSrcweir read_settings_from_environment( aDialogSettings ); 1087*cdf0e10cSrcweir 1088*cdf0e10cSrcweir write_crash_data(); 1089*cdf0e10cSrcweir write_report( aDialogSettings ); 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir string sPreviewFile = get_home_dir(); 1092*cdf0e10cSrcweir sPreviewFile += "/"; 1093*cdf0e10cSrcweir sPreviewFile += string(PRVFILE); 1094*cdf0e10cSrcweir 1095*cdf0e10cSrcweir FILE *fpout = fopen( sPreviewFile.c_str(), "w+" ); 1096*cdf0e10cSrcweir if ( fpout ) 1097*cdf0e10cSrcweir { 1098*cdf0e10cSrcweir FILE *fpin = fopen( g_szReportFile, "r" ); 1099*cdf0e10cSrcweir if ( fpin ) 1100*cdf0e10cSrcweir { 1101*cdf0e10cSrcweir fcopy( fpout, fpin ); 1102*cdf0e10cSrcweir fclose( fpin ); 1103*cdf0e10cSrcweir } 1104*cdf0e10cSrcweir fclose( fpout ); 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir 1107*cdf0e10cSrcweir unlink( g_szReportFile ); 1108*cdf0e10cSrcweir } 1109*cdf0e10cSrcweir 1110*cdf0e10cSrcweir if ( g_bLoadReport ) 1111*cdf0e10cSrcweir { 1112*cdf0e10cSrcweir unlink( g_strXMLFileName.c_str() ); 1113*cdf0e10cSrcweir unlink( g_strChecksumFileName.c_str() ); 1114*cdf0e10cSrcweir } 1115*cdf0e10cSrcweir 1116*cdf0e10cSrcweir unlink( g_szStackFile ); 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir return 0; 1119*cdf0e10cSrcweir } 1120*cdf0e10cSrcweir 1121*cdf0e10cSrcweir return -1; 1122*cdf0e10cSrcweir } 1123