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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_shell.hxx"
24
25 #include "syscmdmail.hxx"
26 #include "cmdmailmsg.hxx"
27
28 #include <com/sun/star/system/MailClientFlags.hpp>
29 #include <com/sun/star/container/XNameAccess.hpp>
30 #include <com/sun/star/beans/PropertyValue.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32
33 #include <osl/file.hxx>
34 #include <osl/thread.hxx>
35 #include <rtl/bootstrap.hxx>
36 #include <rtl/strbuf.hxx>
37
38 #include <unistd.h>
39
40 using com::sun::star::beans::PropertyValue;
41 using com::sun::star::container::XNameAccess;
42 using com::sun::star::system::XMailClient;
43 using com::sun::star::system::XMailMessage;
44 using rtl::OString;
45 using rtl::OStringBuffer;
46 using rtl::OUString;
47 using rtl::OUStringToOString;
48
49 using namespace com::sun::star::lang;
50 using namespace com::sun::star::system::MailClientFlags;
51 using namespace com::sun::star::uno;
52
53 #define COMP_SERVICE_NAME "com.sun.star.system.SystemMailProvider"
54 #define COMP_IMPL_NAME "com.sun.star.comp.system.unx.SystemMailProvider"
55
56 namespace shell
57 {
58
59 namespace
60 {
escapeDoubleQuotes(OStringBuffer & rBuffer,const OUString & ustr,rtl_TextEncoding iEncoding)61 static void escapeDoubleQuotes( OStringBuffer &rBuffer,
62 const OUString &ustr,
63 rtl_TextEncoding iEncoding )
64 {
65 const OString rStr( OUStringToOString( ustr, iEncoding ) );
66 sal_Int32 nIndex = rStr.indexOf('"');
67 if ( nIndex == -1 )
68 rBuffer.append( rStr );
69 else
70 {
71 const sal_Char *pStart = rStr.getStr();
72 const sal_Char *pFrom = pStart;
73 const sal_Int32 nLen = rStr.getLength();
74 sal_Int32 nPrev = 0;;
75 do
76 {
77 rBuffer.append( pFrom, nIndex - nPrev );
78 rBuffer.append( RTL_CONSTASCII_STRINGPARAM( "\\\"" ) );
79 nIndex++;
80 pFrom = pStart + nIndex;
81 nPrev = nIndex;
82 }
83 while ( ( nIndex = rStr.indexOf( '"' , nIndex ) ) != -1 );
84
85 rBuffer.append( pFrom, nLen - nPrev );
86 }
87 }
88 }
89
SystemCommandMail(const Reference<XComponentContext> & xContext)90 SystemCommandMail::SystemCommandMail(
91 const Reference< XComponentContext >& xContext )
92 : SystemCommandMail_Base( m_aMutex )
93 , m_xContext( xContext )
94 {
95 try
96 {
97 m_xConfigurationProvider.set(
98 m_xContext->getServiceManager()->createInstanceWithContext(
99 OUString( RTL_CONSTASCII_USTRINGPARAM(
100 "com.sun.star.configuration.ConfigurationProvider") ),
101 m_xContext ),
102 UNO_QUERY );
103 }
104 catch(...){}
105 }
106
~SystemCommandMail()107 SystemCommandMail::~SystemCommandMail()
108 {
109 m_xConfigurationProvider.clear();
110 m_xContext.clear();
111 }
112
113 Reference< XMailClient > SAL_CALL
queryMailClient()114 SystemCommandMail::queryMailClient()
115 throw ( RuntimeException )
116 {
117 return Reference< XMailClient >(
118 static_cast < cppu::OWeakObject * >( this ), UNO_QUERY );
119 }
120
121
122 Reference< XMailMessage > SAL_CALL
createMailMessage()123 SystemCommandMail::createMailMessage()
124 throw ( RuntimeException )
125 {
126 return Reference< XMailMessage >(
127 static_cast< cppu::OWeakObject *>(
128 new CmdMailMsg() ),
129 UNO_QUERY );
130 }
131
132
133 void SAL_CALL
sendMailMessage(const Reference<XMailMessage> & xMailMessage,sal_Int32)134 SystemCommandMail::sendMailMessage(
135 const Reference< XMailMessage >& xMailMessage,
136 sal_Int32 /*aFlag*/ )
137 throw (IllegalArgumentException, Exception, RuntimeException)
138 {
139 osl::ClearableMutexGuard aGuard( m_aMutex );
140 Reference< XMultiServiceFactory > xConfigurationProvider = m_xConfigurationProvider;
141 aGuard.clear();
142
143 if ( ! xMailMessage.is() )
144 {
145 throw IllegalArgumentException(
146 OUString(RTL_CONSTASCII_USTRINGPARAM( "No message specified" )),
147 static_cast < XMailClient * > (this), 1 );
148 }
149
150 if( ! xConfigurationProvider.is() )
151 {
152 throw Exception(
153 OUString(RTL_CONSTASCII_USTRINGPARAM( "Can not access configuration" )),
154 static_cast < XMailClient * > (this) );
155 }
156
157 OStringBuffer aBuffer;
158 aBuffer.append("\"");
159
160 OUString aProgramURL(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/senddoc"));
161 rtl::Bootstrap::expandMacros(aProgramURL);
162 OUString aProgram;
163 if ( osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aProgramURL, aProgram))
164 {
165 throw Exception(
166 OUString(RTL_CONSTASCII_USTRINGPARAM("Cound not convert executable path")),
167 static_cast < XMailClient * > (this));
168 }
169
170 const rtl_TextEncoding iEncoding = osl_getThreadTextEncoding();
171 aBuffer.append(OUStringToOString(aProgram, iEncoding));
172 aBuffer.append("\" ");
173
174 try
175 {
176 // Query XNameAccess interface of the org.openoffice.Office.Common/ExternalMailer
177 // configuration node to retriece the users preferred email application. This may
178 // transparently by redirected to e.g. the corresponding GConf setting in GNOME.
179 OUString aConfigRoot = OUString(
180 RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/ExternalMailer" ) );
181
182 PropertyValue aProperty;
183 aProperty.Name = OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath" ));
184 aProperty.Value = makeAny( aConfigRoot );
185
186 Sequence< Any > aArgumentList( 1 );
187 aArgumentList[0] = makeAny( aProperty );
188
189 Reference< XNameAccess > xNameAccess =
190 Reference< XNameAccess > (
191 xConfigurationProvider->createInstanceWithArguments(
192 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )),
193 aArgumentList ),
194 UNO_QUERY );
195
196 if( xNameAccess.is() )
197 {
198 OUString aMailer;
199
200 // Retrieve the value for "Program" node and append it feed senddoc with it
201 // using the (undocumented) --mailclient switch
202 xNameAccess->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM("Program") ) ) >>= aMailer;
203
204 if( aMailer.getLength() )
205 {
206 // make sure we have a system path
207 osl::FileBase::getSystemPathFromFileURL( aMailer, aMailer );
208
209 aBuffer.append("--mailclient ");
210 aBuffer.append(OUStringToOString( aMailer, iEncoding ));
211 aBuffer.append(" ");
212 }
213 #ifdef MACOSX
214 else
215 aBuffer.append("--mailclient Mail ");
216 #endif
217 }
218
219 }
220 catch( RuntimeException e )
221 {
222 OSL_TRACE( "RuntimeException caught accessing configuration provider." );
223 OSL_TRACE( OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
224 throw e;
225 }
226
227 // Append body if set in the message
228 OUString ustr = xMailMessage->getBody();
229 if ( ustr.getLength() > 0 )
230 {
231 aBuffer.append("--body \"");
232 escapeDoubleQuotes( aBuffer, ustr, iEncoding );
233 aBuffer.append("\" ");
234 }
235
236 // Append subject if set in the message
237 ustr = xMailMessage->getSubject();
238 if ( ustr.getLength() > 0 )
239 {
240 aBuffer.append("--subject \"");
241 escapeDoubleQuotes( aBuffer, ustr, iEncoding );
242 aBuffer.append("\" ");
243 }
244
245 // Append originator if set in the message
246 if ( xMailMessage->getOriginator().getLength() > 0 )
247 {
248 aBuffer.append("--from \"");
249 aBuffer.append(OUStringToOString(xMailMessage->getOriginator(), iEncoding));
250 aBuffer.append("\" ");
251 }
252
253 // Append receipient if set in the message
254 if ( xMailMessage->getRecipient().getLength() > 0 )
255 {
256 aBuffer.append("--to \"");
257 aBuffer.append(OUStringToOString(xMailMessage->getRecipient(), iEncoding));
258 aBuffer.append("\" ");
259 }
260
261 // Append carbon copy receipients set in the message
262 Sequence< OUString > aStringList = xMailMessage->getCcRecipient();
263 sal_Int32 n, nmax = aStringList.getLength();
264 for ( n = 0; n < nmax; n++ )
265 {
266 aBuffer.append("--cc \"");
267 aBuffer.append(OUStringToOString(aStringList[n], iEncoding));
268 aBuffer.append("\" ");
269 }
270
271 // Append blind carbon copy receipients set in the message
272 aStringList = xMailMessage->getBccRecipient();
273 nmax = aStringList.getLength();
274 for ( n = 0; n < nmax; n++ )
275 {
276 aBuffer.append("--bcc \"");
277 aBuffer.append(OUStringToOString(aStringList[n], iEncoding));
278 aBuffer.append("\" ");
279 }
280
281 // Append attachments set in the message
282 aStringList = xMailMessage->getAttachement();
283 nmax = aStringList.getLength();
284 for ( n = 0; n < nmax; n++ )
285 {
286 OUString aSystemPath;
287 if ( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(aStringList[n], aSystemPath) )
288 {
289 aBuffer.append("--attach \"");
290 aBuffer.append(OUStringToOString(aSystemPath, iEncoding));
291 aBuffer.append("\" ");
292 }
293 }
294
295 OString cmd = aBuffer.makeStringAndClear();
296 if ( 0 != pclose(popen(cmd.getStr(), "w")) )
297 {
298 throw ::com::sun::star::uno::Exception(
299 OUString(RTL_CONSTASCII_USTRINGPARAM( "No mail client configured" )),
300 static_cast < XMailClient * > (this) );
301 }
302 }
303
304 OUString SAL_CALL
getImplementationName()305 SystemCommandMail::getImplementationName( )
306 throw( RuntimeException )
307 {
308 return getImplementationName_static();
309 }
310
311 sal_Bool SAL_CALL
supportsService(const OUString & ServiceName)312 SystemCommandMail::supportsService(
313 const OUString& ServiceName )
314 throw( RuntimeException )
315 {
316 Sequence < OUString > SupportedServicesNames = getSupportedServiceNames_static();
317
318 for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
319 if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
320 return sal_True;
321
322 return sal_False;
323 }
324
325 Sequence< OUString > SAL_CALL
getSupportedServiceNames()326 SystemCommandMail::getSupportedServiceNames()
327 throw( RuntimeException )
328 {
329 return getSupportedServiceNames_static();
330 }
331
332 Reference< XInterface >
Create(const Reference<XComponentContext> & xContext)333 SystemCommandMail::Create(
334 const Reference< XComponentContext > &xContext)
335 {
336 return Reference< XInterface >(
337 static_cast< cppu::OWeakObject *>(
338 new SystemCommandMail( xContext ) ) );
339 }
340
341 OUString
getImplementationName_static()342 SystemCommandMail::getImplementationName_static()
343 {
344 return OUString( RTL_CONSTASCII_USTRINGPARAM( COMP_IMPL_NAME ) );
345 }
346
347 Sequence< OUString >
getSupportedServiceNames_static()348 SystemCommandMail::getSupportedServiceNames_static()
349 {
350 Sequence< OUString > aRet(1);
351 aRet[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( COMP_SERVICE_NAME ) );
352 return aRet;
353 }
354
355 }
356