xref: /AOO41X/main/shell/source/backends/macbe/macbackend.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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