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 {
211 throw css::lang::IllegalArgumentException(
212 rtl::OUString(
213 RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")),
214 static_cast< cppu::OWeakObject * >(this), -1);
215 }
216
getPropertyValue(rtl::OUString const & PropertyName)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
getBackendName(void)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
getImplementationName(void)452 rtl::OUString SAL_CALL MacOSXBackend::getImplementationName(void)
453 {
454 return getBackendName();
455 }
456
457 //------------------------------------------------------------------------------
458
getBackendServiceNames(void)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
supportsService(const rtl::OUString & aServiceName)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
getSupportedServiceNames(void)482 uno::Sequence<rtl::OUString> SAL_CALL MacOSXBackend::getSupportedServiceNames(void)
483 {
484 return getBackendServiceNames();
485 }
486