1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: main.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #include <sys/utsname.h>
39 #include <sys/socket.h>
50 #if defined (LINUX) || (FREEBSD)
51 #include <netinet/in.h>
56 #define closesocket close
57 #define SOCKET_ERROR -1
60 const char *basename( const char *filename
)
62 const char *pSlash
= strrchr( filename
, '/' );
64 return pSlash
? pSlash
+ 1 : pSlash
;
70 static bool g_bNoUI
= false;
71 static bool g_bSendReport
= false;
72 static bool g_bLoadReport
= false;
74 static bool g_bDebugMode
= false;
75 static int g_signal
= 0;
77 static string g_strProductKey
;
78 static string g_strReportServer
;
79 static unsigned short g_uReportPort
= 80;
80 static string g_buildid
;
81 static string g_strDefaultLanguage
;
82 static string g_strXMLFileName
;
83 static string g_strPStackFileName
;
84 static string g_strChecksumFileName
;
85 static string g_strProgramDir
;
87 static char g_szStackFile
[L_tmpnam
] = "";
88 static char g_szDescriptionFile
[2048] = "";
89 static char g_szReportFile
[2048] = "";
91 #define SO_CRASHREPORT_MAIL "so-report@sun.com"
92 #define PSTACK_CMD "pstack %d"
95 #define PMAP_CMD "cat /proc/%d/maps"
97 #define PMAP_CMD "pmap %d"
100 #define REPORT_SERVER (g_strReportServer.c_str())
101 #define REPORT_PORT g_uReportPort
103 static string
getprogramdir()
105 return g_strProgramDir
;
108 static const char *getlocale()
110 const char * locale
= getenv( "LC_ALL" );
113 locale
= getenv( "LC_CTYPE" );
116 locale
= getenv( "LANG" );
124 static const char *get_home_dir()
126 struct passwd
*ppwd
= getpwuid( getuid() );
128 return ppwd
? (ppwd
->pw_dir
? ppwd
->pw_dir
: "/") : "/";
131 static string
trim_string( const string
& rString
)
133 string temp
= rString
;
135 while ( temp
.length() && temp
[0] == ' ' || temp
[0] == '\t' )
138 string::size_type len
= temp
.length();
140 while ( len
&& temp
[len
-1] == ' ' || temp
[len
-1] == '\t' )
142 temp
.erase( len
- 1, 1 );
149 static string
xml_encode( const string
&rString
)
151 string temp
= rString
;
152 string::size_type pos
= 0;
154 // First replace all occurences of '&' because it may occur in further
155 // encoded chardters too
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, "<" );
163 for( pos
= 0; (pos
= temp
.find( '>', pos
)) != string::npos
; pos
+= 4 )
164 temp
.replace( pos
, 1, ">" );
169 static size_t fcopy( FILE *fpout
, FILE *fpin
)
173 size_t nBytesWritten
= 0;
175 while ( 0 != (nBytes
= fread( buffer
, 1, sizeof(buffer
), fpin
)) )
177 nBytesWritten
+= fwrite( buffer
, 1, nBytes
, fpout
);
180 return nBytesWritten
;
184 writes the report to a temp-file
185 from which it can be reviewed and sent
188 bool write_report( const hash_map
< string
, string
>& rSettings
)
190 FILE *fp
= fopen( tmpnam( g_szReportFile
), "w" );
191 const char *pszUserType
= getenv( "STAROFFICE_USERTYPE" );
194 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
195 "<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n"
196 "<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\"%s\">\n"
197 "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\"%s\" email=\"%s\">\n"
198 "<reportmail:title>%s</reportmail:title>\n"
199 "<reportmail:attachment name=\"description.txt\" media-type=\"text/plain\" class=\"UserComment\"/>\n"
200 "<reportmail:attachment name=\"stack.txt\" media-type=\"text/plain\" class=\"pstack output\"/>\n"
201 "</reportmail:mail>\n"
202 "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" build=\"%s\" platform=\"%s\" language=\"%s\" exceptiontype=\"%d\" product=\"%s\" procpath=\"%s\"/>\n"
204 pszUserType
? xml_encode( pszUserType
).c_str() : "",
205 xml_encode(rSettings
.find( "CONTACT" )->second
).c_str(),
206 xml_encode(rSettings
.find( "EMAIL" )->second
).c_str(),
207 xml_encode(rSettings
.find( "TITLE" )->second
).c_str(),
208 g_buildid
.length() ? xml_encode( g_buildid
).c_str() : "unknown",
210 g_strDefaultLanguage
.c_str(),
212 g_strProductKey
.length() ? xml_encode(g_strProductKey
).c_str() : "unknown",
213 xml_encode(getprogramdir()).c_str()
218 memset( &info
, 0, sizeof(info
) );
222 "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
223 "<systeminfo:System name=\"%s\" version=\"%s\" build=\"%s\" locale=\"%s\"/>\n"
225 xml_encode( info
.sysname
).c_str(),
226 xml_encode( info
.version
).c_str(),
227 xml_encode( info
.release
).c_str(),
228 xml_encode( getlocale() ).c_str()
230 fprintf( fp
, "<systeminfo:CPU type=\"%s\"/>\n", xml_encode( info
.machine
).c_str() );
231 fprintf( fp
, "</systeminfo:systeminfo>\n" );
233 FILE *fpxml
= fopen( g_strXMLFileName
.c_str(), "r" );
240 FILE *fpchk
= fopen( g_strChecksumFileName
.c_str(), "r" );
247 fprintf( fp
, "</errormail:errormail>\n" );
255 bool write_description( const hash_map
< string
, string
>& rSettings
)
257 bool bSuccess
= false;
258 FILE *fp
= fopen( tmpnam( g_szDescriptionFile
), "w" );
263 fprintf( fp
, "\xEF\xBB\xBF" );
264 fprintf( fp
, "%s\n", rSettings
.find( "DESCRIPTION" )->second
.c_str() );
273 static void printSettings( const hash_map
<string
,string
>& rSettings
)
275 printf( "Settings:\n" );
276 for( hash_map
<string
,string
>::const_iterator it
= rSettings
.begin(); it
!= rSettings
.end(); ++it
)
278 printf( "%s=\"%s\"\n", it
->first
.c_str(), it
->second
.c_str() );
283 bool save_crash_report( const string
& rFileName
, const hash_map
< string
, string
>& /*rSettings*/ )
285 bool bSuccess
= false;
286 FILE *fpout
= fopen( rFileName
.c_str(), "w" );
290 FILE *fpin
= fopen( g_szStackFile
, "r" );
296 while (fgets(buf
, sizeof(buf
), fpin
) != NULL
)
312 bool SendHTTPRequest(
314 const char *pszServer
,
315 unsigned short uPort
= 80,
316 const char *pszProxyServer
= NULL
,
317 unsigned short uProxyPort
= 8080 )
319 bool success
= false;
323 if ( pszProxyServer
)
324 hp
= gethostbyname( pszProxyServer
);
326 hp
= gethostbyname( pszServer
);
330 SOCKET s
= socket( AF_INET
, SOCK_STREAM
, 0 );
334 struct sockaddr_in address
;
336 memcpy(&(address
.sin_addr
.s_addr
), *(hp
->h_addr_list
),sizeof(struct in_addr
));
337 address
.sin_family
= AF_INET
;
339 if ( pszProxyServer
)
340 address
.sin_port
= ntohs( uProxyPort
);
342 address
.sin_port
= ntohs( uPort
);
344 if ( 0 == connect( s
, (struct sockaddr
*)&address
, sizeof(struct sockaddr_in
)) )
346 fseek( fp
, 0, SEEK_END
);
347 size_t length
= ftell( fp
);
348 fseek( fp
, 0, SEEK_SET
);
352 if ( pszProxyServer
)
354 "POST http://%s:%d/soap/servlet/rpcrouter HTTP/1.0\r\n"
355 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
356 "Content-Length: %d\r\n"
357 "SOAPAction: \"\"\r\n\r\n",
364 "POST /soap/servlet/rpcrouter HTTP/1.0\r\n"
365 "Content-Type: text/xml; charset=\"utf-8\"\r\n"
366 "Content-Length: %d\r\n"
367 "SOAPAction: \"\"\r\n\r\n",
373 printf( "*** Sending HTTP request ***\n\n" );
377 if ( SOCKET_ERROR
!= send( s
, buffer
, strlen(buffer
), 0 ) )
383 nBytes
= fread( buffer
, 1, sizeof(buffer
), fp
);
388 fwrite( buffer
, 1, nBytes
, stdout
);
389 success
= SOCKET_ERROR
!= send( s
, buffer
, nBytes
, 0 );
391 } while( nBytes
&& success
);
396 printf( "*** Receiving HTTP response ***\n\n" );
398 memset( buffer
, 0, sizeof(buffer
) );
399 success
= SOCKET_ERROR
!= recv( s
, buffer
, sizeof(buffer
), 0 );
402 char szHTTPSignature
[sizeof(buffer
)] = "";
403 unsigned uHTTPReturnCode
= 0;
405 sscanf( buffer
, "%s %d ", szHTTPSignature
, &uHTTPReturnCode
);
406 success
= uHTTPReturnCode
== 200;
412 memset( buffer
, 0, sizeof(buffer
) );
413 } while ( 0 < recv( s
, buffer
, sizeof(buffer
), 0 ) );
426 static void WriteSOAPRequest( FILE *fp
)
429 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
430 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
431 "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
432 "xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n"
433 "xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\n"
434 "xmlns:rds=\"urn:ReportDataService\"\n"
435 "xmlns:apache=\"http://xml.apache.org/xml-soap\"\n"
436 "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
440 fprintf( fp
, "<rds:submitReport>\n" );
441 fprintf( fp
, "<body xsi:type=\"xsd:string\">This is an autogenerated crash report mail.</body>\n" );
442 fprintf( fp
, "<hash xsi:type=\"apache:Map\">\n" );
444 FILE *fpin
= fopen( g_szReportFile
, "r" );
449 "<key xsi:type=\"xsd:string\">reportmail.xml</key>\n"
450 "<value xsi:type=\"xsd:string\"><![CDATA[" );
452 fprintf( fp
, "]]></value></item>\n" );
456 fpin
= fopen( g_szDescriptionFile
, "r" );
461 "<key xsi:type=\"xsd:string\">description.txt</key>\n"
462 "<value xsi:type=\"xsd:string\"><![CDATA[" );
464 fprintf( fp
, "]]></value></item>\n" );
468 fpin
= fopen( g_szStackFile
, "r" );
473 "<key xsi:type=\"xsd:string\">stack.txt</key>\n"
474 "<value xsi:type=\"xsd:string\"><![CDATA[" );
476 fprintf( fp
, "]]></value></item>\n" );
482 "</rds:submitReport>\n"
484 "</SOAP-ENV:Envelope>\n"
493 unsigned short uPort
;
494 const char *pProxyServer
;
495 unsigned short uProxyPort
;
499 bool send_crash_report( const hash_map
< string
, string
>& rSettings
)
501 if ( 0 == strcasecmp( rSettings
.find( "CONTACT" )->second
.c_str(), "true" ) &&
502 !trim_string(rSettings
.find( "EMAIL" )->second
).length() )
509 const char *pProxyServer
= rSettings
.find( "SERVER" )->second
.c_str();
510 unsigned short uProxyPort
= (unsigned short)strtoul( rSettings
.find( "PORT" )->second
.c_str(), &endptr
, 10 );
512 bool bUseProxy
= !strcasecmp( "true", rSettings
.find( "USEPROXY" )->second
.c_str() );
515 write_description( rSettings
);
516 write_report( rSettings
);
518 bool bSuccess
= false;
520 FILE *fptemp
= tmpfile();
523 WriteSOAPRequest( fptemp
);
524 fseek( fptemp
, 0, SEEK_SET
);
526 bSuccess
= SendHTTPRequest(
528 REPORT_SERVER
, REPORT_PORT
,
529 bUseProxy
? pProxyServer
: NULL
,
530 uProxyPort
? uProxyPort
: 8080
537 unlink( g_szDescriptionFile
);
538 unlink( g_szReportFile
);
544 static bool append_file( const char *filename
, string
& rString
)
547 bool bSuccess
= false;
549 FILE *fp
= fopen( filename
, "r" );
553 while (fgets(buf
, sizeof(buf
), fp
) != NULL
)
555 rString
.append( buf
);
563 string
crash_get_details( const hash_map
< string
, string
>& rSettings
)
567 write_description( rSettings
);
568 write_report( rSettings
);
570 aRet
.append( rSettings
.find( "TITLE" )->second
.c_str() );
571 aRet
.append( "\n\n" );
572 append_file( g_szDescriptionFile
, aRet
);
573 aRet
.append( "\n\n-------\n\n" );
574 append_file( g_szReportFile
, aRet
);
575 aRet
.append( "\n\n-------\n\n" );
576 append_file( g_szStackFile
, aRet
);
578 unlink( g_szDescriptionFile
);
579 unlink( g_szReportFile
);
585 // ensure validity of program relative paths
586 static void setup_program_dir( const char* progname
)
588 char szCanonicProgPath
[PATH_MAX
];
591 if ( realpath( progname
, szCanonicProgPath
) )
593 string aDir
= szCanonicProgPath
;
595 size_t pos
= aDir
.rfind( '/' );
596 // FIXME: search PATH if necessary
597 assert( pos
!= string::npos
);
599 g_strProgramDir
= aDir
.substr( 0, pos
+ 1 );
601 chdir( aDir
.c_str() );
605 //*************************************************************************
607 static long setup_commandline_arguments( int argc
, char** argv
, int *pSignal
)
612 for ( int n
= 1; n
< argc
; n
++ )
614 if ( 0 == strcmp( argv
[n
], "-p" ) )
617 pid
= strtol( argv
[n
], NULL
, 0 );
619 else if ( 0 == strcmp( argv
[n
], "-s" ) )
622 signal
= strtol( argv
[n
], NULL
, 0 );
624 else if ( 0 == strcmp( argv
[n
], "-debug" ) )
628 else if ( 0 == strcmp( argv
[n
], "-xml" ) )
631 g_strXMLFileName
= argv
[n
];
633 else if ( 0 == strcmp( argv
[n
], "-stack" ) )
636 g_strPStackFileName
= argv
[n
];
638 else if ( 0 == strcmp( argv
[n
], "-chksum" ) )
641 g_strChecksumFileName
= argv
[n
];
643 else if ( 0 == strcmp( argv
[n
], "-noui" ) )
647 else if ( 0 == strcmp( argv
[n
], "-send" ) )
649 g_bSendReport
= true;
651 else if ( 0 == strcmp( argv
[n
], "-load" ) )
653 g_bLoadReport
= true;
655 else if ( argv
[n
] && strlen(argv
[n
]) )
658 "\n%s crash_report %s\n\n" \
659 "/?, -h[elp] %s\n\n" \
661 "%MSG_CMDLINE_USAGE%",
662 "%MSG_PARAM_PROCESSID%",
663 "%MSG_PARAM_HELP_DESCRIPTION%",
664 "%MSG_PARAM_PROCESSID%",
665 "%MSG_PARAM_PROCESSID_DESCRIPTION%"
676 //*************************************************************************
678 static bool read_line( FILE *fp
, string
& rLine
)
681 bool bSuccess
= false;
686 while ( !bEOL
&& fgets( szBuffer
, sizeof(szBuffer
), fp
) )
688 int len
= strlen(szBuffer
);
692 while ( len
&& szBuffer
[len
- 1] == '\n' )
698 line
.append( szBuffer
);
705 static string
get_script_string( const char *pFileName
, const char *pKeyName
)
707 FILE *fp
= fopen( pFileName
, "r" );
715 while ( read_line( fp
, line
) )
717 line
= trim_string( line
);
720 string::size_type iEqualSign
= line
.find( '=', 0 );
722 if ( iEqualSign
!= string::npos
)
724 string keyname
= line
.substr( 0, iEqualSign
);
725 keyname
= trim_string( keyname
);
727 string value
= line
.substr( iEqualSign
+ 1, string::npos
);
728 value
= trim_string( value
);
730 if ( value
.length() && '\"' == value
[0] )
734 string::size_type iQuotes
= value
.find( '"', 0 );
736 if ( iQuotes
!= string::npos
)
737 value
.erase( iQuotes
);
740 if ( 0 == strcasecmp( keyname
.c_str(), pKeyName
) )
754 static string
get_profile_string( const char *pFileName
, const char *pSectionName
, const char *pKeyName
, const char *pDefault
= NULL
)
756 FILE *fp
= fopen( pFileName
, "r" );
757 string retValue
= pDefault
? pDefault
: "";
764 while ( read_line( fp
, line
) )
766 line
= trim_string( line
);
768 if ( line
.length() && line
[0] == '[' )
771 string::size_type end
= line
.find( ']', 0 );
773 if ( string::npos
!= end
)
774 section
= trim_string( line
.substr( 0, end
) );
779 string::size_type iEqualSign
= line
.find( '=', 0 );
781 if ( iEqualSign
!= string::npos
)
783 string keyname
= line
.substr( 0, iEqualSign
);
784 keyname
= trim_string( keyname
);
786 string value
= line
.substr( iEqualSign
+ 1, string::npos
);
787 value
= trim_string( value
);
790 0 == strcasecmp( section
.c_str(), pSectionName
) &&
791 0 == strcasecmp( keyname
.c_str(), pKeyName
)
807 static string
get_environment_string( const char *pEnvName
)
809 const char *pEnvValue
= getenv( pEnvName
);
817 static string
read_from_file( const string
& rFileName
)
820 FILE *fp
= fopen( rFileName
.c_str(), "r" );
824 char buffer
[256 + 1];
827 while( 0 != ( nBytesRead
= fread( buffer
, 1, sizeof(buffer
) - 1, fp
) ) )
829 buffer
[nBytesRead
] = 0;
839 #define RCFILE ".crash_reportrc"
840 #define XMLFILE ".crash_report_frames"
841 #define CHKFILE ".crash_report_checksum"
842 #define LCKFILE ".crash_report_unsent"
843 #define PRVFILE ".crash_report_preview"
845 static void load_crash_data()
847 g_strXMLFileName
= get_home_dir();
848 g_strXMLFileName
+= "/";
849 g_strXMLFileName
+= string(XMLFILE
);
851 g_strChecksumFileName
= get_home_dir();
852 g_strChecksumFileName
+= "/";
853 g_strChecksumFileName
+= string(CHKFILE
);
856 static bool write_crash_data()
859 string sFile
= get_home_dir();
862 sFile
+= string(XMLFILE
);
864 FILE *fp
= fopen( sFile
.c_str(), "w" );
868 FILE *fpin
= fopen( g_strXMLFileName
.c_str(), "r" );
879 sFile
= get_home_dir();
882 sFile
+= string(CHKFILE
);
884 fp
= fopen( sFile
.c_str(), "w" );
888 FILE *fpin
= fopen( g_strChecksumFileName
.c_str(), "r" );
899 sFile
= get_home_dir();
902 sFile
+= string(LCKFILE
);
904 fp
= fopen( sFile
.c_str(), "w" );
908 fprintf( fp
, "Unsent\n" );
917 static bool write_settings( const hash_map
< string
, string
>& rSettings
)
919 bool success
= false;
920 string sRCFile
= get_home_dir();
923 sRCFile
+= string(RCFILE
);
925 FILE *fp
= fopen( sRCFile
.c_str(), "w" );
929 fprintf( fp
, "[Options]\n" );
930 fprintf( fp
, "UseProxy=%s\n", rSettings
.find( "USEPROXY" )->second
.c_str() );
931 fprintf( fp
, "ProxyServer=%s\n", rSettings
.find( "SERVER" )->second
.c_str() );
932 fprintf( fp
, "ProxyPort=%s\n", rSettings
.find( "PORT" )->second
.c_str() );
933 fprintf( fp
, "ReturnAddress=%s\n", rSettings
.find( "EMAIL" )->second
.c_str() );
934 fprintf( fp
, "AllowContact=%s\n", rSettings
.find( "CONTACT" )->second
.c_str() );
942 static void read_settings( hash_map
< string
, string
>& rSettings
)
944 string sRCFile
= get_home_dir();
947 sRCFile
+= string(RCFILE
);
949 rSettings
[ "EMAIL" ] = get_profile_string( sRCFile
.c_str(), "Options", "ReturnAddress" );
950 rSettings
[ "SERVER" ] = get_profile_string( sRCFile
.c_str(), "Options", "ProxyServer" );
951 rSettings
[ "PORT" ] = get_profile_string( sRCFile
.c_str(), "Options", "ProxyPort" );
952 rSettings
[ "USEPROXY" ] = get_profile_string( sRCFile
.c_str(), "Options", "UseProxy" );
953 rSettings
[ "CONTACT" ] = get_profile_string( sRCFile
.c_str(), "Options", "AllowContact" );
954 rSettings
[ "DESCRIPTION" ] = "";
955 rSettings
[ "TITLE" ] = "";
958 static void read_settings_from_environment( hash_map
< string
, string
>& rSettings
)
962 strEnv
= get_environment_string( "ERRORREPORT_RETURNADDRESS" );
963 if ( strEnv
.length() )
965 rSettings
[ "EMAIL" ] = strEnv
;
966 if ( !(rSettings
.find( "CONTACT" )->second
).length() )
967 rSettings
[ "CONTACT" ] = "true";
969 else if ( !(rSettings
.find( "CONTACT" )->second
).length() )
970 rSettings
[ "CONTACT" ] = "false";
973 strEnv
= get_environment_string( "ERRORREPORT_HTTPPROXYSERVER" );
974 if ( strEnv
.length() )
975 rSettings
[ "SERVER" ] = strEnv
;
977 strEnv
= get_environment_string( "ERRORREPORT_HTTPPROXYPORT" );
978 if ( strEnv
.length() )
979 rSettings
[ "PORT" ] = strEnv
;
981 strEnv
= get_environment_string( "ERRORREPORT_HTTPCONNECTIONTYPE" );
982 if ( strEnv
.length() )
983 rSettings
[ "USEPROXY" ] = 0 == strcasecmp( strEnv
.c_str(), "MANUALPROXY" ) ? "true" : "false";
985 strEnv
= get_environment_string( "ERRORREPORT_BODYFILE" );
986 if ( strEnv
.length() )
987 rSettings
[ "DESCRIPTION" ] = read_from_file( strEnv
);
989 strEnv
= get_environment_string( "ERRORREPORT_SUBJECT" );
990 if ( strEnv
.length() )
991 rSettings
[ "TITLE" ] = strEnv
;
994 static bool setup_version()
996 if ( !getenv( "PRODUCTNAME" ) )
998 string productkey
= get_profile_string( "bootstraprc", "Bootstrap", "ProductKey" );
1000 g_strProductKey
= productkey
;
1002 if ( productkey
.length() )
1004 static string productname
;
1005 static string productversion
;
1006 string::size_type iSpace
= productkey
.find( ' ', 0 );
1008 if ( string::npos
!= iSpace
)
1010 productname
= productkey
.substr( 0, iSpace
);
1011 productversion
= productkey
.substr( iSpace
+ 1, string::npos
);
1014 productname
= productkey
;
1016 productname
.insert( 0, "PRODUCTNAME=" );
1017 putenv( (char *)productname
.c_str() );
1019 productversion
.insert( 0, "PRODUCTVERSION=" );
1020 putenv( (char *)productversion
.c_str() );
1024 g_buildid
= get_profile_string( "versionrc", "Version", "BuildId" );
1025 g_strDefaultLanguage
= get_script_string( "instdb.ins", "DefaultLanguage" );
1027 g_strReportServer
= get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportServer" );
1029 string strReportPort
= get_profile_string( "bootstraprc", "ErrorReport", "ErrorReportPort", "80" );
1030 char *endptr
= NULL
;
1031 unsigned short uReportPort
= (unsigned short)strtoul( strReportPort
.c_str(), &endptr
, 10 );
1032 g_uReportPort
= uReportPort
? uReportPort
: 80;
1034 return 0 != g_strReportServer
.length();
1038 // Use gconftool-2 to determine if gnome accessiblity is enabled
1040 static bool get_accessibility_state()
1042 bool bAccessible
= false;
1043 FILE *fin
= popen( "gconftool-2 -g /desktop/gnome/interface/accessibility", "r");
1047 char buffer
[sizeof("true")];
1049 bAccessible
= fgets( buffer
, sizeof(buffer
), fin
) && 0 == strcmp( buffer
, "true" );
1058 int main( int argc
, char** argv
)
1060 freopen( "/dev/null", "w", stderr
);
1062 setup_program_dir( argv
[0] );
1064 // Don't start if accessiblity is enabled or report server is not given
1066 if ( setup_version() )
1068 /*long pid =*/ setup_commandline_arguments( argc
, argv
, &g_signal
);
1070 if ( g_bLoadReport
)
1075 if ( g_bSendReport
)
1077 hash_map
< string
, string
> aDialogSettings
;
1079 read_settings( aDialogSettings
);
1080 read_settings_from_environment( aDialogSettings
);
1082 send_crash_report( aDialogSettings
);
1086 hash_map
< string
, string
> aDialogSettings
;
1088 read_settings( aDialogSettings
);
1089 read_settings_from_environment( aDialogSettings
);
1092 write_report( aDialogSettings
);
1094 string sPreviewFile
= get_home_dir();
1095 sPreviewFile
+= "/";
1096 sPreviewFile
+= string(PRVFILE
);
1098 FILE *fpout
= fopen( sPreviewFile
.c_str(), "w+" );
1101 FILE *fpin
= fopen( g_szReportFile
, "r" );
1104 fcopy( fpout
, fpin
);
1110 unlink( g_szReportFile
);
1113 if ( g_bLoadReport
)
1115 unlink( g_strXMLFileName
.c_str() );
1116 unlink( g_strChecksumFileName
.c_str() );
1119 unlink( g_szStackFile
);