1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <unistd.h>
21 #include <string.h>
22 
23 #include <config_features.h>
24 
25 #include "system.hxx"
26 
27 #ifdef NO_PTHREAD_RTL
28 
29 #if defined(MACOSX)
30 
31 #include <premac.h>
32 #include <Foundation/Foundation.h>
33 #include <postmac.h>
34 
35 /*
36  * Add support for resolving Mac native alias files (not the same as unix alias files)
37  * (what are "unix alias files"?)
38  * returns 0 on success.
39  */
macxp_resolveAlias(char * path,int buflen)40 int macxp_resolveAlias(char *path, int buflen)
41 {
42 #if HAVE_FEATURE_MACOSX_SANDBOX
43   /* Avoid unnecessary messages in the system.log:
44    *
45    * soffice(57342) deny file-read-data /Users/tml/Documents/b.odt/..namedfork/rsrc
46    * etc.
47    *
48    * Just don't bother with resolving aliases. I doubt its usefulness anyway.
49    */
50   (void) path;
51   (void) buflen;
52   return 0;
53 #else
54   CFStringRef cfpath;
55   CFURLRef cfurl;
56   CFErrorRef cferror;
57   CFDataRef cfbookmark;
58 
59   // Don't even try anything for files inside the app bundle. Just a
60   // waste of time.
61 
62   static const char * const appBundle = [[[NSBundle mainBundle] bundlePath] UTF8String];
63 
64   const size_t appBundleLen = strlen(appBundle);
65   if (strncmp(path, appBundle, appBundleLen) == 0 && path[appBundleLen] == '/')
66       return 0;
67 
68   char *unprocessedPath = path;
69 
70   if ( *unprocessedPath == '/' )
71       unprocessedPath++;
72 
73   int nRet = 0;
74   while ( !nRet && unprocessedPath && *unprocessedPath )
75   {
76       unprocessedPath = strchr( unprocessedPath, '/' );
77       if ( unprocessedPath )
78           *unprocessedPath = '\0';
79 
80       cfpath = CFStringCreateWithCString( nullptr, path, kCFStringEncodingUTF8 );
81       cfurl = CFURLCreateWithFileSystemPath( nullptr, cfpath, kCFURLPOSIXPathStyle, false );
82       CFRelease( cfpath );
83       cferror = nullptr;
84       cfbookmark = CFURLCreateBookmarkDataFromFile( nullptr, cfurl, &cferror );
85       CFRelease( cfurl );
86 
87       if ( cfbookmark == nullptr )
88       {
89           if(cferror)
90           {
91               CFRelease( cferror );
92           }
93       }
94       else
95       {
96           Boolean isStale;
97           cfurl = CFURLCreateByResolvingBookmarkData( nullptr, cfbookmark, kCFBookmarkResolutionWithoutUIMask,
98                                                       nullptr, nullptr, &isStale, &cferror );
99           CFRelease( cfbookmark );
100           if ( cfurl == nullptr )
101           {
102               CFRelease( cferror );
103           }
104           else
105           {
106               cfpath = CFURLCopyFileSystemPath( cfurl, kCFURLPOSIXPathStyle );
107               CFRelease( cfurl );
108               if ( cfpath != nullptr )
109               {
110                   char tmpPath[ PATH_MAX ];
111                   if ( CFStringGetCString( cfpath, tmpPath, PATH_MAX, kCFStringEncodingUTF8 ) )
112                   {
113                       int nLen = strlen( tmpPath ) + ( unprocessedPath ? strlen( unprocessedPath + 1 ) + 1 : 0 );
114                       if ( nLen < buflen && nLen < PATH_MAX )
115                       {
116                           if ( unprocessedPath )
117                           {
118                               int nTmpPathLen = strlen( tmpPath );
119                               strcat( tmpPath, "/" );
120                               strcat( tmpPath, unprocessedPath + 1 );
121                               strcpy( path, tmpPath);
122                               unprocessedPath = path + nTmpPathLen;
123                           }
124                           else if ( !unprocessedPath )
125                           {
126                               strcpy( path, tmpPath );
127                           }
128                       }
129                       else
130                       {
131                           errno = ENAMETOOLONG;
132                           nRet = -1;
133                       }
134                   }
135                   CFRelease( cfpath );
136               }
137           }
138       }
139 
140       if ( unprocessedPath )
141           *unprocessedPath++ = '/';
142   }
143 
144   return nRet;
145 #endif
146 }
147 
148 #endif  /* defined MACOSX */
149 
150 #endif /* NO_PTHREAD_RTL */
151 
152 //might be useful on other platforms, but doesn't compiler under MACOSX anyway
153 #if defined(__GNUC__) && defined(LINUX)
154 //force the __data_start symbol to exist in any executables that link against
155 //libuno_sal so that dlopening of the libgcj provided libjvm.so on some
156 //platforms where it needs that symbol will succeed. e.g. Debian mips/lenny
157 //with gcc 4.3. With this in place the smoketest succeeds with libgcj provided
158 //java. Quite possibly also required/helpful for s390x/s390 and maybe some
159 //others. Without it the dlopen of libjvm.so will fail with __data_start
160 //not found
161 extern int __data_start[] __attribute__((weak));
162 extern int data_start[] __attribute__((weak));
163 extern int _end[] __attribute__((weak));
164 static void *dummy[] __attribute__((used)) = {__data_start, data_start, _end};
165 #endif
166 
167 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
168