xref: /trunk/main/shell/source/cmdmail/syscmdmail.cxx (revision 9d37da743abb7db0a497688391f6e55a19f27c44)
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 {
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 
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 
107 SystemCommandMail::~SystemCommandMail()
108 {
109     m_xConfigurationProvider.clear();
110     m_xContext.clear();
111 }
112 
113 Reference< XMailClient > SAL_CALL
114 SystemCommandMail::queryMailClient()
115 {
116     return Reference< XMailClient >(
117         static_cast < cppu::OWeakObject * >( this ), UNO_QUERY );
118 }
119 
120 
121 Reference< XMailMessage > SAL_CALL
122 SystemCommandMail::createMailMessage()
123 {
124     return Reference< XMailMessage >(
125         static_cast< cppu::OWeakObject *>(
126             new CmdMailMsg() ),
127         UNO_QUERY );
128 }
129 
130 
131 void SAL_CALL
132 SystemCommandMail::sendMailMessage(
133     const Reference< XMailMessage >& xMailMessage,
134     sal_Int32 /*aFlag*/ )
135 {
136     osl::ClearableMutexGuard aGuard( m_aMutex );
137     Reference< XMultiServiceFactory > xConfigurationProvider = m_xConfigurationProvider;
138     aGuard.clear();
139 
140     if ( ! xMailMessage.is() )
141     {
142         throw IllegalArgumentException(
143             OUString(RTL_CONSTASCII_USTRINGPARAM( "No message specified" )),
144             static_cast < XMailClient * > (this), 1 );
145     }
146 
147     if( ! xConfigurationProvider.is() )
148     {
149         throw Exception(
150             OUString(RTL_CONSTASCII_USTRINGPARAM( "Can not access configuration" )),
151             static_cast < XMailClient * > (this) );
152     }
153 
154     OStringBuffer aBuffer;
155     aBuffer.append("\"");
156 
157     OUString aProgramURL(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/senddoc"));
158     rtl::Bootstrap::expandMacros(aProgramURL);
159     OUString aProgram;
160     if ( osl::FileBase::E_None != osl::FileBase::getSystemPathFromFileURL(aProgramURL, aProgram))
161     {
162         throw Exception(
163             OUString(RTL_CONSTASCII_USTRINGPARAM("Cound not convert executable path")),
164             static_cast < XMailClient * > (this));
165     }
166 
167     const rtl_TextEncoding iEncoding = osl_getThreadTextEncoding();
168     aBuffer.append(OUStringToOString(aProgram, iEncoding));
169     aBuffer.append("\" ");
170 
171     try
172     {
173         // Query XNameAccess interface of the org.openoffice.Office.Common/ExternalMailer
174         // configuration node to retriece the users preferred email application. This may
175         // transparently by redirected to e.g. the corresponding GConf setting in GNOME.
176         OUString aConfigRoot = OUString(
177             RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/ExternalMailer" ) );
178 
179         PropertyValue aProperty;
180         aProperty.Name = OUString( RTL_CONSTASCII_USTRINGPARAM("nodepath" ));
181         aProperty.Value = makeAny( aConfigRoot );
182 
183         Sequence< Any > aArgumentList( 1 );
184         aArgumentList[0] = makeAny( aProperty );
185 
186         Reference< XNameAccess > xNameAccess =
187             Reference< XNameAccess > (
188                 xConfigurationProvider->createInstanceWithArguments(
189                     OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )),
190                     aArgumentList ),
191                 UNO_QUERY );
192 
193         if( xNameAccess.is() )
194         {
195             OUString aMailer;
196 
197             // Retrieve the value for "Program" node and append it feed senddoc with it
198             // using the (undocumented) --mailclient switch
199             xNameAccess->getByName( OUString( RTL_CONSTASCII_USTRINGPARAM("Program") ) ) >>= aMailer;
200 
201             if( aMailer.getLength() )
202             {
203                 // make sure we have a system path
204                 osl::FileBase::getSystemPathFromFileURL( aMailer, aMailer );
205 
206                 aBuffer.append("--mailclient ");
207                 aBuffer.append(OUStringToOString( aMailer, iEncoding ));
208                 aBuffer.append(" ");
209             }
210 #ifdef MACOSX
211             else
212                 aBuffer.append("--mailclient Mail ");
213 #endif
214         }
215 
216     }
217     catch( RuntimeException e )
218     {
219         OSL_TRACE( "RuntimeException caught accessing configuration provider." );
220         OSL_TRACE( OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
221         throw e;
222     }
223 
224     // Append body if set in the message
225     OUString ustr = xMailMessage->getBody();
226     if ( ustr.getLength() > 0 )
227     {
228         aBuffer.append("--body \"");
229         escapeDoubleQuotes( aBuffer, ustr, iEncoding );
230         aBuffer.append("\" ");
231     }
232 
233     // Append subject if set in the message
234     ustr = xMailMessage->getSubject();
235     if ( ustr.getLength() > 0 )
236     {
237         aBuffer.append("--subject \"");
238         escapeDoubleQuotes( aBuffer, ustr, iEncoding );
239         aBuffer.append("\" ");
240     }
241 
242     // Append originator if set in the message
243     if ( xMailMessage->getOriginator().getLength() > 0 )
244     {
245         aBuffer.append("--from \"");
246         aBuffer.append(OUStringToOString(xMailMessage->getOriginator(), iEncoding));
247         aBuffer.append("\" ");
248     }
249 
250     // Append receipient if set in the message
251     if ( xMailMessage->getRecipient().getLength() > 0 )
252     {
253         aBuffer.append("--to \"");
254         aBuffer.append(OUStringToOString(xMailMessage->getRecipient(), iEncoding));
255         aBuffer.append("\" ");
256     }
257 
258     // Append carbon copy receipients set in the message
259     Sequence< OUString > aStringList = xMailMessage->getCcRecipient();
260     sal_Int32 n, nmax = aStringList.getLength();
261     for ( n = 0; n < nmax; n++ )
262     {
263         aBuffer.append("--cc \"");
264         aBuffer.append(OUStringToOString(aStringList[n], iEncoding));
265         aBuffer.append("\" ");
266     }
267 
268     // Append blind carbon copy receipients set in the message
269     aStringList = xMailMessage->getBccRecipient();
270     nmax = aStringList.getLength();
271     for ( n = 0; n < nmax; n++ )
272     {
273         aBuffer.append("--bcc \"");
274         aBuffer.append(OUStringToOString(aStringList[n], iEncoding));
275         aBuffer.append("\" ");
276     }
277 
278     // Append attachments set in the message
279     aStringList = xMailMessage->getAttachement();
280     nmax = aStringList.getLength();
281     for ( n = 0; n < nmax; n++ )
282     {
283         OUString aSystemPath;
284         if ( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(aStringList[n], aSystemPath) )
285         {
286             aBuffer.append("--attach \"");
287             aBuffer.append(OUStringToOString(aSystemPath, iEncoding));
288             aBuffer.append("\" ");
289         }
290     }
291 
292     OString cmd = aBuffer.makeStringAndClear();
293     if ( 0 != pclose(popen(cmd.getStr(), "w")) )
294     {
295         throw ::com::sun::star::uno::Exception(
296             OUString(RTL_CONSTASCII_USTRINGPARAM( "No mail client configured" )),
297             static_cast < XMailClient * > (this) );
298     }
299 }
300 
301 OUString SAL_CALL
302 SystemCommandMail::getImplementationName(  )
303 {
304     return getImplementationName_static();
305 }
306 
307 sal_Bool SAL_CALL
308 SystemCommandMail::supportsService(
309     const OUString& ServiceName )
310 {
311     Sequence < OUString > SupportedServicesNames = getSupportedServiceNames_static();
312 
313     for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; )
314         if (SupportedServicesNames[n].compareTo(ServiceName) == 0)
315             return sal_True;
316 
317     return sal_False;
318 }
319 
320 Sequence< OUString > SAL_CALL
321 SystemCommandMail::getSupportedServiceNames()
322 {
323     return getSupportedServiceNames_static();
324 }
325 
326 Reference< XInterface >
327 SystemCommandMail::Create(
328     const Reference< XComponentContext > &xContext)
329 {
330     return Reference< XInterface >(
331         static_cast< cppu::OWeakObject *>(
332             new SystemCommandMail( xContext ) ) );
333 }
334 
335 OUString
336 SystemCommandMail::getImplementationName_static()
337 {
338     return OUString( RTL_CONSTASCII_USTRINGPARAM( COMP_IMPL_NAME ) );
339 }
340 
341 Sequence< OUString >
342 SystemCommandMail::getSupportedServiceNames_static()
343 {
344     Sequence< OUString > aRet(1);
345     aRet[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( COMP_SERVICE_NAME ) );
346     return aRet;
347 }
348 
349 }
350