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