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