1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_shell.hxx" 30 31 // For MAXHOSTNAMELEN constant 32 #include <sys/param.h> 33 34 #include <premac.h> 35 #include <SystemConfiguration/SystemConfiguration.h> 36 #include <Foundation/NSPathUtilities.h> 37 #include <postmac.h> 38 39 #include "macbackend.hxx" 40 41 #include "com/sun/star/beans/Optional.hpp" 42 #include "rtl/ustrbuf.hxx" 43 #include "osl/file.h" 44 45 #define SPACE ' ' 46 #define SEMI_COLON ';' 47 48 typedef struct 49 { 50 rtl::OUString Server; 51 sal_Int32 Port; 52 } ProxyEntry; 53 54 typedef enum { 55 sHTTP, 56 sHTTPS, 57 sFTP 58 } ServiceType; 59 60 //------------------------------------------------------------------------ 61 // helper functions 62 //------------------------------------------------------------------------ 63 64 namespace // private 65 { 66 67 /* 68 * Returns current proxy settings for selected service type (HTTP or 69 * FTP) as a C string (in the buffer specified by host and hostSize) 70 * and a port number. 71 */ 72 73 bool GetProxySetting(ServiceType sType, char *host, size_t hostSize, UInt16 *port) 74 { 75 bool result; 76 CFDictionaryRef proxyDict; 77 CFNumberRef enableNum; 78 int enable; 79 CFStringRef hostStr; 80 CFNumberRef portNum; 81 int portInt; 82 83 proxyDict = SCDynamicStoreCopyProxies(NULL); 84 85 if (!proxyDict) 86 return false; 87 88 CFStringRef proxiesEnable; 89 CFStringRef proxiesProxy; 90 CFStringRef proxiesPort; 91 92 switch ( sType ) 93 { 94 case sHTTP : proxiesEnable = kSCPropNetProxiesHTTPEnable; 95 proxiesProxy = kSCPropNetProxiesHTTPProxy; 96 proxiesPort = kSCPropNetProxiesHTTPPort; 97 break; 98 case sHTTPS: proxiesEnable = kSCPropNetProxiesHTTPSEnable; 99 proxiesProxy = kSCPropNetProxiesHTTPSProxy; 100 proxiesPort = kSCPropNetProxiesHTTPSPort; 101 break; 102 default: proxiesEnable = kSCPropNetProxiesFTPEnable; 103 proxiesProxy = kSCPropNetProxiesFTPProxy; 104 proxiesPort = kSCPropNetProxiesFTPPort; 105 break; 106 } 107 // Proxy enabled? 108 enableNum = (CFNumberRef) CFDictionaryGetValue( proxyDict, 109 proxiesEnable ); 110 111 result = (enableNum != NULL) && (CFGetTypeID(enableNum) == CFNumberGetTypeID()); 112 113 if (result) 114 result = CFNumberGetValue(enableNum, kCFNumberIntType, &enable) && (enable != 0); 115 116 // Proxy enabled -> get hostname 117 if (result) 118 { 119 hostStr = (CFStringRef) CFDictionaryGetValue( proxyDict, 120 proxiesProxy ); 121 122 result = (hostStr != NULL) && (CFGetTypeID(hostStr) == CFStringGetTypeID()); 123 } 124 125 if (result) 126 result = CFStringGetCString(hostStr, host, (CFIndex) hostSize, kCFStringEncodingASCII); 127 128 // Get proxy port 129 if (result) 130 { 131 portNum = (CFNumberRef) CFDictionaryGetValue( proxyDict, 132 proxiesPort ); 133 134 result = (portNum != NULL) && (CFGetTypeID(portNum) == CFNumberGetTypeID()); 135 } 136 else 137 { 138 CFRelease(proxyDict); 139 return false; 140 } 141 142 if (result) 143 result = CFNumberGetValue(portNum, kCFNumberIntType, &portInt); 144 145 if (result) 146 *port = (UInt16) portInt; 147 148 if (proxyDict) 149 CFRelease(proxyDict); 150 151 if (!result) 152 { 153 *host = 0; 154 *port = 0; 155 } 156 157 return result; 158 } 159 160 } // end private namespace 161 162 //------------------------------------------------------------------------------ 163 164 MacOSXBackend::MacOSXBackend() 165 { 166 } 167 168 //------------------------------------------------------------------------------ 169 170 MacOSXBackend::~MacOSXBackend(void) 171 { 172 } 173 174 //------------------------------------------------------------------------------ 175 176 MacOSXBackend* MacOSXBackend::createInstance() 177 { 178 return new MacOSXBackend; 179 } 180 181 // --------------------------------------------------------------------------------------- 182 183 rtl::OUString CFStringToOUString(const CFStringRef sOrig) { 184 CFRetain(sOrig); 185 186 CFIndex nStringLen = CFStringGetLength(sOrig)+1; 187 188 // Allocate a c string buffer 189 char sBuffer[nStringLen]; 190 191 CFStringGetCString(sOrig, sBuffer, nStringLen, kCFStringEncodingASCII); 192 193 CFRelease(sOrig); 194 195 return rtl::OUString::createFromAscii((sal_Char*)sBuffer); 196 } 197 198 rtl::OUString GetOUString( NSString* pStr ) 199 { 200 if( ! pStr ) 201 return rtl::OUString(); 202 int nLen = [pStr length]; 203 if( nLen == 0 ) 204 return rtl::OUString(); 205 206 rtl::OUStringBuffer aBuf( nLen+1 ); 207 aBuf.setLength( nLen ); 208 [pStr getCharacters: const_cast<sal_Unicode*>(aBuf.getStr())]; 209 return aBuf.makeStringAndClear(); 210 } 211 212 void MacOSXBackend::setPropertyValue( 213 rtl::OUString const &, css::uno::Any const &) 214 throw ( 215 css::beans::UnknownPropertyException, css::beans::PropertyVetoException, 216 css::lang::IllegalArgumentException, css::lang::WrappedTargetException, 217 css::uno::RuntimeException) 218 { 219 throw css::lang::IllegalArgumentException( 220 rtl::OUString( 221 RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")), 222 static_cast< cppu::OWeakObject * >(this), -1); 223 } 224 225 css::uno::Any MacOSXBackend::getPropertyValue( 226 rtl::OUString const & PropertyName) 227 throw ( 228 css::beans::UnknownPropertyException, css::lang::WrappedTargetException, 229 css::uno::RuntimeException) 230 { 231 if (PropertyName.equalsAsciiL( 232 RTL_CONSTASCII_STRINGPARAM("WorkPathVariable"))) 233 { 234 rtl::OUString aDocDir; 235 NSArray* pPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true ); 236 if( pPaths && [pPaths count] > 0 ) 237 { 238 aDocDir = GetOUString( [pPaths objectAtIndex: 0] ); 239 240 rtl::OUString aDocURL; 241 if( aDocDir.getLength() > 0 && 242 osl_getFileURLFromSystemPath( aDocDir.pData, &aDocURL.pData ) == osl_File_E_None ) 243 { 244 return css::uno::makeAny( 245 css::beans::Optional< css::uno::Any >( 246 true, css::uno::makeAny( aDocURL ) ) ); 247 } 248 else 249 { 250 OSL_TRACE( "user documents list contains empty file path or conversion failed" ); 251 } 252 } 253 else 254 { 255 OSL_TRACE( "Got nil or empty list of user document directories" ); 256 } 257 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 258 } else if (PropertyName.equalsAsciiL( 259 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyName"))) 260 { 261 ProxyEntry aFtpProxy; 262 263 char host[MAXHOSTNAMELEN]; 264 UInt16 port; 265 bool retVal; 266 267 retVal = GetProxySetting(sFTP, host, 100, &port); 268 269 if (retVal) 270 { 271 aFtpProxy.Server = rtl::OUString::createFromAscii( host ); 272 } 273 274 // ftp proxy name 275 if( aFtpProxy.Server.getLength() > 0 ) 276 { 277 return css::uno::makeAny( 278 css::beans::Optional< css::uno::Any >( 279 true, uno::makeAny( aFtpProxy.Server ) ) ); 280 } 281 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 282 } else if (PropertyName.equalsAsciiL( 283 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyPort"))) 284 { 285 ProxyEntry aFtpProxy; 286 287 char host[MAXHOSTNAMELEN]; 288 UInt16 port; 289 bool retVal; 290 291 retVal = GetProxySetting(sFTP, host, 100, &port); 292 293 if (retVal) 294 { 295 aFtpProxy.Port = port; 296 } 297 298 // ftp proxy port 299 if( aFtpProxy.Port > 0 ) 300 { 301 return css::uno::makeAny( 302 css::beans::Optional< css::uno::Any >( 303 true, uno::makeAny( aFtpProxy.Port ) ) ); 304 } 305 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 306 } else if (PropertyName.equalsAsciiL( 307 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyName"))) 308 { 309 ProxyEntry aHttpProxy; 310 311 char host[MAXHOSTNAMELEN]; 312 UInt16 port; 313 bool retVal; 314 315 retVal = GetProxySetting(sHTTP, host, 100, &port); 316 317 if (retVal) 318 { 319 aHttpProxy.Server = rtl::OUString::createFromAscii( host ); 320 } 321 322 // http proxy name 323 if( aHttpProxy.Server.getLength() > 0 ) 324 { 325 return css::uno::makeAny( 326 css::beans::Optional< css::uno::Any >( 327 true, uno::makeAny( aHttpProxy.Server ) ) ); 328 } 329 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 330 } else if (PropertyName.equalsAsciiL( 331 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyPort"))) 332 { 333 ProxyEntry aHttpProxy; 334 335 char host[MAXHOSTNAMELEN]; 336 UInt16 port; 337 bool retVal; 338 339 retVal = GetProxySetting(sHTTP, host, 100, &port); 340 341 if (retVal) 342 { 343 aHttpProxy.Port = port; 344 } 345 346 // http proxy port 347 if( aHttpProxy.Port > 0 ) 348 { 349 return css::uno::makeAny( 350 css::beans::Optional< css::uno::Any >( 351 true, uno::makeAny( aHttpProxy.Port ) ) ); 352 } 353 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 354 } else if (PropertyName.equalsAsciiL( 355 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyName"))) 356 { 357 ProxyEntry aHttpsProxy; 358 359 char host[MAXHOSTNAMELEN]; 360 UInt16 port; 361 bool retVal; 362 363 retVal = GetProxySetting(sHTTPS, host, 100, &port); 364 365 if (retVal) 366 { 367 aHttpsProxy.Server = rtl::OUString::createFromAscii( host ); 368 } 369 370 // https proxy name 371 if( aHttpsProxy.Server.getLength() > 0 ) 372 { 373 return css::uno::makeAny( 374 css::beans::Optional< css::uno::Any >( 375 true, uno::makeAny( aHttpsProxy.Server ) ) ); 376 } 377 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 378 } else if (PropertyName.equalsAsciiL( 379 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyPort"))) 380 { 381 ProxyEntry aHttpsProxy; 382 383 char host[MAXHOSTNAMELEN]; 384 UInt16 port; 385 bool retVal; 386 387 retVal = GetProxySetting(sHTTPS, host, 100, &port); 388 389 if (retVal) 390 { 391 aHttpsProxy.Port = port; 392 } 393 394 // https proxy port 395 if( aHttpsProxy.Port > 0 ) 396 { 397 return css::uno::makeAny( 398 css::beans::Optional< css::uno::Any >( 399 true, uno::makeAny( aHttpsProxy.Port ) ) ); 400 } 401 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 402 } else if (PropertyName.equalsAsciiL( 403 RTL_CONSTASCII_STRINGPARAM("ooInetProxyType"))) 404 { 405 // override default for ProxyType, which is "0" meaning "No proxies". 406 sal_Int32 nProperties = 1; 407 return css::uno::makeAny( 408 css::beans::Optional< css::uno::Any >( 409 true, uno::makeAny( nProperties ) ) ); 410 } else if (PropertyName.equalsAsciiL( 411 RTL_CONSTASCII_STRINGPARAM("ooInetNoProxy"))) 412 { 413 rtl::OUString aProxyBypassList; 414 415 CFArrayRef rExceptionsList; 416 CFDictionaryRef rProxyDict = SCDynamicStoreCopyProxies(NULL); 417 418 if (!rProxyDict) 419 rExceptionsList = false; 420 else 421 rExceptionsList = (CFArrayRef) CFDictionaryGetValue(rProxyDict, kSCPropNetProxiesExceptionsList); 422 423 if (rExceptionsList) 424 { 425 for (CFIndex idx = 0; idx < CFArrayGetCount(rExceptionsList); idx++) 426 { 427 CFStringRef rException = (CFStringRef) CFArrayGetValueAtIndex(rExceptionsList, idx); 428 429 if (idx>0) 430 aProxyBypassList += rtl::OUString::createFromAscii( ";" ); 431 432 aProxyBypassList += CFStringToOUString(rException); 433 } 434 } 435 436 if (rProxyDict) 437 CFRelease(rProxyDict); 438 439 // fill proxy bypass list 440 if( aProxyBypassList.getLength() > 0 ) 441 { 442 return css::uno::makeAny( 443 css::beans::Optional< css::uno::Any >( 444 true, 445 uno::makeAny( aProxyBypassList.replace( SPACE, SEMI_COLON ) ) ) ); 446 } 447 return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); 448 } else { 449 throw css::beans::UnknownPropertyException( 450 PropertyName, static_cast< cppu::OWeakObject * >(this)); 451 } 452 } 453 454 //------------------------------------------------------------------------------ 455 456 rtl::OUString SAL_CALL MacOSXBackend::getBackendName(void) 457 { 458 return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.backend.MacOSXBackend"); 459 } 460 461 //------------------------------------------------------------------------------ 462 463 rtl::OUString SAL_CALL MacOSXBackend::getImplementationName(void) 464 throw (uno::RuntimeException) 465 { 466 return getBackendName(); 467 } 468 469 //------------------------------------------------------------------------------ 470 471 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getBackendServiceNames(void) 472 { 473 uno::Sequence<rtl::OUString> aServiceNameList(1); 474 aServiceNameList[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.MacOSXBackend")); 475 476 return aServiceNameList; 477 } 478 479 //------------------------------------------------------------------------------ 480 481 sal_Bool SAL_CALL MacOSXBackend::supportsService(const rtl::OUString& aServiceName) 482 throw (uno::RuntimeException) 483 { 484 uno::Sequence< rtl::OUString > const svc = getBackendServiceNames(); 485 486 for(sal_Int32 i = 0; i < svc.getLength(); ++i ) 487 if(svc[i] == aServiceName) 488 return true; 489 490 return false; 491 } 492 493 //------------------------------------------------------------------------------ 494 495 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void) 496 throw (uno::RuntimeException) 497 { 498 return getBackendServiceNames(); 499 } 500