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
GetProxySetting(ServiceType sType,char * host,size_t hostSize,UInt16 * port)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
MacOSXBackend()160 MacOSXBackend::MacOSXBackend()
161 {
162 }
163
164 //------------------------------------------------------------------------------
165
~MacOSXBackend(void)166 MacOSXBackend::~MacOSXBackend(void)
167 {
168 }
169
170 //------------------------------------------------------------------------------
171
createInstance()172 MacOSXBackend* MacOSXBackend::createInstance()
173 {
174 return new MacOSXBackend;
175 }
176
177 // ---------------------------------------------------------------------------------------
178
CFStringToOUString(const CFStringRef sOrig)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
GetOUString(NSString * pStr)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
setPropertyValue(rtl::OUString const &,css::uno::Any const &)208 void MacOSXBackend::setPropertyValue(
209 rtl::OUString const &, css::uno::Any const &)
210 throw (
211 css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
212 css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
213 css::uno::RuntimeException)
214 {
215 throw css::lang::IllegalArgumentException(
216 rtl::OUString(
217 RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")),
218 static_cast< cppu::OWeakObject * >(this), -1);
219 }
220
getPropertyValue(rtl::OUString const & PropertyName)221 css::uno::Any MacOSXBackend::getPropertyValue(
222 rtl::OUString const & PropertyName)
223 throw (
224 css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
225 css::uno::RuntimeException)
226 {
227 if (PropertyName.equalsAsciiL(
228 RTL_CONSTASCII_STRINGPARAM("WorkPathVariable")))
229 {
230 rtl::OUString aDocDir;
231 NSArray* pPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, true );
232 if( pPaths && [pPaths count] > 0 )
233 {
234 aDocDir = GetOUString( [pPaths objectAtIndex: 0] );
235
236 rtl::OUString aDocURL;
237 if( aDocDir.getLength() > 0 &&
238 osl_getFileURLFromSystemPath( aDocDir.pData, &aDocURL.pData ) == osl_File_E_None )
239 {
240 return css::uno::makeAny(
241 css::beans::Optional< css::uno::Any >(
242 true, css::uno::makeAny( aDocURL ) ) );
243 }
244 else
245 {
246 OSL_TRACE( "user documents list contains empty file path or conversion failed" );
247 }
248 }
249 else
250 {
251 OSL_TRACE( "Got nil or empty list of user document directories" );
252 }
253 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
254 } else if (PropertyName.equalsAsciiL(
255 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyName")))
256 {
257 ProxyEntry aFtpProxy;
258
259 char host[MAXHOSTNAMELEN];
260 UInt16 port;
261 bool retVal;
262
263 retVal = GetProxySetting(sFTP, host, 100, &port);
264
265 if (retVal)
266 {
267 aFtpProxy.Server = rtl::OUString::createFromAscii( host );
268 }
269
270 // ftp proxy name
271 if( aFtpProxy.Server.getLength() > 0 )
272 {
273 return css::uno::makeAny(
274 css::beans::Optional< css::uno::Any >(
275 true, uno::makeAny( aFtpProxy.Server ) ) );
276 }
277 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
278 } else if (PropertyName.equalsAsciiL(
279 RTL_CONSTASCII_STRINGPARAM("ooInetFTPProxyPort")))
280 {
281 ProxyEntry aFtpProxy;
282
283 char host[MAXHOSTNAMELEN];
284 UInt16 port;
285 bool retVal;
286
287 retVal = GetProxySetting(sFTP, host, 100, &port);
288
289 if (retVal)
290 {
291 aFtpProxy.Port = port;
292 }
293
294 // ftp proxy port
295 if( aFtpProxy.Port > 0 )
296 {
297 return css::uno::makeAny(
298 css::beans::Optional< css::uno::Any >(
299 true, uno::makeAny( aFtpProxy.Port ) ) );
300 }
301 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
302 } else if (PropertyName.equalsAsciiL(
303 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyName")))
304 {
305 ProxyEntry aHttpProxy;
306
307 char host[MAXHOSTNAMELEN];
308 UInt16 port;
309 bool retVal;
310
311 retVal = GetProxySetting(sHTTP, host, 100, &port);
312
313 if (retVal)
314 {
315 aHttpProxy.Server = rtl::OUString::createFromAscii( host );
316 }
317
318 // http proxy name
319 if( aHttpProxy.Server.getLength() > 0 )
320 {
321 return css::uno::makeAny(
322 css::beans::Optional< css::uno::Any >(
323 true, uno::makeAny( aHttpProxy.Server ) ) );
324 }
325 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
326 } else if (PropertyName.equalsAsciiL(
327 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPProxyPort")))
328 {
329 ProxyEntry aHttpProxy;
330
331 char host[MAXHOSTNAMELEN];
332 UInt16 port;
333 bool retVal;
334
335 retVal = GetProxySetting(sHTTP, host, 100, &port);
336
337 if (retVal)
338 {
339 aHttpProxy.Port = port;
340 }
341
342 // http proxy port
343 if( aHttpProxy.Port > 0 )
344 {
345 return css::uno::makeAny(
346 css::beans::Optional< css::uno::Any >(
347 true, uno::makeAny( aHttpProxy.Port ) ) );
348 }
349 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
350 } else if (PropertyName.equalsAsciiL(
351 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyName")))
352 {
353 ProxyEntry aHttpsProxy;
354
355 char host[MAXHOSTNAMELEN];
356 UInt16 port;
357 bool retVal;
358
359 retVal = GetProxySetting(sHTTPS, host, 100, &port);
360
361 if (retVal)
362 {
363 aHttpsProxy.Server = rtl::OUString::createFromAscii( host );
364 }
365
366 // https proxy name
367 if( aHttpsProxy.Server.getLength() > 0 )
368 {
369 return css::uno::makeAny(
370 css::beans::Optional< css::uno::Any >(
371 true, uno::makeAny( aHttpsProxy.Server ) ) );
372 }
373 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
374 } else if (PropertyName.equalsAsciiL(
375 RTL_CONSTASCII_STRINGPARAM("ooInetHTTPSProxyPort")))
376 {
377 ProxyEntry aHttpsProxy;
378
379 char host[MAXHOSTNAMELEN];
380 UInt16 port;
381 bool retVal;
382
383 retVal = GetProxySetting(sHTTPS, host, 100, &port);
384
385 if (retVal)
386 {
387 aHttpsProxy.Port = port;
388 }
389
390 // https proxy port
391 if( aHttpsProxy.Port > 0 )
392 {
393 return css::uno::makeAny(
394 css::beans::Optional< css::uno::Any >(
395 true, uno::makeAny( aHttpsProxy.Port ) ) );
396 }
397 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
398 } else if (PropertyName.equalsAsciiL(
399 RTL_CONSTASCII_STRINGPARAM("ooInetProxyType")))
400 {
401 // override default for ProxyType, which is "0" meaning "No proxies".
402 sal_Int32 nProperties = 1;
403 return css::uno::makeAny(
404 css::beans::Optional< css::uno::Any >(
405 true, uno::makeAny( nProperties ) ) );
406 } else if (PropertyName.equalsAsciiL(
407 RTL_CONSTASCII_STRINGPARAM("ooInetNoProxy")))
408 {
409 rtl::OUString aProxyBypassList;
410
411 CFArrayRef rExceptionsList;
412 CFDictionaryRef rProxyDict = SCDynamicStoreCopyProxies(NULL);
413
414 if (!rProxyDict)
415 rExceptionsList = nil;
416 else
417 rExceptionsList = (CFArrayRef) CFDictionaryGetValue(rProxyDict, kSCPropNetProxiesExceptionsList);
418
419 if (rExceptionsList)
420 {
421 for (CFIndex idx = 0; idx < CFArrayGetCount(rExceptionsList); idx++)
422 {
423 CFStringRef rException = (CFStringRef) CFArrayGetValueAtIndex(rExceptionsList, idx);
424
425 if (idx>0)
426 aProxyBypassList += rtl::OUString::createFromAscii( ";" );
427
428 aProxyBypassList += CFStringToOUString(rException);
429 }
430 }
431
432 if (rProxyDict)
433 CFRelease(rProxyDict);
434
435 // fill proxy bypass list
436 if( aProxyBypassList.getLength() > 0 )
437 {
438 return css::uno::makeAny(
439 css::beans::Optional< css::uno::Any >(
440 true,
441 uno::makeAny( aProxyBypassList.replace( SPACE, SEMI_COLON ) ) ) );
442 }
443 return css::uno::makeAny(css::beans::Optional< css::uno::Any >());
444 } else {
445 throw css::beans::UnknownPropertyException(
446 PropertyName, static_cast< cppu::OWeakObject * >(this));
447 }
448 }
449
450 //------------------------------------------------------------------------------
451
getBackendName(void)452 rtl::OUString SAL_CALL MacOSXBackend::getBackendName(void)
453 {
454 return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.backend.MacOSXBackend");
455 }
456
457 //------------------------------------------------------------------------------
458
getImplementationName(void)459 rtl::OUString SAL_CALL MacOSXBackend::getImplementationName(void)
460 throw (uno::RuntimeException)
461 {
462 return getBackendName();
463 }
464
465 //------------------------------------------------------------------------------
466
getBackendServiceNames(void)467 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getBackendServiceNames(void)
468 {
469 uno::Sequence<rtl::OUString> aServiceNameList(1);
470 aServiceNameList[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.MacOSXBackend"));
471
472 return aServiceNameList;
473 }
474
475 //------------------------------------------------------------------------------
476
supportsService(const rtl::OUString & aServiceName)477 sal_Bool SAL_CALL MacOSXBackend::supportsService(const rtl::OUString& aServiceName)
478 throw (uno::RuntimeException)
479 {
480 uno::Sequence< rtl::OUString > const svc = getBackendServiceNames();
481
482 for(sal_Int32 i = 0; i < svc.getLength(); ++i )
483 if(svc[i] == aServiceName)
484 return true;
485
486 return false;
487 }
488
489 //------------------------------------------------------------------------------
490
getSupportedServiceNames(void)491 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void)
492 throw (uno::RuntimeException)
493 {
494 return getBackendServiceNames();
495 }
496