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