Bump version to 5.0-14
[LibreOffice.git] / shell / source / cmdmail / cmdmailsuppl.cxx
blob07da391c5601f8eb52e8b2ed0ea6e715cf8fc1cf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_folders.h>
22 #include <osl/diagnose.h>
23 #include <osl/thread.h>
25 #include <rtl/bootstrap.hxx>
27 #include <osl/file.hxx>
28 #include <rtl/strbuf.hxx>
29 #include "cmdmailsuppl.hxx"
30 #include "cmdmailmsg.hxx"
31 #include <com/sun/star/system/SimpleMailClientFlags.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/configuration/theDefaultProvider.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/uno/XComponentContext.hpp>
37 #include <cppuhelper/supportsservice.hxx>
39 #include <string.h>
40 #include <errno.h>
41 #include <unistd.h>
44 // namespace directives
47 using com::sun::star::beans::PropertyValue;
48 using com::sun::star::system::XSimpleMailClientSupplier;
49 using com::sun::star::system::XSimpleMailClient;
50 using com::sun::star::system::XSimpleMailMessage;
51 using com::sun::star::system::XSimpleMailMessage2;
52 using com::sun::star::container::XNameAccess;
53 using com::sun::star::container::NoSuchElementException;
54 using osl::MutexGuard;
55 using osl::FileBase;
57 using namespace cppu;
58 using namespace com::sun::star::system::SimpleMailClientFlags;
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::lang;
61 using namespace com::sun::star::configuration;
63 namespace // private
65 Sequence< OUString > SAL_CALL Component_getSupportedServiceNames()
67 Sequence< OUString > aRet(1);
68 aRet[0] = "com.sun.star.system.SimpleCommandMail";
69 return aRet;
72 } // end private namespace
76 CmdMailSuppl::CmdMailSuppl( const Reference< XComponentContext >& xContext ) :
77 WeakImplHelper3< XSimpleMailClientSupplier, XSimpleMailClient, XServiceInfo >()
79 m_xConfigurationProvider = theDefaultProvider::get(xContext);
83 // XSimpleMailClientSupplier
86 Reference< XSimpleMailClient > SAL_CALL CmdMailSuppl::querySimpleMailClient( )
87 throw (RuntimeException, std::exception)
89 return static_cast < XSimpleMailClient * > (this);
93 // XSimpleMailClient
96 Reference< XSimpleMailMessage > SAL_CALL CmdMailSuppl::createSimpleMailMessage( )
97 throw (::com::sun::star::uno::RuntimeException, std::exception)
99 return Reference< XSimpleMailMessage >( new CmdMailMsg( ) );
103 // XSimpleMailClient
106 namespace {
108 void appendShellWord(OStringBuffer & buffer, OUString const & word, bool strict)
110 OString sys;
111 if (!word.convertToString(
112 &sys, osl_getThreadTextEncoding(),
113 (strict
114 ? (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
115 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)
116 : OUSTRING_TO_OSTRING_CVTFLAGS)))
118 throw css::uno::Exception(
119 ("Could not convert \"" + word + "\" to encoding #"
120 + OUString::number(osl_getThreadTextEncoding())),
121 css::uno::Reference<css::uno::XInterface>());
123 buffer.append('\'');
124 for (sal_Int32 i = 0; i != sys.getLength(); ++i) {
125 char c = sys[i];
126 switch (c) {
127 case 0:
128 if (strict) {
129 throw css::uno::Exception(
130 "Could not convert word containing NUL, \"" + word + "\"",
131 css::uno::Reference<css::uno::XInterface>());
133 break;
134 case '\'':
135 buffer.append("'\\''");
136 break;
137 default:
138 buffer.append(c);
139 break;
142 buffer.append('\'');
147 void SAL_CALL CmdMailSuppl::sendSimpleMailMessage( const Reference< XSimpleMailMessage >& xSimpleMailMessage, sal_Int32 /*aFlag*/ )
148 throw (IllegalArgumentException, Exception, RuntimeException, std::exception)
150 if ( ! xSimpleMailMessage.is() )
152 throw ::com::sun::star::lang::IllegalArgumentException( "No message specified" ,
153 static_cast < XSimpleMailClient * > (this), 1 );
156 if( ! m_xConfigurationProvider.is() )
158 throw ::com::sun::star::uno::Exception( "Can not access configuration" ,
159 static_cast < XSimpleMailClient * > (this) );
163 OUString aProgramURL("$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/senddoc");
164 rtl::Bootstrap::expandMacros(aProgramURL);
166 OUString aProgram;
167 if ( FileBase::E_None != FileBase::getSystemPathFromFileURL(aProgramURL, aProgram))
169 throw ::com::sun::star::uno::Exception("Cound not convert executable path",
170 static_cast < XSimpleMailClient * > (this));
173 OStringBuffer aBuffer;
174 appendShellWord(aBuffer, aProgram, true);
178 // Query XNameAccess interface of the org.openoffice.Office.Common/ExternalMailer
179 // configuration node to retriece the users preferred email application. This may
180 // transparently by redirected to e.g. the corresponding GConf setting in GNOME.
181 OUString aConfigRoot = "org.openoffice.Office.Common/ExternalMailer";
183 PropertyValue aProperty;
184 aProperty.Name = "nodepath";
185 aProperty.Value = makeAny( aConfigRoot );
187 Sequence< Any > aArgumentList( 1 );
188 aArgumentList[0] = makeAny( aProperty );
190 Reference< XNameAccess > xNameAccess =
191 Reference< XNameAccess > (
192 m_xConfigurationProvider->createInstanceWithArguments(
193 OUString("com.sun.star.configuration.ConfigurationAccess"),
194 aArgumentList ),
195 UNO_QUERY );
197 if( xNameAccess.is() )
199 OUString aMailer;
201 // Retrieve the value for "Program" node and append it feed senddoc with it
202 // using the (undocumented) --mailclient switch
203 xNameAccess->getByName("Program") >>= aMailer;
205 if( !aMailer.isEmpty() )
207 // make sure we have a system path
208 FileBase::getSystemPathFromFileURL( aMailer, aMailer );
210 aBuffer.append(" --mailclient ");
211 appendShellWord(aBuffer, aMailer, true);
213 #ifdef MACOSX
214 else
215 aBuffer.append(" --mailclient Mail");
216 #endif
221 catch(const RuntimeException &e )
223 m_xConfigurationProvider.clear();
224 OSL_TRACE( "RuntimeException caught accessing configuration provider." );
225 OSL_TRACE( "%s", OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
226 throw;
229 Reference< XSimpleMailMessage2 > xMessage( xSimpleMailMessage, UNO_QUERY );
230 if ( xMessage.is() )
232 rtl::OUString sBody = xMessage->getBody();
233 if ( sBody.getLength() > 0 )
235 aBuffer.append(" --body ");
236 appendShellWord(aBuffer, sBody, false);
240 // Convert from, to, etc. in a best-effort rather than a strict way to the
241 // system encoding, based on the assumption that the relevant address parts
242 // of those strings are ASCII anyway and any problematic characters are only
243 // in the human-readable, informational-only parts:
245 // Append originator if set in the message
246 if ( !xSimpleMailMessage->getOriginator().isEmpty() )
248 aBuffer.append(" --from ");
249 appendShellWord(aBuffer, xSimpleMailMessage->getOriginator(), false);
252 // Append receipient if set in the message
253 if ( !xSimpleMailMessage->getRecipient().isEmpty() )
255 aBuffer.append(" --to ");
256 appendShellWord(aBuffer, xSimpleMailMessage->getRecipient(), false);
259 // Append carbon copy receipients set in the message
260 Sequence< OUString > aStringList = xSimpleMailMessage->getCcRecipient();
261 sal_Int32 n, nmax = aStringList.getLength();
262 for ( n = 0; n < nmax; n++ )
264 aBuffer.append(" --cc ");
265 appendShellWord(aBuffer, aStringList[n], false);
268 // Append blind carbon copy receipients set in the message
269 aStringList = xSimpleMailMessage->getBccRecipient();
270 nmax = aStringList.getLength();
271 for ( n = 0; n < nmax; n++ )
273 aBuffer.append(" --bcc ");
274 appendShellWord(aBuffer, aStringList[n], false);
277 // Append subject if set in the message
278 if ( !xSimpleMailMessage->getSubject().isEmpty() )
280 aBuffer.append(" --subject ");
281 appendShellWord(aBuffer, xSimpleMailMessage->getSubject(), false);
284 // Append attachments set in the message
285 aStringList = xSimpleMailMessage->getAttachement();
286 nmax = aStringList.getLength();
287 for ( n = 0; n < nmax; n++ )
289 OUString aSystemPath;
290 if ( FileBase::E_None == FileBase::getSystemPathFromFileURL(aStringList[n], aSystemPath) )
292 aBuffer.append(" --attach ");
293 appendShellWord(aBuffer, aSystemPath, true);
297 OString cmd = aBuffer.makeStringAndClear();
298 FILE * f = popen(cmd.getStr(), "w");
299 if (f == 0 || pclose(f) != 0)
301 throw ::com::sun::star::uno::Exception("No mail client configured",
302 static_cast < XSimpleMailClient * > (this) );
306 // XServiceInfo
307 OUString SAL_CALL CmdMailSuppl::getImplementationName( )
308 throw( RuntimeException, std::exception )
310 return OUString("com.sun.star.comp.system.SimpleCommandMail");
313 // XServiceInfo
314 sal_Bool SAL_CALL CmdMailSuppl::supportsService( const OUString& ServiceName )
315 throw( RuntimeException, std::exception )
317 return cppu::supportsService(this, ServiceName);
320 // XServiceInfo
321 Sequence< OUString > SAL_CALL CmdMailSuppl::getSupportedServiceNames( )
322 throw( RuntimeException, std::exception )
324 return Component_getSupportedServiceNames();
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */