1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
29 #include <sys/utsname.h>
36 #include <sys/socket.h>
47 #if defined (LINUX) || (FREEBSD)
48 #include <netinet/in.h>
53 #define closesocket close
54 #define SOCKET_ERROR -1
57 const char *basename( const char *filename
)
59 const char *pSlash
= strrchr( filename
, '/' );
61 return pSlash
? pSlash
+ 1 : pSlash
;
67 static bool g_bNoUI
= false;
68 static bool g_bSendReport
= false;
69 static bool g_bLoadReport
= false;
71 static bool g_bDebugMode
= false;
72 static int g_signal
= 0;
74 static string g_strProductKey
;
75 static string g_strReportServer
;
76 static unsigned short g_uReportPort
= 80;
77 static string g_buildid
;
78 static string g_strDefaultLanguage
;
79 static string g_strXMLFileName
;
80 static string g_strPStackFileName
;
81 static string g_strChecksumFileName
;
82 static string g_strProgramDir
;
84 static char g_szStackFile
[L_tmpnam
] = "";
85 static char g_szDescriptionFile
[2048] = "";
86 static char g_szReportFile
[2048] = "";
88 #define SO_CRASHREPORT_MAIL "so-report@sun.com"
89 #define PSTACK_CMD "pstack %d"
92 #define PMAP_CMD "cat /proc/%d/maps"
94 #define PMAP_CMD "pmap %d"
97 #define REPORT_SERVER (g_strReportServer.c_str())
98 #define REPORT_PORT g_uReportPort
100 static string
getprogramdir()
102 return g_strProgramDir
;
105 static const char *getlocale()
107 const char * locale
= getenv( "LC_ALL" );
110 locale
= getenv( "LC_CTYPE" );
113 locale
= getenv( "LANG" );
121 static const char *get_home_dir()
123 struct passwd
*ppwd
= getpwuid( getuid() );
125 return ppwd
? (ppwd
->pw_dir
? ppwd
->pw_dir
: "/") : "/";
128 static string
trim_string( const string
& rString
)
130 string temp
= rString
;
132 while ( temp
.length() && (temp
[0] == ' ' || temp
[0] == '\t') )
135 string::size_type len
= temp
.length();
137 while ( len
&& (temp
[len
-1] == ' ' || temp
[len
-1] == '\t') )
139 temp
.erase( len
- 1, 1 );
146 static string
xml_encode( const string
&rString
)
148 string temp
= rString
;
149 string::size_type pos
= 0;
151 // First replace all occurences of '&' because it may occur in further
152 // encoded chardters too
154 for( pos
= 0; (pos
= temp
.find( '&', pos
)) != string::npos
; pos
+= 4 )
155 temp
.replace( pos
, 1, "&" );
157 for( pos
= 0; (pos
= temp
.find( '<', pos
)) != string::npos
; pos
+= 4 )
158 temp
.replace( pos
, 1, "<" );
160 for( pos
= 0; (pos
= temp
.find( '>', pos
)) != string::npos
; pos
+= 4 )
161 temp
.replace( pos
, 1, ">" );
166 static size_t fcopy( FILE *fpout
, FILE *fpin
)
170 size_t nBytesWritten
= 0;
172 while ( 0 != (nBytes
= fread( buffer
, 1, sizeof(buffer
), fpin
)) )
174 nBytesWritten
+= fwrite( buffer
, 1, nBytes
, fpout
);
177 return nBytesWritten
;
181 writes the report to a temp-file
182 from which it can be reviewed and sent
185 bool write_report( const hash_map
< string
, string
>& rSettings
)
187 FILE *fp
= fopen( tmpnam( g_szReportFile
), "w" );
188 const char *pszUserType
= getenv( "STAROFFICE_USERTYPE" );
191 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
192 "<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n"
193 "<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\"%s\">\n"
194 "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\"%s\" email=\"%s\">\n"
195 "<reportmail:title>%s</reportmail:title>\n"
196 "<reportmail:attachment name=\"description.txt\" media-type=\"text/plain\" class=\"UserComment\"/>\n"
197 "<reportmail:attachment name=\"stack.txt\" media-type=\"text/plain\" class=\"pstack output\"/>\n"
198 "</reportmail:mail>\n"
199 "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" build=\"%s\" platform=\"%s\" language=\"%s\" exceptiontype=\"%d\" product=\"%s\" procpath=\"%s\"/>\n"
201 pszUserType
? xml_encode( pszUserType
).c_str() : "",
202 xml_encode(rSettings
.find( "CONTACT" )->second
).c_str(),
203 xml_encode(rSettings
.find( "EMAIL" )->second
).c_str(),
204 xml_encode(rSettings
.find( "TITLE" )->second
).c_str(),
205 g_buildid
.length() ? xml_encode( g_buildid
).c_str() : "unknown",
207 g_strDefaultLanguage
.c_str(),
209 g_strProductKey
.length() ? xml_encode(g_strProductKey
).c_str() : "unknown",
210 xml_encode(getprogramdir()).c_str()
215 memset( &info
, 0, sizeof(info
) );
219 "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
220 "<systeminfo:System name=\"%s\" version=\"%s\" build=\"%s\" locale=\"%s\"/>\n"
222 xml_encode( info
.sysname
).c_str(),
223 xml_encode( info
.version
).c_str(),
224 xml_encode( info
.release
).c_str(),
225 xml_encode( getlocale() ).c_str()
227 fprintf( fp
, "<systeminfo:CPU type=\"%s\"/>\n", xml_encode( info
.machine
).c_str() );
228 fprintf( fp
, "</systeminfo:systeminfo>\n" );
230 FILE *fpxml
= fopen( g_strXMLFileName
.c_str(), "r" );
237 FILE *fpchk
= fopen( g_strChecksumFileName
.c_str(), "r" );
244 fprintf( fp
, "</errormail:errormail>\n" );
252 bool write_description( const hash_map
< string
, string
>& rSettings
)
254 bool bSuccess
= false;
255 FILE *fp
= fopen( tmpnam( g_szDescriptionFile
), "w" );
260 fprintf( fp
, "\xEF\xBB\xBF" );
261 fprintf( fp
, "%s\n", rSettings
.find( "DESCRIPTION" )->second
.c_str() );
270 static void printSettings( const hash_map
<string
,string
>& rSettings
)
272 printf( "Settings:\n" );
273 for( hash_map
<string
,string
>::const_iterator it
= rSettings
.begin(); it
!= rSettings
.end(); ++it
)
275 printf( "%s=\"%s\"\n", it
->first
.c_str(), it
->second
.c_str() );
280 bool save_crash_report( const string
& rFileName
, const hash_map
< string
, string
>& /*rSettings*/ )
282 bool bSuccess
= false;
283 FILE *fpout
= fopen( rFileName
.c_str(), "w" );
287 FILE *fpin
= fopen( g_szStackFile
, "r" );
293 while (fgets(buf
, sizeof(buf
), fpin
) != NULL
)
309 bool SendHTTPRequest(
311 const char *pszServer
,
312 unsigned short uPort
= 80,
313 const char *pszProxyServer
= NULL
,
314 unsigned short uProxyPort
= 8080 )
316 bool success
= false;
320 if ( pszProxyServer
)
321 hp
= gethostbyname( pszProxyServer
);
323 hp
= gethostbyname( pszServer
);
327 SOCKET s
= socket( AF_INET
, SOCK_STREAM
, 0 );
331 struct sockaddr_in address
;
333 memcpy(&(address
.sin_addr
.s_addr
), *(hp
->h_addr_list
),sizeof(struct in_addr
));
334 address
.sin_family
= AF_INET
;
336 if ( pszProxyServer
)
337 address
.sin_port
= ntohs( uProxyPort
);
339 address
.sin_port
= ntohs( uPort
);
341 if ( 0 == connect( s
, (struct sockaddr
*)&address
, sizeof(struct sockaddr_in
)) )
343 fseek( fp
, 0, SEEK_END
);
344 size_t length
= ftell( fp
);
345 fseek( fp
, 0, SEEK_SET
);
349 if ( pszProxyServer
)
351 "POST http://%s:%d/soap/servlet/rpcrouter HTTP/1.0\r\n"
352 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
353 "Content-Length: %d\r\n"
354 "SOAPAction: \"\"\r\n\r\n",
357 static_cast<int>(length
)
361 "POST /soap/servlet/rpcrouter HTTP/1.0\r\n"
362 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
363 "Content-Length: %d\r\n"
364 "SOAPAction: \"\"\r\n\r\n",
365 static_cast<int>(length
)
370 printf( "*** Sending HTTP request ***\n\n" );
374 if ( SOCKET_ERROR
!= send( s
, buffer
, strlen(buffer
), 0 ) )
380 nBytes
= fread( buffer
, 1, sizeof(buffer
), fp
);
385 fwrite( buffer
, 1, nBytes
, stdout
);
386 success
= SOCKET_ERROR
!= send( s
, buffer
, nBytes
, 0 );
388 } while( nBytes
&& success
);
393 printf( "*** Receiving HTTP response ***\n\n" );
395 memset( buffer
, 0, sizeof(buffer
) );
396 success
= SOCKET_ERROR
!= recv( s
, buffer
, sizeof(buffer
), 0 );
399 char szHTTPSignature
[sizeof(buffer
)] = "";
400 unsigned uHTTPReturnCode
= 0;
402 sscanf( buffer
, "%s %d ", szHTTPSignature
, &uHTTPReturnCode
);
403 success
= uHTTPReturnCode
== 200;
409 memset( buffer
, 0, sizeof(buffer
) );
410 } while ( 0 < recv( s
, buffer
, sizeof(buffer
), 0 ) );
423 static void WriteSOAPRequest( FILE *fp
)
426 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
427 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
428 "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
429 "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
430 "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
431 "xmlns:rds=\"urn:ReportDataService\"\n"
432 "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
433 "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
437 fprintf( fp
, "<rds:submitReport>\n" );
438 fprintf( fp
, "<body xsi:type=\"xsd:string\">This is an autogenerated crash report mail.</body>\n" );
439 fprintf( fp
, "<hash xsi:type=\"apache:Map\">\n" );
441 FILE *fpin
= fopen( g_szReportFile
, "r" );
446 "<key xsi:type=\"xsd:string\">reportmail.xml</key>\n"
447 "<value xsi:type=\"xsd:string\"><![CDATA[" );
449 fprintf( fp
, "]]></value></item>\n" );
453 fpin
= fopen( g_szDescriptionFile
, "r" );
458 "<key xsi:type=\"xsd:string\">description.txt</key>\n"
459 "<value xsi:type=\"xsd:string\"><![CDATA[" );
461 fprintf( fp
, "]]></value></item>\n" );
465 fpin
= fopen( g_szStackFile
, "r" );
470 "<key xsi:type=\"xsd:string\">stack.txt</key>\n"
471 "<value xsi:type=\"xsd:string\"><![CDATA[" );
473 fprintf( fp
, "]]></value></item>\n" );
479 "</rds:submitReport>\n"
481 "</SOAP-ENV:Envelope>\n"
490 unsigned short uPort
;
491 const char *pProxyServer
;
492 unsigned short uProxyPort
;
496 bool send_crash_report( const hash_map
< string
, string
>& rSettings
)
498 if ( 0 == strcasecmp( rSettings
.find( "CONTACT" )->second
.c_str(), "true" ) &&
499 !trim_string(rSettings
.find( "EMAIL" )->second
).length() )
506 const char *pProxyServer
= rSettings
.find( "SERVER" )->second
.c_str();
507 unsigned short uProxyPort
= (unsigned short)strtoul( rSettings
.find( "PORT" )->second
.c_str(), &endptr
, 10 );
509 bool bUseProxy
= !strcasecmp( "true", rSettings
.find( "USEPROXY" )->second
.c_str() );
512 write_description( rSettings
);
513 write_report( rSettings
);
515 bool bSuccess
= false;
517 FILE *fptemp
= tmpfile();
520 WriteSOAPRequest( fptemp
);
521 fseek( fptemp
, 0, SEEK_SET
);
523 bSuccess
= SendHTTPRequest(
525 REPORT_SERVER
, REPORT_PORT
,
526 bUseProxy
? pProxyServer
: NULL
,
527 uProxyPort
? uProxyPort
: 8080
534 unlink( g_szDescriptionFile
);
535 unlink( g_szReportFile
);
541 static bool append_file( const char *filename
, string
& rString
)
544 bool bSuccess
= false;
546 FILE *fp
= fopen( filename
, "r" );
550 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
552 rString
.append( buf
);
560 string
crash_get_details( const hash_map
< string
, string
>& rSettings
)
564 write_description( rSettings
);
565 write_report( rSettings
);
567 aRet
.append( rSettings
.find( "TITLE" )->second
.c_str() );
568 aRet
.append( "\n\n" );
569 append_file( g_szDescriptionFile
, aRet
);
570 aRet
.append( "\n\n-------\n\n" );
571 append_file( g_szReportFile
, aRet
);
572 aRet
.append( "\n\n-------\n\n" );
573 append_file( g_szStackFile
, aRet
);
575 unlink( g_szDescriptionFile
);
576 unlink( g_szReportFile
);
582 // ensure validity of program relative paths
583 static void setup_program_dir( const char* progname
)
585 char szCanonicProgPath
[PATH_MAX
];
588 if ( realpath( progname
, szCanonicProgPath
) )
590 string aDir
= szCanonicProgPath
;
592 size_t pos
= aDir
.rfind( '/' );
593 // FIXME: search PATH if necessary
594 assert( pos
!= string::npos
);
596 g_strProgramDir
= aDir
.substr( 0, pos
+ 1 );
598 chdir( aDir
.c_str() );
602 //*************************************************************************
604 static long setup_commandline_arguments( int argc
, char** argv
, int *pSignal
)
609 for ( int n
= 1; n
< argc
; n
++ )
611 if ( 0 == strcmp( argv
[n
], "-p" ) )
614 pid
= strtol( argv
[n
], NULL
, 0 );
616 else if ( 0 == strcmp( argv
[n
], "-s" ) )
619 signal
= strtol( argv
[n
], NULL
, 0 );
621 else if ( 0 == strcmp( argv
[n
], "-debug" ) )
625 else if ( 0 == strcmp( argv
[n
], "-xml" ) )
628 g_strXMLFileName
= argv
[n
];
630 else if ( 0 == strcmp( argv
[n
], "-stack" ) )
633 g_strPStackFileName
= argv
[n
];
635 else if ( 0 == strcmp( argv
[n
], "-chksum" ) )
638 g_strChecksumFileName
= argv
[n
];
640 else if ( 0 == strcmp( argv
[n
], "-noui" ) )
644 else if ( 0 == strcmp( argv
[n
], "-send" ) )
646 g_bSendReport
= true;
648 else if ( 0 == strcmp( argv
[n
], "-load" ) )
650 g_bLoadReport
= true;
652 else if ( argv
[n
] && strlen(argv
[n
]) )
655 "\n%s crash_report %s\n\n" \
656 "/?, -h[elp] %s\n\n" \
658 "%MSG_CMDLINE_USAGE%",
659 "%MSG_PARAM_PROCESSID%",
660 "%MSG_PARAM_HELP_DESCRIPTION%",
661 "%MSG_PARAM_PROCESSID%",
662 "%MSG_PARAM_PROCESSID_DESCRIPTION%"
673 //*************************************************************************
675 static bool read_line( FILE *fp
, string
& rLine
)
678 bool bSuccess
= false;
683 while ( !bEOL
&& fgets( szBuffer
, sizeof(szBuffer
), fp
) )
685 int len
= strlen(szBuffer
);
689 while ( len
&& szBuffer
[len
- 1] == '\n' )
695 line
.append( szBuffer
);
702 static string
get_script_string( const char *pFileName
, const char *pKeyName
)
704 FILE *fp
= fopen( pFileName
, "r" );
712 while ( read_line( fp
, line
) )
714 line
= trim_string( line
);
717 string::size_type iEqualSign
= line
.find( '=', 0 );
719 if ( iEqualSign
!= string::npos
)
721 string keyname
= line
.substr( 0, iEqualSign
);
722 keyname
= trim_string( keyname
);
724 string value
= line
.substr( iEqualSign
+ 1, string::npos
);
725 value
= trim_string( value
);
727 if ( value
.length() && '\"' == value
[0] )
731 string::size_type iQuotes
= value
.find( '"', 0 );
733 if ( iQuotes
!= string::npos
)
734 value
.erase( iQuotes
);
737 if ( 0 == strcasecmp( keyname
.c_str(), pKeyName
) )
751 static string
get_profile_string( const char *pFileName
, const char *pSectionName
, const char *pKeyName
, const char *pDefault
= NULL
)
753 FILE *fp
= fopen( pFileName
, "r" );
754 string retValue
= pDefault
? pDefault
: "";
761 while ( read_line( fp
, line
) )
763 line
= trim_string( line
);
765 if ( line
.length() && line
[0] == '[' )
768 string::size_type end
= line
.find( ']', 0 );
770 if ( string::npos
!= end
)
771 section
= trim_string( line
.substr( 0, end
) );
776 string::size_type iEqualSign
= line
.find( '=', 0 );
778 if ( iEqualSign
!= string::npos
)
780 string keyname
= line
.substr( 0, iEqualSign
);
781 keyname
= trim_string( keyname
);
783 string value
= line
.substr( iEqualSign
+ 1, string::npos
);
784 value
= trim_string( value
);
787 0 == strcasecmp( section
.c_str(), pSectionName
) &&
788 0 == strcasecmp( keyname
.c_str(), pKeyName
)
804 static string
get_environment_string( const char *pEnvName
)
806 const char *pEnvValue
= getenv( pEnvName
);
814 static string
read_from_file( const string
& rFileName
)
817 FILE *fp
= fopen( rFileName
.c_str(), "r" );
821 char buffer
[256 + 1];
824 while( 0 != ( nBytesRead
= fread( buffer
, 1, sizeof(buffer
) - 1, fp
) ) )
826 buffer
[nBytesRead
] = 0;
836 #define RCFILE ".crash_reportrc"
837 #define XMLFILE ".crash_report_frames"
838 #define CHKFILE ".crash_report_checksum"
839 #define LCKFILE ".crash_report_unsent"
840 #define PRVFILE ".crash_report_preview"
842 static void load_crash_data()
844 g_strXMLFileName
= get_home_dir();
845 g_strXMLFileName
+= "/";
846 g_strXMLFileName
+= string(XMLFILE
);
848 g_strChecksumFileName
= get_home_dir();
849 g_strChecksumFileName
+= "/";
850 g_strChecksumFileName
+= string(CHKFILE
);
853 static bool write_crash_data()
856 string sFile
= get_home_dir();
859 sFile
+= string(XMLFILE
);
861 FILE *fp
= fopen( sFile
.c_str(), "w" );
865 FILE *fpin
= fopen( g_strXMLFileName
.c_str(), "r" );
876 sFile
= get_home_dir();
879 sFile
+= string(CHKFILE
);
881 fp
= fopen( sFile
.c_str(), "w" );
885 FILE *fpin
= fopen( g_strChecksumFileName
.c_str(), "r" );
896 sFile
= get_home_dir();
899 sFile
+= string(LCKFILE
);
901 fp
= fopen( sFile
.c_str(), "w" );
905 fprintf( fp
, "Unsent\n" );
914 static bool write_settings( const hash_map
< string
, string
>& rSettings
)
916 bool success
= false;
917 string sRCFile
= get_home_dir();
920 sRCFile
+= string(RCFILE
);
922 FILE *fp
= fopen( sRCFile
.c_str(), "w" );
926 fprintf( fp
, "[Options]\n" );
927 fprintf( fp
, "UseProxy=%s\n", rSettings
.find( "USEPROXY" )->second
.c_str() );
928 fprintf( fp
, "ProxyServer=%s\n", rSettings
.find( "SERVER" )->second
.c_str() );
929 fprintf( fp
, "ProxyPort=%s\n", rSettings
.find( "PORT" )->second
.c_str() );
930 fprintf( fp
, "ReturnAddress=%s\n", rSettings
.find( "EMAIL" )->second
.c_str() );
931 fprintf( fp
, "AllowContact=%s\n", rSettings
.find( "CONTACT" )->second
.c_str() );
939 static void read_settings( hash_map
< string
, string
>& rSettings
)
941 string sRCFile
= get_home_dir();
944 sRCFile
+= string(RCFILE
);
946 rSettings
[ "EMAIL" ] = get_profile_string( sRCFile
.c_str(), "Options", "ReturnAddress" );
947 rSettings
[ "SERVER" ] = get_profile_string( sRCFile
.c_str(), "Options", "ProxyServer" );
948 rSettings
[ "PORT" ] = get_profile_string( sRCFile
.c_str(), "Options", "ProxyPort" );
949 rSettings
[ "USEPROXY" ] = get_profile_string( sRCFile
.c_str(), "Options", "UseProxy" );
950 rSettings
[ "CONTACT" ] = get_profile_string( sRCFile
.c_str(), "Options", "AllowContact" );
951 rSettings
[ "DESCRIPTION" ] = "";
952 rSettings
[ "TITLE" ] = "";
955 static void read_settings_from_environment( hash_map
< string
, string
>& rSettings
)
959 strEnv
= get_environment_string( "ERRORREPORT_RETURNADDRESS" );
960 if ( strEnv
.length() )
962 rSettings
[ "EMAIL" ] = strEnv
;
963 if ( !(rSettings
.find( "CONTACT" )->second
).length() )
964 rSettings
[ "CONTACT" ] = "true";
966 else if ( !(rSettings
.find( "CONTACT" )->second
).length() )
967 rSettings
[ "CONTACT" ] = "false";
970 strEnv
= get_environment_string( "ERRORREPORT_HTTPPROXYSERVER" );
971 if ( strEnv
.length() )
972 rSettings
[ "SERVER" ] = strEnv
;
974 strEnv
= get_environment_string( "ERRORREPORT_HTTPPROXYPORT" );
975 if ( strEnv
.length() )
976 rSettings
[ "PORT" ] = strEnv
;
978 strEnv
= get_environment_string( "ERRORREPORT_HTTPCONNECTIONTYPE" );
979 if ( strEnv
.length() )
980 rSettings
[ "USEPROXY" ] = 0 == strcasecmp( strEnv
.c_str(), "MANUALPROXY" ) ? "true" : "false";
982 strEnv
= get_environment_string( "ERRORREPORT_BODYFILE" );
983 if ( strEnv
.length() )
984 rSettings
[ "DESCRIPTION" ] = read_from_file( strEnv
);
986 strEnv
= get_environment_string( "ERRORREPORT_SUBJECT" );
987 if ( strEnv
.length() )
988 rSettings
[ "TITLE" ] = strEnv
;
991 static bool setup_version()
993 if ( !getenv( "PRODUCTNAME" ) )
995 string productkey
= get_profile_string( "bootstraprc", "Bootstrap", "ProductKey" );
997 g_strProductKey
= productkey
;
999 if ( productkey
.length() )
1001 static string productname
;
1002 static string productversion
;
1003 string::size_type iSpace
= productkey
.find( ' ', 0 );
1005 if ( string::npos
!= iSpace
)
1007 productname
= productkey
.substr( 0, iSpace
);
1008 productversion
= productkey
.substr( iSpace
+ 1, string::npos
);
1011 productname
= productkey
;
1013 productname
.insert( 0, "PRODUCTNAME=" );
1014 putenv( (char *)productname
.c_str() );
1016 productversion
.insert( 0, "PRODUCTVERSION=" );
1017 putenv( (char *)productversion
.c_str() );
1021 g_buildid
= get_profile_string( "versionrc", "Version", "BuildId" );
1022 g_strDefaultLanguage
= get_script_string( "instdb.ins", "DefaultLanguage" );
1024 g_strReportServer
= get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportServer" );
1026 string strReportPort
= get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportPort", "80" );
1027 char *endptr
= NULL
;
1028 unsigned short uReportPort
= (unsigned short)strtoul( strReportPort
.c_str(), &endptr
, 10 );
1029 g_uReportPort
= uReportPort
? uReportPort
: 80;
1031 return 0 != g_strReportServer
.length();
1035 // Use gconftool-2 to determine if gnome accessiblity is enabled
1037 static bool get_accessibility_state()
1039 bool bAccessible
= false;
1040 FILE *fin
= popen( "gconftool-2 -g /desktop/gnome/interface/accessibility", "r");
1044 char buffer
[sizeof("true")];
1046 bAccessible
= fgets( buffer
, sizeof(buffer
), fin
) && 0 == strcmp( buffer
, "true" );
1055 int main( int argc
, char** argv
)
1057 freopen( "/dev/null", "w", stderr
);
1059 setup_program_dir( argv
[0] );
1061 // Don't start if accessiblity is enabled or report server is not given
1063 if ( setup_version() )
1065 /*long pid =*/ setup_commandline_arguments( argc
, argv
, &g_signal
);
1067 if ( g_bLoadReport
)
1072 if ( g_bSendReport
)
1074 hash_map
< string
, string
> aDialogSettings
;
1076 read_settings( aDialogSettings
);
1077 read_settings_from_environment( aDialogSettings
);
1079 send_crash_report( aDialogSettings
);
1083 hash_map
< string
, string
> aDialogSettings
;
1085 read_settings( aDialogSettings
);
1086 read_settings_from_environment( aDialogSettings
);
1089 write_report( aDialogSettings
);
1091 string sPreviewFile
= get_home_dir();
1092 sPreviewFile
+= "/";
1093 sPreviewFile
+= string(PRVFILE
);
1095 FILE *fpout
= fopen( sPreviewFile
.c_str(), "w+" );
1098 FILE *fpin
= fopen( g_szReportFile
, "r" );
1101 fcopy( fpout
, fpin
);
1107 unlink( g_szReportFile
);
1110 if ( g_bLoadReport
)
1112 unlink( g_strXMLFileName
.c_str() );
1113 unlink( g_strChecksumFileName
.c_str() );
1116 unlink( g_szStackFile
);