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