1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26 
27 #include "errormail.hxx"
28 #include "config.hxx"
29 #include <unotools/bootstrap.hxx>
30 #include <rtl/ustring.hxx>
31 #include <rtl/string.hxx>
32 #include <rtl/strbuf.hxx>
33 
34 #if defined(UNIX) || defined(OS2)
35     #include <sys/utsname.h>
36 #endif
37 #ifdef WIN32
38     #include <windows.h>
39 #endif
40 
41 
42 using namespace com::sun::star::lang;
43 using namespace com::sun::star::uno;
44 using namespace oooimprovement;
45 using ::rtl::OUString;
46 using ::rtl::OString;
47 using ::rtl::OStringBuffer;
48 
49 
50 namespace {
replaceAll(const OString & str,sal_Char old,const OString & replacement)51     static OString replaceAll(const OString& str, sal_Char old, const OString& replacement)
52     {
53         OStringBuffer result;
54         sal_Int32 idx = 0;
55         do {
56             result.append(str.getToken(0, old, idx));
57             if(idx>=0) result.append(replacement);
58         } while(idx >= 0);
59         return result.makeStringAndClear();
60     };
61 
xmlAttrEncode(const OString & input)62     static OString xmlAttrEncode(const OString& input)
63     {
64         OString result = replaceAll(input, '&', OString("&amp;"));
65         result = replaceAll(result, '<', OString("&lt;"));
66         result = replaceAll(result, '"', OString("&quot;"));
67         return replaceAll(result, '>', OString("&gt;"));
68     }
69 
getPlatform()70     static OString getPlatform()
71     {
72         #ifdef SOLARIS
73             return "Solaris";
74         #elif defined LINUX
75             return "Linux";
76         #elif defined WIN32
77             return "Win32";
78         #elif defined UNIX
79             return "Unix";
80         #elif defined OS2
81             return "OS/2";
82         #else
83             return "Unknown";
84         #endif
85     };
86 
87 #if defined(UNIX) || defined(OS2)
getLocale()88     static const OString getLocale()
89     {
90         const char * locale = getenv( "LC_ALL" );
91         if( NULL == locale )
92             locale = getenv( "LC_CTYPE" );
93 
94         if( NULL == locale )
95             locale = getenv( "LANG" );
96 
97         if( NULL == locale )
98             locale = "C";
99         return locale;
100     };
101 
getSystemInfoXml(const Reference<XMultiServiceFactory> &)102     static OString getSystemInfoXml(const Reference<XMultiServiceFactory>&)
103     {
104         struct utsname info;
105         //memset(&info, 0, sizeof(info));
106         uname(&info);
107         OStringBuffer result =
108             "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
109             "<systeminfo:System name=\""
110             + xmlAttrEncode(OString(info.sysname)) + "\" version=\""
111             + xmlAttrEncode(OString(info.version)) + "\" build=\""
112             + xmlAttrEncode(OString(info.release)) + "\" locale=\""
113             + xmlAttrEncode(OString(getLocale())) + "\"/>\n"
114             "<systeminfo:CPU type=\""
115             + xmlAttrEncode(OString(info.machine)) + "\"/>\n"
116             "</systeminfo:systeminfo>\n";
117         return result.makeStringAndClear();
118     };
119 #else
getSystemInfoXml(const Reference<XMultiServiceFactory> &)120     static OString getSystemInfoXml(const Reference<XMultiServiceFactory>&)
121     {
122         OSVERSIONINFO info;
123         ZeroMemory(&info, sizeof(OSVERSIONINFO));
124         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
125         GetVersionEx(&info);
126         OStringBuffer result = OString(
127             "<systeminfo:systeminfo xmlns:systeminfo=\"http://openoffice.org/2002/systeminfo\">\n"
128             "<systeminfo:System name=\"");
129         if(VER_PLATFORM_WIN32_NT == info.dwPlatformId)
130             result.append(OString("Windows NT"));
131         else
132             result.append(OString("Windows"));
133         result.append("\" version=\"").append(static_cast<long>(info.dwMajorVersion));
134         result.append(".").append(static_cast<long>(info.dwMinorVersion));
135         result.append("\" build=\"").append(static_cast<long>(info.dwBuildNumber));
136         result.append("\" locale=\"").append(static_cast<long>(GetUserDefaultLangID()));
137         result.append("\"/>\n");
138         result.append("<systeminfo:CPU type=\""
139             /* x86 or AMD64 */  "\"/>\n"
140             "</systeminfo:systeminfo>\n");
141         return result.makeStringAndClear();
142     };
143 #endif
144 
getOfficeInfoXml(const Reference<XMultiServiceFactory> & sf)145     static OString getOfficeInfoXml(const Reference<XMultiServiceFactory>& sf)
146     {
147         Config config(sf);
148         const OString product = OUStringToOString(config.getCompleteProductname(), RTL_TEXTENCODING_ASCII_US);
149         const OString platform = getPlatform();
150         const OString language = OUStringToOString(config.getSetupLocale(), RTL_TEXTENCODING_ASCII_US);
151         // If the oooimprovement lib is packaged in an extension, this needs to
152         // be done in another way: The build version string needs to be made
153         // available in an UNO service (if no better place is found for this,
154         // com.sun.star.comp.extensions.oooimprovecore.Core in oooimprovecore
155         // is likely the best fit)
156         const OString build = OUStringToOString(::utl::Bootstrap::getBuildIdData(OUString()), RTL_TEXTENCODING_ASCII_US);
157         const OString exceptiontype = "";
158         OStringBuffer result =
159             "<officeinfo:officeinfo xmlns:officeinfo=\"http://openoffice.org/2002/officeinfo\" platform=\""
160             + xmlAttrEncode(platform) + "\" language=\""
161             + xmlAttrEncode(language) + "\" build=\""
162             + xmlAttrEncode(build) + "\" exceptiontype=\""
163             + xmlAttrEncode(exceptiontype) + "\" product=\""
164             + xmlAttrEncode(product) + " \" />\n";
165         return result.makeStringAndClear();
166     };
167 }
168 
169 namespace oooimprovement
170 {
Errormail(const Reference<XMultiServiceFactory> & sf)171     Errormail::Errormail(const Reference<XMultiServiceFactory>& sf)
172         : m_ServiceFactory(sf)
173     {}
174 
getXml()175     OString Errormail::getXml()
176     {
177         Config config(m_ServiceFactory);
178         const OString usertype;
179         const OString email = OUStringToOString(config.getReporterEmail(), RTL_TEXTENCODING_ASCII_US);
180         OString feedback;
181         {
182             OStringBuffer temp;
183             temp.append(config.getReportCount());
184             feedback = temp.makeStringAndClear();
185         }
186         const OString title;
187         OStringBuffer result =
188             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
189             "<!DOCTYPE errormail:errormail PUBLIC \"-//OpenOffice.org//DTD ErrorMail 1.0//EN\" \"errormail.dtd\">\n"
190             "<errormail:errormail xmlns:errormail=\"http://openoffice.org/2002/errormail\" usertype=\""
191             + xmlAttrEncode(usertype) + "\">\n"
192             "<reportmail:mail xmlns:reportmail=\"http://openoffice.org/2002/reportmail\" version=\"1.1\" feedback=\""
193             + xmlAttrEncode(feedback) + "\" email=\""
194             + xmlAttrEncode(email) + "\">\n"
195             "<reportmail:title>"
196             + xmlAttrEncode(title) + "</reportmail:title>\n"
197            "<reportmail:attachment name=\"data.zip\" media-type=\"application/zip\" class=\"OOoImprovementLog\"/>\n"
198             "</reportmail:mail>\n"
199             + getOfficeInfoXml(m_ServiceFactory)
200             + getSystemInfoXml(m_ServiceFactory) +
201             "</errormail:errormail>\n";
202         return result.makeStringAndClear();
203     }
204 }
205