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 throw ( RuntimeException ) 116 { 117 return Reference< XMailClient >( 118 static_cast < cppu::OWeakObject * >( this ), UNO_QUERY ); 119 } 120 121 122 Reference< XMailMessage > SAL_CALL 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 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 305 SystemCommandMail::getImplementationName( ) 306 throw( RuntimeException ) 307 { 308 return getImplementationName_static(); 309 } 310 311 sal_Bool SAL_CALL 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 326 SystemCommandMail::getSupportedServiceNames() 327 throw( RuntimeException ) 328 { 329 return getSupportedServiceNames_static(); 330 } 331 332 Reference< XInterface > 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 342 SystemCommandMail::getImplementationName_static() 343 { 344 return OUString( RTL_CONSTASCII_USTRINGPARAM( COMP_IMPL_NAME ) ); 345 } 346 347 Sequence< OUString > 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