1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
24 // For MAXHOSTNAMELEN constant
25 #include <sys/param.h>
28 #include <SystemConfiguration/SystemConfiguration.h>
29 #include <Foundation/NSPathUtilities.h>
32 #include "macbackend.hxx"
34 #include <com/sun/star/beans/Optional.hpp>
35 #include <com/sun/star/uno/XComponentContext.hpp>
36 #include <cppuhelper/supportsservice.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <sal/log.hxx>
39 #include <osl/diagnose.h>
43 #define SEMI_COLON ';'
54 * Returns current proxy settings for selected service type (HTTP or
55 * HTTPS) as a C string (in the buffer specified by host and hostSize)
59 bool GetProxySetting(ServiceType sType, char *host, size_t hostSize, UInt16 *port)
62 CFDictionaryRef proxyDict;
63 CFNumberRef enableNum;
69 proxyDict = SCDynamicStoreCopyProxies(nullptr);
74 CFStringRef proxiesEnable;
75 CFStringRef proxiesProxy;
76 CFStringRef proxiesPort;
80 case sHTTP : proxiesEnable = kSCPropNetProxiesHTTPEnable;
81 proxiesProxy = kSCPropNetProxiesHTTPProxy;
82 proxiesPort = kSCPropNetProxiesHTTPPort;
84 case sHTTPS: proxiesEnable = kSCPropNetProxiesHTTPSEnable;
85 proxiesProxy = kSCPropNetProxiesHTTPSProxy;
86 proxiesPort = kSCPropNetProxiesHTTPSPort;
90 enableNum = static_cast<CFNumberRef>(CFDictionaryGetValue( proxyDict,
93 result = (enableNum != nullptr) && (CFGetTypeID(enableNum) == CFNumberGetTypeID());
96 result = CFNumberGetValue(enableNum, kCFNumberIntType, &enable) && (enable != 0);
98 // Proxy enabled -> get hostname
101 hostStr = static_cast<CFStringRef>(CFDictionaryGetValue( proxyDict,
104 result = (hostStr != nullptr) && (CFGetTypeID(hostStr) == CFStringGetTypeID());
108 result = CFStringGetCString(hostStr, host, static_cast<CFIndex>(hostSize), kCFStringEncodingASCII);
113 portNum = static_cast<CFNumberRef>(CFDictionaryGetValue( proxyDict,
116 result = (portNum != nullptr) && (CFGetTypeID(portNum) == CFNumberGetTypeID());
120 CFRelease(proxyDict);
125 result = CFNumberGetValue(portNum, kCFNumberIntType, &portInt);
128 *port = static_cast<UInt16>(portInt);
131 CFRelease(proxyDict);
142 } // unnamed namespace
144 MacOSXBackend::MacOSXBackend()
148 MacOSXBackend::~MacOSXBackend(void)
152 static OUString CFStringToOUString(const CFStringRef sOrig) {
155 CFIndex nStringLen = CFStringGetLength(sOrig)+1;
157 // Allocate a c string buffer
158 auto const sBuffer = std::make_unique<char[]>(nStringLen);
160 CFStringGetCString(sOrig, sBuffer.get(), nStringLen, kCFStringEncodingASCII);
164 return OUString::createFromAscii(sBuffer.get());
167 static OUString GetOUString( NSString* pStr )
171 int nLen = [pStr length];
175 OUStringBuffer aBuf( nLen+1 );
176 aBuf.setLength( nLen );
178 reinterpret_cast<unichar *>(const_cast<sal_Unicode*>(aBuf.getStr()))];
179 return aBuf.makeStringAndClear();
182 void MacOSXBackend::setPropertyValue(
183 OUString const &, css::uno::Any const &)
185 throw css::lang::IllegalArgumentException(
186 "setPropertyValue not supported",
190 css::uno::Any MacOSXBackend::getPropertyValue(
191 OUString const & PropertyName)
193 if ( PropertyName == "WorkPathVariable" )
196 NSArray* pPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true );
197 if( pPaths && [pPaths count] > 0 )
199 aDocDir = GetOUString( [pPaths objectAtIndex: 0] );
202 if( aDocDir.getLength() > 0 &&
203 osl_getFileURLFromSystemPath( aDocDir.pData, &aDocURL.pData ) == osl_File_E_None )
205 return css::uno::Any(
206 css::beans::Optional< css::uno::Any >(
207 true, css::uno::Any( aDocURL ) ) );
211 SAL_WARN("shell", "user documents list contains empty file path or conversion failed" );
216 SAL_WARN("shell", "Got nil or empty list of user document directories" );
218 return css::uno::Any(css::beans::Optional< css::uno::Any >());
219 } else if ( PropertyName == "ooInetHTTPProxyName" )
221 char host[MAXHOSTNAMELEN];
225 retVal = GetProxySetting(sHTTP, host, 100, &port);
229 auto const Server = OUString::createFromAscii( host );
230 if( Server.getLength() > 0 )
232 return css::uno::Any(
233 css::beans::Optional< css::uno::Any >(
234 true, uno::Any( Server ) ) );
237 return css::uno::Any(css::beans::Optional< css::uno::Any >());
238 } else if ( PropertyName == "ooInetHTTPProxyPort" )
240 char host[MAXHOSTNAMELEN];
244 retVal = GetProxySetting(sHTTP, host, 100, &port);
246 if (retVal && port > 0)
248 return css::uno::Any(
249 css::beans::Optional< css::uno::Any >(
250 true, uno::Any( sal_Int32(port) ) ) );
252 return css::uno::Any(css::beans::Optional< css::uno::Any >());
253 } else if ( PropertyName == "ooInetHTTPSProxyName" )
255 char host[MAXHOSTNAMELEN];
259 retVal = GetProxySetting(sHTTPS, host, 100, &port);
263 auto const Server = OUString::createFromAscii( host );
264 if( Server.getLength() > 0 )
266 return css::uno::Any(
267 css::beans::Optional< css::uno::Any >(
268 true, uno::Any( Server ) ) );
271 return css::uno::Any(css::beans::Optional< css::uno::Any >());
272 } else if ( PropertyName == "ooInetHTTPSProxyPort" )
274 char host[MAXHOSTNAMELEN];
278 retVal = GetProxySetting(sHTTPS, host, 100, &port);
280 if (retVal && port > 0)
282 return css::uno::Any(
283 css::beans::Optional< css::uno::Any >(
284 true, uno::Any( sal_Int32(port) ) ) );
286 return css::uno::Any(css::beans::Optional< css::uno::Any >());
287 } else if ( PropertyName == "ooInetProxyType" )
289 // override default for ProxyType, which is "0" meaning "No proxies".
290 return css::uno::Any(
291 css::beans::Optional< css::uno::Any >(
292 true, uno::Any( sal_Int32(1) ) ) );
293 } else if ( PropertyName == "ooInetNoProxy" )
295 OUString aProxyBypassList;
297 CFArrayRef rExceptionsList;
298 CFDictionaryRef rProxyDict = SCDynamicStoreCopyProxies(nullptr);
301 rExceptionsList = nullptr;
303 rExceptionsList = static_cast<CFArrayRef>(CFDictionaryGetValue(rProxyDict, kSCPropNetProxiesExceptionsList));
307 for (CFIndex idx = 0; idx < CFArrayGetCount(rExceptionsList); idx++)
309 CFStringRef rException = static_cast<CFStringRef>(CFArrayGetValueAtIndex(rExceptionsList, idx));
312 aProxyBypassList += ";";
314 aProxyBypassList += CFStringToOUString(rException);
319 CFRelease(rProxyDict);
321 // fill proxy bypass list
322 if( aProxyBypassList.getLength() > 0 )
324 return css::uno::Any(
325 css::beans::Optional< css::uno::Any >(
327 uno::Any( aProxyBypassList.replace( SPACE, SEMI_COLON ) ) ) );
329 return css::uno::Any(css::beans::Optional< css::uno::Any >());
331 throw css::beans::UnknownPropertyException(
332 PropertyName, getXWeak());
336 OUString SAL_CALL MacOSXBackend::getImplementationName(void)
338 return "com.sun.star.comp.configuration.backend.MacOSXBackend";
341 sal_Bool SAL_CALL MacOSXBackend::supportsService(const OUString& aServiceName)
343 return cppu::supportsService(this, aServiceName);
346 uno::Sequence<OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void)
348 return { "com.sun.star.configuration.backend.MacOSXBackend" };
351 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
352 shell_MacOSXBackend_get_implementation(
353 css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
355 return cppu::acquire(new MacOSXBackend());
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */