1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25  ************************************************************************/
26 
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_extensions.hxx"
29 
30 #include "errormail.hxx"
31 #include "config.hxx"
32 #include <unotools/bootstrap.hxx>
33 #include <rtl/ustring.hxx>
34 #include <rtl/string.hxx>
35 #include <rtl/strbuf.hxx>
36 
37 #if defined(UNIX) || defined(OS2)
38     #include <sys/utsname.h>
39 #endif
40 #ifdef WIN32
41     #include <windows.h>
42 #endif
43 
44 
45 using namespace com::sun::star::lang;
46 using namespace com::sun::star::uno;
47 using namespace oooimprovement;
48 using ::rtl::OUString;
49 using ::rtl::OString;
50 using ::rtl::OStringBuffer;
51 
52 
53 namespace {
54     static OString replaceAll(const OString& str, sal_Char old, const OString& replacement)
55     {
56         OStringBuffer result;
57         sal_Int32 idx = 0;
58         do {
59             result.append(str.getToken(0, old, idx));
60             if(idx>=0) result.append(replacement);
61         } while(idx >= 0);
62         return result.makeStringAndClear();
63     };
64 
65     static OString xmlAttrEncode(const OString& input)
66     {
67         OString result = replaceAll(input, '&', OString("&amp;"));
68         result = replaceAll(result, '<', OString("&lt;"));
69         result = replaceAll(result, '"', OString("&quot;"));
70         return replaceAll(result, '>', OString("&gt;"));
71     }
72 
73     static OString getPlatform()
74     {
75         #ifdef SOLARIS
76             return "Solaris";
77         #elif defined LINUX
78             return "Linux";
79         #elif defined WIN32
80             return "Win32";
81         #elif defined UNIX
82             return "Unix";
83         #elif defined OS2
84             return "OS/2";
85         #else
86             return "Unknown";
87         #endif
88     };
89 
90 #if defined(UNIX) || defined(OS2)
91     static const OString getLocale()
92     {
93         const char * locale = getenv( "LC_ALL" );
94         if( NULL == locale )
95             locale = getenv( "LC_CTYPE" );
96 
97         if( NULL == locale )
98             locale = getenv( "LANG" );
99 
100         if( NULL == locale )
101             locale = "C";
102         return locale;
103     };
104 
105     static OString getSystemInfoXml(const Reference<XMultiServiceFactory>&)
106     {
107         struct utsname info;
108         //memset(&info, 0, sizeof(info));
109         uname(&info);
110         OStringBuffer result =
111             "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
112             "<systeminfo:System name=\""
113             + xmlAttrEncode(OString(info.sysname)) + "\" version=\""
114             + xmlAttrEncode(OString(info.version)) + "\" build=\""
115             + xmlAttrEncode(OString(info.release)) + "\" locale=\""
116             + xmlAttrEncode(OString(getLocale())) + "\"/>\n"
117             "<systeminfo:CPU type=\""
118             + xmlAttrEncode(OString(info.machine)) + "\"/>\n"
119             "</systeminfo:systeminfo>\n";
120         return result.makeStringAndClear();
121     };
122 #else
123     static OString getSystemInfoXml(const Reference<XMultiServiceFactory>&)
124     {
125         OSVERSIONINFO info;
126         ZeroMemory(&info, sizeof(OSVERSIONINFO));
127         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
128         GetVersionEx(&info);
129         OStringBuffer result = OString(
130             "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
131             "<systeminfo:System name=\"");
132         if(VER_PLATFORM_WIN32_NT == info.dwPlatformId)
133             result.append(OString("Windows NT"));
134         else
135             result.append(OString("Windows"));
136         result.append("\" version=\"").append(static_cast<long>(info.dwMajorVersion));
137         result.append(".").append(static_cast<long>(info.dwMinorVersion));
138         result.append("\" build=\"").append(static_cast<long>(info.dwBuildNumber));
139         result.append("\" locale=\"").append(static_cast<long>(GetUserDefaultLangID()));
140         result.append("\"/>\n");
141         result.append("<systeminfo:CPU type=\""
142             /* x86 or AMD64 */  "\"/>\n"
143             "</systeminfo:systeminfo>\n");
144         return result.makeStringAndClear();
145     };
146 #endif
147 
148     static OString getOfficeInfoXml(const Reference<XMultiServiceFactory>& sf)
149     {
150         Config config(sf);
151         const OString product = OUStringToOString(config.getCompleteProductname(), RTL_TEXTENCODING_ASCII_US);
152         const OString platform = getPlatform();
153         const OString language = OUStringToOString(config.getSetupLocale(), RTL_TEXTENCODING_ASCII_US);
154         // If the oooimprovement lib is packaged in an extension, this needs to
155         // be done in another way: The build version string needs to be made
156         // available in an UNO service (if no better place is found for this,
157         // com.sun.star.comp.extensions.oooimprovecore.Core in oooimprovecore
158         // is likely the best fit)
159         const OString build = OUStringToOString(::utl::Bootstrap::getBuildIdData(OUString()), RTL_TEXTENCODING_ASCII_US);
160         const OString exceptiontype = "";
161         OStringBuffer result =
162             "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" platform=\""
163             + xmlAttrEncode(platform) + "\" language=\""
164             + xmlAttrEncode(language) + "\" build=\""
165             + xmlAttrEncode(build) + "\" exceptiontype=\""
166             + xmlAttrEncode(exceptiontype) + "\" product=\""
167             + xmlAttrEncode(product) + " \" />\n";
168         return result.makeStringAndClear();
169     };
170 }
171 
172 namespace oooimprovement
173 {
174     Errormail::Errormail(const Reference<XMultiServiceFactory>& sf)
175         : m_ServiceFactory(sf)
176     {}
177 
178     OString Errormail::getXml()
179     {
180         Config config(m_ServiceFactory);
181         const OString usertype;
182         const OString email = OUStringToOString(config.getReporterEmail(), RTL_TEXTENCODING_ASCII_US);
183         OString feedback;
184         {
185             OStringBuffer temp;
186             temp.append(config.getReportCount());
187             feedback = temp.makeStringAndClear();
188         }
189         const OString title;
190         OStringBuffer result =
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=\""
194             + xmlAttrEncode(usertype) + "\">\n"
195             "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\""
196             + xmlAttrEncode(feedback) + "\" email=\""
197             + xmlAttrEncode(email) + "\">\n"
198             "<reportmail:title>"
199             + xmlAttrEncode(title) + "</reportmail:title>\n"
200            "<reportmail:attachment name=\"data.zip\" media-type=\"application/zip\" class=\"OOoImprovementLog\"/>\n"
201             "</reportmail:mail>\n"
202             + getOfficeInfoXml(m_ServiceFactory)
203             + getSystemInfoXml(m_ServiceFactory) +
204             "</errormail:errormail>\n";
205         return result.makeStringAndClear();
206     }
207 }
208