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
10c42202c3SAndrew Rist *
11c42202c3SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12c42202c3SAndrew Rist *
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.
19c42202c3SAndrew Rist *
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
basename(const char * filename)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
getprogramdir()96cdf0e10cSrcweir static string getprogramdir()
97cdf0e10cSrcweir {
98cdf0e10cSrcweir return g_strProgramDir;
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
getlocale()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
get_home_dir()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
trim_string(const string & rString)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
xml_encode(const string & rString)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
fcopy(FILE * fpout,FILE * fpin)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
write_report(const hash_map<string,string> & rSettings)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
write_description(const hash_map<string,string> & rSettings)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
save_crash_report(const string & rFileName,const hash_map<string,string> &)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
SendHTTPRequest(FILE * fp,const char * pszServer,unsigned short uPort=80,const char * pszProxyServer=NULL,unsigned short uProxyPort=8080)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
WriteSOAPRequest(FILE * fp)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
send_crash_report(const hash_map<string,string> & rSettings)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
append_file(const char * filename,string & rString)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
crash_get_details(const hash_map<string,string> & rSettings)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
setup_program_dir(const char * progname)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
setup_commandline_arguments(int argc,char ** argv,int * pSignal)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
read_line(FILE * fp,string & rLine)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
get_script_string(const char * pFileName,const char * pKeyName)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
get_profile_string(const char * pFileName,const char * pSectionName,const char * pKeyName,const char * pDefault=NULL)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
get_environment_string(const char * pEnvName)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
read_from_file(const string & rFileName)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
load_crash_data()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
write_crash_data()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
read_settings(hash_map<string,string> & rSettings)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
read_settings_from_environment(hash_map<string,string> & rSettings)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
setup_version()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*6b6a7a13SJohn 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
main(int argc,char ** argv)1051cdf0e10cSrcweir int main( int argc, char** argv )
1052cdf0e10cSrcweir {
1053cdf0e10cSrcweir freopen( "/dev/null", "w", stderr );
1054cdf0e10cSrcweir
1055cdf0e10cSrcweir setup_program_dir( argv[0] );
1056cdf0e10cSrcweir
1057*6b6a7a13SJohn 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