xref: /AOO42X/main/sal/osl/os2/file_url.cxx (revision 87d2adbc9cadf14644c3679b041b9226f7630199)
1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <ctype.h>
25cdf0e10cSrcweir #include "system.h"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #ifndef _LIMITS_H
28cdf0e10cSrcweir #include <limits.h>
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #ifndef _ERRNO_H
32cdf0e10cSrcweir #include <errno.h>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #ifndef _STDLIB_H_
36cdf0e10cSrcweir #include <stdlib.h>
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #ifndef _STRINGS_H
40cdf0e10cSrcweir #include <strings.h>
41cdf0e10cSrcweir #endif
42cdf0e10cSrcweir 
43cdf0e10cSrcweir #ifndef _UNISTD_H
44cdf0e10cSrcweir #include <unistd.h>
45cdf0e10cSrcweir #endif
46cdf0e10cSrcweir #include <osl/file.h>
47cdf0e10cSrcweir #include <osl/security.h>
48cdf0e10cSrcweir #include <rtl/uri.h>
49cdf0e10cSrcweir #include <osl/diagnose.h>
50cdf0e10cSrcweir #include <rtl/ustring.hxx>
51cdf0e10cSrcweir #include <rtl/ustrbuf.h>
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #ifndef _OSL_TREAD_H_
54cdf0e10cSrcweir #include <osl/thread.h>
55cdf0e10cSrcweir #endif
56cdf0e10cSrcweir #include <osl/file.hxx>
57cdf0e10cSrcweir #include <osl/mutex.h>
58cdf0e10cSrcweir #include <osl/process.h>
59cdf0e10cSrcweir #include "file_error_transl.h"
60cdf0e10cSrcweir 
61cdf0e10cSrcweir #ifndef _FILE_URL_H_
62cdf0e10cSrcweir #include "file_url.h"
63cdf0e10cSrcweir #endif
64cdf0e10cSrcweir #include "file_path_helper.hxx"
65cdf0e10cSrcweir 
66cdf0e10cSrcweir #ifndef _OSL_UUNXAPI_HXX_
67cdf0e10cSrcweir #include "uunxapi.hxx"
68cdf0e10cSrcweir #endif
69cdf0e10cSrcweir 
70cdf0e10cSrcweir #include <wchar.h>
71cdf0e10cSrcweir #include <wctype.h>
72cdf0e10cSrcweir 
73cdf0e10cSrcweir /***************************************************
74cdf0e10cSrcweir 
75cdf0e10cSrcweir  General note
76cdf0e10cSrcweir 
77cdf0e10cSrcweir  This file contains the part that handles File URLs.
78cdf0e10cSrcweir 
79cdf0e10cSrcweir  File URLs as scheme specific notion of URIs
80cdf0e10cSrcweir  (RFC2396) may be handled platform independend, but
81cdf0e10cSrcweir  will not in osl which is considered wrong.
82cdf0e10cSrcweir  Future version of osl should handle File URLs this
83cdf0e10cSrcweir  way. In rtl/uri there is already an URI parser etc.
84cdf0e10cSrcweir  so this code should be consolidated.
85cdf0e10cSrcweir 
86cdf0e10cSrcweir  **************************************************/
87cdf0e10cSrcweir 
88cdf0e10cSrcweir oslMutex g_CurrentDirectoryMutex;
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
91cdf0e10cSrcweir /***************************************************
92cdf0e10cSrcweir  * forward
93cdf0e10cSrcweir  **************************************************/
94cdf0e10cSrcweir 
95cdf0e10cSrcweir void _osl_warnFile(const char*, rtl_uString*);
96cdf0e10cSrcweir rtl_uString*  oslMakeUStrFromPsz(const sal_Char* pszStr,rtl_uString** uStr);
97cdf0e10cSrcweir 
98cdf0e10cSrcweir extern "C" int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32);
99cdf0e10cSrcweir extern "C" int TextToUnicode(const char* text, size_t text_buffer_size, sal_Unicode* unic_text, sal_Int32 unic_text_buffer_size);
100cdf0e10cSrcweir 
101cdf0e10cSrcweir /***************************************************
102cdf0e10cSrcweir  * namespace directives
103cdf0e10cSrcweir  **************************************************/
104cdf0e10cSrcweir 
105cdf0e10cSrcweir using namespace osl;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir /******************************************************************************
108cdf0e10cSrcweir  *
109cdf0e10cSrcweir  *                  Exported Module Functions
110cdf0e10cSrcweir  *
111cdf0e10cSrcweir  *****************************************************************************/
112cdf0e10cSrcweir 
113cdf0e10cSrcweir /* a slightly modified version of Pchar in rtl/source/uri.c */
114cdf0e10cSrcweir const sal_Bool uriCharClass[128] =
115cdf0e10cSrcweir {
116cdf0e10cSrcweir   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
117cdf0e10cSrcweir   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118cdf0e10cSrcweir   0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./  */
119cdf0e10cSrcweir   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /* 0123456789:;<=>? */
120cdf0e10cSrcweir   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ABCDEFGHIJKLMNO */
121cdf0e10cSrcweir   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* PQRSTUVWXYZ[\]^_ */
122cdf0e10cSrcweir   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* `abcdefghijklmno */
123cdf0e10cSrcweir   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0  /* pqrstuvwxyz{|}~  */
124cdf0e10cSrcweir };
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 
127cdf0e10cSrcweir /* check for top wrong usage strings */
128cdf0e10cSrcweir /*
129cdf0e10cSrcweir static sal_Bool findWrongUsage( const sal_Unicode *path, sal_Int32 len )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir     rtl_uString *pTmp = NULL;
132cdf0e10cSrcweir     sal_Bool bRet;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir     rtl_uString_newFromStr_WithLength( &pTmp, path, len );
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     rtl_ustr_toAsciiLowerCase_WithLength( pTmp->buffer, pTmp->length );
137cdf0e10cSrcweir 
138cdf0e10cSrcweir     bRet = ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "ftp://", 6 ) ) ||
139cdf0e10cSrcweir            ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "http://", 7 ) ) ||
140cdf0e10cSrcweir            ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "vnd.sun.star", 12 ) ) ||
141cdf0e10cSrcweir            ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "private:", 8 ) ) ||
142cdf0e10cSrcweir            ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "slot:", 5) );
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     rtl_uString_release( pTmp );
145cdf0e10cSrcweir     return bRet;
146cdf0e10cSrcweir }
147cdf0e10cSrcweir */
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 
150cdf0e10cSrcweir /****************************************************************************/
151cdf0e10cSrcweir /*  osl_getFileURLFromSystemPath */
152cdf0e10cSrcweir /****************************************************************************/
153cdf0e10cSrcweir 
154cdf0e10cSrcweir BOOL WINAPI IsValidFilePathComponent(
155cdf0e10cSrcweir     LPCTSTR lpComponent, LPCTSTR *lppComponentEnd, DWORD dwFlags)
156cdf0e10cSrcweir {
157cdf0e10cSrcweir     LPCTSTR lpComponentEnd = NULL;
158cdf0e10cSrcweir     LPCTSTR lpCurrent = lpComponent;
159cdf0e10cSrcweir     BOOL    fValid = TRUE;  /* Assume success */
160cdf0e10cSrcweir     TCHAR   cLast = 0;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     /* Path component length must not exceed MAX_PATH */
163cdf0e10cSrcweir 
164cdf0e10cSrcweir     while ( !lpComponentEnd && lpCurrent && lpCurrent - lpComponent < _MAX_PATH )
165cdf0e10cSrcweir     {
166cdf0e10cSrcweir         switch ( *lpCurrent )
167cdf0e10cSrcweir         {
168cdf0e10cSrcweir             /* Both backslash and slash determine the end of a path component */
169cdf0e10cSrcweir         case '\0':
170cdf0e10cSrcweir         case '/':
171cdf0e10cSrcweir         case '\\':
172cdf0e10cSrcweir             switch ( cLast )
173cdf0e10cSrcweir             {
174cdf0e10cSrcweir                 /* Component must not end with '.' or blank and can't be empty */
175cdf0e10cSrcweir 
176cdf0e10cSrcweir             case '.':
177cdf0e10cSrcweir                 if ( dwFlags & VALIDATEPATH_ALLOW_ELLIPSE )
178cdf0e10cSrcweir                 {
179cdf0e10cSrcweir                     if ( 1 == lpCurrent - lpComponent )
180cdf0e10cSrcweir                     {
181cdf0e10cSrcweir                         /* Current directory is O.K. */
182cdf0e10cSrcweir                         lpComponentEnd = lpCurrent;
183cdf0e10cSrcweir                         break;
184cdf0e10cSrcweir                     }
185cdf0e10cSrcweir                     else if ( 2 == lpCurrent - lpComponent && '.' == *lpComponent )
186cdf0e10cSrcweir                     {
187cdf0e10cSrcweir                         /* Parent directory is O.K. */
188cdf0e10cSrcweir                         lpComponentEnd = lpCurrent;
189cdf0e10cSrcweir                         break;
190cdf0e10cSrcweir                     }
191cdf0e10cSrcweir                 }
192cdf0e10cSrcweir             case 0:
193cdf0e10cSrcweir             case ' ':
194cdf0e10cSrcweir                 lpComponentEnd = lpCurrent - 1;
195cdf0e10cSrcweir                 fValid = FALSE;
196cdf0e10cSrcweir                 break;
197cdf0e10cSrcweir             default:
198cdf0e10cSrcweir                 lpComponentEnd = lpCurrent;
199cdf0e10cSrcweir                 break;
200cdf0e10cSrcweir             }
201cdf0e10cSrcweir             break;
202cdf0e10cSrcweir             /* '?' and '*' are valid wildcards but not valid file name characters */
203cdf0e10cSrcweir         case '?':
204cdf0e10cSrcweir         case '*':
205cdf0e10cSrcweir             if ( dwFlags & VALIDATEPATH_ALLOW_WILDCARDS )
206cdf0e10cSrcweir                 break;
207cdf0e10cSrcweir             /* The following characters are reserved */
208cdf0e10cSrcweir         case '<':
209cdf0e10cSrcweir         case '>':
210cdf0e10cSrcweir         case '\"':
211cdf0e10cSrcweir         case '|':
212cdf0e10cSrcweir         case ':':
213cdf0e10cSrcweir             lpComponentEnd = lpCurrent;
214cdf0e10cSrcweir             fValid = FALSE;
215cdf0e10cSrcweir             break;
216cdf0e10cSrcweir         default:
217cdf0e10cSrcweir             /* Characters below ASCII 32 are not allowed */
218cdf0e10cSrcweir             if ( *lpCurrent < ' ' )
219cdf0e10cSrcweir             {
220cdf0e10cSrcweir                 lpComponentEnd = lpCurrent;
221cdf0e10cSrcweir                 fValid = FALSE;
222cdf0e10cSrcweir             }
223cdf0e10cSrcweir             break;
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir         cLast = *lpCurrent++;
226cdf0e10cSrcweir     }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     /*  If we don't reached the end of the component the length of the component was to long
229cdf0e10cSrcweir         ( See condition of while loop ) */
230cdf0e10cSrcweir     if ( !lpComponentEnd )
231cdf0e10cSrcweir     {
232cdf0e10cSrcweir         fValid = FALSE;
233cdf0e10cSrcweir         lpComponentEnd = lpCurrent;
234cdf0e10cSrcweir     }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     /* Test wether the component specifies a device name what is not allowed */
237cdf0e10cSrcweir 
238cdf0e10cSrcweir     // MT: PERFORMANCE:
239cdf0e10cSrcweir     // This is very expensive. A lot of calls to _tcsicmp.
240cdf0e10cSrcweir     // in SRC6870m71 67.000 calls of this method while empty office start result into more than 1.500.00 calls of _tcsicmp!
241cdf0e10cSrcweir     // Possible optimizations
242cdf0e10cSrcweir     // - Array should be const static
243cdf0e10cSrcweir     // - Sorted array, use binary search
244cdf0e10cSrcweir     // - More intelligent check for com1-9, lpt1-9
245cdf0e10cSrcweir     // Maybe make szComponent upper case, don't search case intensitive
246cdf0e10cSrcweir     // Talked to HRO: Could be removed. Shouldn't be used in OOo, and if used for something like a filename, it will lead to an error anyway.
247cdf0e10cSrcweir     /*
248cdf0e10cSrcweir     if ( fValid )
249cdf0e10cSrcweir     {
250cdf0e10cSrcweir         LPCTSTR alpDeviceNames[] =
251cdf0e10cSrcweir         {
252cdf0e10cSrcweir             TEXT("CON"),
253cdf0e10cSrcweir             TEXT("PRN"),
254cdf0e10cSrcweir             TEXT("AUX"),
255cdf0e10cSrcweir             TEXT("CLOCK$"),
256cdf0e10cSrcweir             TEXT("NUL"),
257cdf0e10cSrcweir             TEXT("LPT1"),
258cdf0e10cSrcweir             TEXT("LPT2"),
259cdf0e10cSrcweir             TEXT("LPT3"),
260cdf0e10cSrcweir             TEXT("LPT4"),
261cdf0e10cSrcweir             TEXT("LPT5"),
262cdf0e10cSrcweir             TEXT("LPT6"),
263cdf0e10cSrcweir             TEXT("LPT7"),
264cdf0e10cSrcweir             TEXT("LPT8"),
265cdf0e10cSrcweir             TEXT("LPT9"),
266cdf0e10cSrcweir             TEXT("COM1"),
267cdf0e10cSrcweir             TEXT("COM2"),
268cdf0e10cSrcweir             TEXT("COM3"),
269cdf0e10cSrcweir             TEXT("COM4"),
270cdf0e10cSrcweir             TEXT("COM5"),
271cdf0e10cSrcweir             TEXT("COM6"),
272cdf0e10cSrcweir             TEXT("COM7"),
273cdf0e10cSrcweir             TEXT("COM8"),
274cdf0e10cSrcweir             TEXT("COM9")
275cdf0e10cSrcweir         };
276cdf0e10cSrcweir 
277cdf0e10cSrcweir         TCHAR   szComponent[MAX_PATH];
278cdf0e10cSrcweir         int     nComponentLength;
279cdf0e10cSrcweir         LPCTSTR lpDot;
280cdf0e10cSrcweir         int     i;
281cdf0e10cSrcweir 
282cdf0e10cSrcweir         // A device name with an extension is also invalid
283cdf0e10cSrcweir         lpDot = _tcschr( lpComponent, '.' );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         if ( !lpDot || lpDot > lpComponentEnd )
286cdf0e10cSrcweir             nComponentLength = lpComponentEnd - lpComponent;
287cdf0e10cSrcweir         else
288cdf0e10cSrcweir             nComponentLength = lpDot - lpComponent;
289cdf0e10cSrcweir 
290cdf0e10cSrcweir         _tcsncpy( szComponent, lpComponent, nComponentLength );
291cdf0e10cSrcweir         szComponent[nComponentLength] = 0;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir         for ( i = 0; i < sizeof( alpDeviceNames ) / sizeof(LPCTSTR); i++ )
294cdf0e10cSrcweir         {
295cdf0e10cSrcweir             if ( 0 == _tcsicmp( szComponent, alpDeviceNames[i] ) )
296cdf0e10cSrcweir             {
297cdf0e10cSrcweir                 lpComponentEnd = lpComponent;
298cdf0e10cSrcweir                 fValid = FALSE;
299cdf0e10cSrcweir                 break;
300cdf0e10cSrcweir             }
301cdf0e10cSrcweir         }
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir     */
304cdf0e10cSrcweir 
305cdf0e10cSrcweir     if ( fValid )
306cdf0e10cSrcweir     {
307cdf0e10cSrcweir         // Empty components are not allowed
308cdf0e10cSrcweir         if ( lpComponentEnd - lpComponent < 1 )
309cdf0e10cSrcweir             fValid = FALSE;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         // If we reached the end of the string NULL is returned
312cdf0e10cSrcweir         else if ( !*lpComponentEnd )
313cdf0e10cSrcweir             lpComponentEnd = NULL;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     if ( lppComponentEnd )
318cdf0e10cSrcweir         *lppComponentEnd = lpComponentEnd;
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     return fValid;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir //#####################################################
324cdf0e10cSrcweir DWORD WINAPI IsValidFilePath(LPCTSTR lpszPath, LPCTSTR *lppError, DWORD dwFlags)
325cdf0e10cSrcweir {
326cdf0e10cSrcweir     LPCTSTR lpComponent;
327cdf0e10cSrcweir     BOOL    fValid = TRUE;
328cdf0e10cSrcweir     DWORD   dwPathType = PATHTYPE_ERROR;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir     if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
331cdf0e10cSrcweir         dwFlags |= VALIDATEPATH_ALLOW_ELLIPSE;
332cdf0e10cSrcweir 
333cdf0e10cSrcweir     if ( !lpszPath )
334cdf0e10cSrcweir     {
335cdf0e10cSrcweir         fValid = FALSE;
336cdf0e10cSrcweir         lpComponent = lpszPath;
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     /* Test for UNC path notation */
340cdf0e10cSrcweir     if ( 2 == _tcsspn( lpszPath, CHARSET_SEPARATOR ) )
341cdf0e10cSrcweir     {
342cdf0e10cSrcweir         /* Place the pointer behind the leading to backslashes */
343cdf0e10cSrcweir 
344cdf0e10cSrcweir         lpComponent = lpszPath + 2;
345cdf0e10cSrcweir 
346cdf0e10cSrcweir         fValid = IsValidFilePathComponent( lpComponent, &lpComponent, VALIDATEPATH_ALLOW_ELLIPSE );
347cdf0e10cSrcweir 
348cdf0e10cSrcweir         /* So far we have a valid servername. Now let's see if we also have a network resource */
349cdf0e10cSrcweir 
350cdf0e10cSrcweir         dwPathType = PATHTYPE_ABSOLUTE_UNC;
351cdf0e10cSrcweir 
352cdf0e10cSrcweir         if ( fValid )
353cdf0e10cSrcweir         {
354cdf0e10cSrcweir             if ( lpComponent &&  !*++lpComponent )
355cdf0e10cSrcweir                 lpComponent = NULL;
356cdf0e10cSrcweir 
357cdf0e10cSrcweir             if ( !lpComponent )
358cdf0e10cSrcweir             {
359cdf0e10cSrcweir #if 0
360cdf0e10cSrcweir                 /* We only have a Server specification what is invalid */
361cdf0e10cSrcweir 
362cdf0e10cSrcweir                 lpComponent = lpszPath;
363cdf0e10cSrcweir                 fValid = FALSE;
364cdf0e10cSrcweir #else
365cdf0e10cSrcweir                 dwPathType |= PATHTYPE_IS_SERVER;
366cdf0e10cSrcweir #endif
367cdf0e10cSrcweir             }
368cdf0e10cSrcweir             else
369cdf0e10cSrcweir             {
370cdf0e10cSrcweir                 /* Now test the network resource */
371cdf0e10cSrcweir 
372cdf0e10cSrcweir                 fValid = IsValidFilePathComponent( lpComponent, &lpComponent, 0 );
373cdf0e10cSrcweir 
374cdf0e10cSrcweir                 /* If we now reached the end of the path, everything is O.K. */
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 
377cdf0e10cSrcweir                 if ( fValid && (!lpComponent || lpComponent && !*++lpComponent ) )
378cdf0e10cSrcweir                 {
379cdf0e10cSrcweir                     lpComponent = NULL;
380cdf0e10cSrcweir                     dwPathType |= PATHTYPE_IS_VOLUME;
381cdf0e10cSrcweir                 }
382cdf0e10cSrcweir             }
383cdf0e10cSrcweir         }
384cdf0e10cSrcweir     }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     /* Local path verification. Must start with <drive>: */
387cdf0e10cSrcweir     else if ( _istalpha( lpszPath[0] ) && ':' == lpszPath[1] )
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         /* Place pointer behind correct drive specification */
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         lpComponent = lpszPath + 2;
392cdf0e10cSrcweir 
393cdf0e10cSrcweir         if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
394cdf0e10cSrcweir             lpComponent++;
395cdf0e10cSrcweir         else if ( *lpComponent )
396cdf0e10cSrcweir             fValid = FALSE;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir         dwPathType = PATHTYPE_ABSOLUTE_LOCAL;
399cdf0e10cSrcweir 
400cdf0e10cSrcweir         /* Now we are behind the backslash or it was a simple drive without backslash */
401cdf0e10cSrcweir 
402cdf0e10cSrcweir         if ( fValid && !*lpComponent )
403cdf0e10cSrcweir         {
404cdf0e10cSrcweir             lpComponent = NULL;
405cdf0e10cSrcweir             dwPathType |= PATHTYPE_IS_VOLUME;
406cdf0e10cSrcweir         }
407cdf0e10cSrcweir     }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     /* Can be a relative path */
410cdf0e10cSrcweir     else if ( dwFlags & VALIDATEPATH_ALLOW_RELATIVE )
411cdf0e10cSrcweir     {
412cdf0e10cSrcweir         lpComponent = lpszPath;
413cdf0e10cSrcweir 
414cdf0e10cSrcweir         /* Relative path can start with a backslash */
415cdf0e10cSrcweir 
416cdf0e10cSrcweir         if ( 1 == _tcsspn( lpComponent, CHARSET_SEPARATOR ) )
417cdf0e10cSrcweir         {
418cdf0e10cSrcweir             lpComponent++;
419cdf0e10cSrcweir             if ( !*lpComponent )
420cdf0e10cSrcweir                 lpComponent = NULL;
421cdf0e10cSrcweir         }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir         dwPathType = PATHTYPE_RELATIVE;
424cdf0e10cSrcweir     }
425cdf0e10cSrcweir 
426cdf0e10cSrcweir     /* Anything else is an error */
427cdf0e10cSrcweir     else
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         fValid = FALSE;
430cdf0e10cSrcweir         lpComponent = lpszPath;
431cdf0e10cSrcweir     }
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     /* Now validate each component of the path */
434cdf0e10cSrcweir     while ( fValid && lpComponent )
435cdf0e10cSrcweir     {
436cdf0e10cSrcweir         fValid = IsValidFilePathComponent( lpComponent, &lpComponent, dwFlags );
437cdf0e10cSrcweir 
438cdf0e10cSrcweir         if ( fValid && lpComponent )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             lpComponent++;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir             /* If the string behind the backslash is empty, we've done */
443cdf0e10cSrcweir 
444cdf0e10cSrcweir             if ( !*lpComponent )
445cdf0e10cSrcweir                 lpComponent = NULL;
446cdf0e10cSrcweir         }
447cdf0e10cSrcweir     }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     if ( fValid && _tcslen( lpszPath ) >= _MAX_PATH )
450cdf0e10cSrcweir     {
451cdf0e10cSrcweir         fValid = FALSE;
452cdf0e10cSrcweir         lpComponent = lpszPath + _MAX_PATH;
453cdf0e10cSrcweir     }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir     if ( lppError )
456cdf0e10cSrcweir         *lppError = lpComponent;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir     return fValid ? dwPathType : PATHTYPE_ERROR;
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
461cdf0e10cSrcweir sal_Bool _osl_decodeURL( rtl_String* strUTF8, rtl_uString** pstrDecodedURL )
462cdf0e10cSrcweir {
463cdf0e10cSrcweir     sal_Char        *pBuffer;
464cdf0e10cSrcweir     const sal_Char  *pSrcEnd;
465cdf0e10cSrcweir     const sal_Char  *pSrc;
466cdf0e10cSrcweir     sal_Char        *pDest;
467cdf0e10cSrcweir     sal_Int32       nSrcLen;
468cdf0e10cSrcweir     sal_Bool        bValidEncoded = sal_True;   /* Assume success */
469cdf0e10cSrcweir 
470cdf0e10cSrcweir     /* The resulting decoded string length is shorter or equal to the source length */
471cdf0e10cSrcweir 
472cdf0e10cSrcweir     nSrcLen = rtl_string_getLength(strUTF8);
473cdf0e10cSrcweir     pBuffer = reinterpret_cast<sal_Char*>(rtl_allocateMemory(nSrcLen + 1));
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     pDest = pBuffer;
476cdf0e10cSrcweir     pSrc = rtl_string_getStr(strUTF8);
477cdf0e10cSrcweir     pSrcEnd = pSrc + nSrcLen;
478cdf0e10cSrcweir 
479cdf0e10cSrcweir     /* Now decode the URL what should result in an UTF8 string */
480cdf0e10cSrcweir     while ( bValidEncoded && pSrc < pSrcEnd )
481cdf0e10cSrcweir     {
482cdf0e10cSrcweir         switch ( *pSrc )
483cdf0e10cSrcweir         {
484cdf0e10cSrcweir         case '%':
485cdf0e10cSrcweir             {
486cdf0e10cSrcweir                 sal_Char    aToken[3];
487cdf0e10cSrcweir                 sal_Char    aChar;
488cdf0e10cSrcweir 
489cdf0e10cSrcweir                 pSrc++;
490cdf0e10cSrcweir                 aToken[0] = *pSrc++;
491cdf0e10cSrcweir                 aToken[1] = *pSrc++;
492cdf0e10cSrcweir                 aToken[2] = 0;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir                 aChar = (sal_Char)strtoul( aToken, NULL, 16 );
495cdf0e10cSrcweir 
496cdf0e10cSrcweir                 /* The chars are path delimiters and must not be encoded */
497cdf0e10cSrcweir 
498cdf0e10cSrcweir                 if ( 0 == aChar || '\\' == aChar || '/' == aChar || ':' == aChar )
499cdf0e10cSrcweir                     bValidEncoded = sal_False;
500cdf0e10cSrcweir                 else
501cdf0e10cSrcweir                     *pDest++ = aChar;
502cdf0e10cSrcweir             }
503cdf0e10cSrcweir             break;
504cdf0e10cSrcweir         default:
505cdf0e10cSrcweir             *pDest++ = *pSrc++;
506cdf0e10cSrcweir             break;
507cdf0e10cSrcweir         }
508cdf0e10cSrcweir     }
509cdf0e10cSrcweir 
510cdf0e10cSrcweir     *pDest++ = 0;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir     if ( bValidEncoded ) {
513cdf0e10cSrcweir         rtl_string2UString( pstrDecodedURL, pBuffer, rtl_str_getLength(pBuffer), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
514cdf0e10cSrcweir         OSL_ASSERT(*pstrDecodedURL != 0);
515cdf0e10cSrcweir     }
516cdf0e10cSrcweir 
517cdf0e10cSrcweir     rtl_freeMemory( pBuffer );
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     return bValidEncoded;
520cdf0e10cSrcweir }
521cdf0e10cSrcweir 
522cdf0e10cSrcweir //#############################################
523cdf0e10cSrcweir void _osl_encodeURL( rtl_uString *strURL, rtl_String **pstrEncodedURL )
524cdf0e10cSrcweir {
525cdf0e10cSrcweir     /* Encode non ascii characters within the URL */
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     rtl_String      *strUTF8 = NULL;
528cdf0e10cSrcweir     sal_Char        *pszEncodedURL;
529cdf0e10cSrcweir     const sal_Char  *pURLScan;
530cdf0e10cSrcweir     sal_Char        *pURLDest;
531cdf0e10cSrcweir     sal_Int32       nURLScanLen;
532cdf0e10cSrcweir     sal_Int32       nURLScanCount;
533cdf0e10cSrcweir 
534cdf0e10cSrcweir     rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
535cdf0e10cSrcweir 
536cdf0e10cSrcweir     pszEncodedURL = (sal_Char*) rtl_allocateMemory( (rtl_string_getLength( strUTF8 ) * 3 + 1)  * sizeof(sal_Char) );
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     pURLDest = pszEncodedURL;
539cdf0e10cSrcweir     pURLScan = rtl_string_getStr( strUTF8 );
540cdf0e10cSrcweir     nURLScanLen = rtl_string_getLength( strUTF8 );
541cdf0e10cSrcweir     nURLScanCount = 0;
542cdf0e10cSrcweir 
543cdf0e10cSrcweir     while ( nURLScanCount < nURLScanLen )
544cdf0e10cSrcweir     {
545cdf0e10cSrcweir         sal_Char    cCurrent = *pURLScan;
546cdf0e10cSrcweir 
547cdf0e10cSrcweir         switch ( cCurrent )
548cdf0e10cSrcweir         {
549cdf0e10cSrcweir         default:
550cdf0e10cSrcweir             if (!( ( cCurrent >= 'a' && cCurrent <= 'z' ) || ( cCurrent >= 'A' && cCurrent <= 'Z' ) || ( cCurrent >= '0' && cCurrent <= '9' ) ) )
551cdf0e10cSrcweir             {
552cdf0e10cSrcweir                 sprintf( pURLDest, "%%%02X", (unsigned char)cCurrent );
553cdf0e10cSrcweir                 pURLDest += 3;
554cdf0e10cSrcweir                 break;
555cdf0e10cSrcweir             }
556cdf0e10cSrcweir         case '!':
557cdf0e10cSrcweir         case '\'':
558cdf0e10cSrcweir         case '(':
559cdf0e10cSrcweir         case ')':
560cdf0e10cSrcweir         case '*':
561cdf0e10cSrcweir         case '-':
562cdf0e10cSrcweir         case '.':
563cdf0e10cSrcweir         case '_':
564cdf0e10cSrcweir         case '~':
565cdf0e10cSrcweir         case '$':
566cdf0e10cSrcweir         case '&':
567cdf0e10cSrcweir         case '+':
568cdf0e10cSrcweir         case ',':
569cdf0e10cSrcweir         case '=':
570cdf0e10cSrcweir         case '@':
571cdf0e10cSrcweir         case ':':
572cdf0e10cSrcweir         case '/':
573cdf0e10cSrcweir         case '\\':
574cdf0e10cSrcweir         case '|':
575cdf0e10cSrcweir             *pURLDest++ = cCurrent;
576cdf0e10cSrcweir             break;
577cdf0e10cSrcweir         case 0:
578cdf0e10cSrcweir             break;
579cdf0e10cSrcweir         }
580cdf0e10cSrcweir 
581cdf0e10cSrcweir         pURLScan++;
582cdf0e10cSrcweir         nURLScanCount++;
583cdf0e10cSrcweir     }
584cdf0e10cSrcweir 
585cdf0e10cSrcweir 
586cdf0e10cSrcweir     *pURLDest = 0;
587cdf0e10cSrcweir 
588cdf0e10cSrcweir     rtl_string_release( strUTF8 );
589cdf0e10cSrcweir     rtl_string_newFromStr( pstrEncodedURL, pszEncodedURL );
590cdf0e10cSrcweir     rtl_freeMemory( pszEncodedURL );
591cdf0e10cSrcweir }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir //#############################################
594cdf0e10cSrcweir oslFileError SAL_CALL _osl_getFileURLFromSystemPath( rtl_uString* strPath, rtl_uString** pstrURL )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir     oslFileError nError = osl_File_E_INVAL; /* Assume failure */
597cdf0e10cSrcweir     rtl_uString *strTempURL = NULL;
598cdf0e10cSrcweir     DWORD dwPathType = PATHTYPE_ERROR;
599cdf0e10cSrcweir 
600cdf0e10cSrcweir     if (strPath)
601cdf0e10cSrcweir         dwPathType = IsValidFilePath(strPath->buffer, NULL, VALIDATEPATH_ALLOW_RELATIVE);
602cdf0e10cSrcweir 
603cdf0e10cSrcweir     if (dwPathType)
604cdf0e10cSrcweir     {
605cdf0e10cSrcweir         rtl_uString *strTempPath = NULL;
606cdf0e10cSrcweir 
607cdf0e10cSrcweir         /* Replace backslashes */
608cdf0e10cSrcweir 
609cdf0e10cSrcweir         rtl_uString_newReplace( &strTempPath, strPath, '\\', '/' );
610cdf0e10cSrcweir 
611cdf0e10cSrcweir         switch ( dwPathType & PATHTYPE_MASK_TYPE )
612cdf0e10cSrcweir         {
613cdf0e10cSrcweir         case PATHTYPE_RELATIVE:
614cdf0e10cSrcweir             rtl_uString_assign( &strTempURL, strTempPath );
615cdf0e10cSrcweir             nError = osl_File_E_None;
616cdf0e10cSrcweir             break;
617cdf0e10cSrcweir         case PATHTYPE_ABSOLUTE_UNC:
618cdf0e10cSrcweir             rtl_uString_newFromAscii( &strTempURL, "file:" );
619cdf0e10cSrcweir             rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
620cdf0e10cSrcweir             nError = osl_File_E_None;
621cdf0e10cSrcweir             break;
622cdf0e10cSrcweir         case PATHTYPE_ABSOLUTE_LOCAL:
623cdf0e10cSrcweir             rtl_uString_newFromAscii( &strTempURL, "file:///" );
624cdf0e10cSrcweir             rtl_uString_newConcat( &strTempURL, strTempURL, strTempPath );
625cdf0e10cSrcweir             nError = osl_File_E_None;
626cdf0e10cSrcweir             break;
627cdf0e10cSrcweir         default:
628cdf0e10cSrcweir             break;
629cdf0e10cSrcweir         }
630cdf0e10cSrcweir 
631cdf0e10cSrcweir         /* Release temp path */
632cdf0e10cSrcweir 
633cdf0e10cSrcweir         rtl_uString_release( strTempPath );
634cdf0e10cSrcweir     }
635cdf0e10cSrcweir 
636cdf0e10cSrcweir     if ( osl_File_E_None == nError )
637cdf0e10cSrcweir     {
638cdf0e10cSrcweir         rtl_String  *strEncodedURL = NULL;
639cdf0e10cSrcweir 
640cdf0e10cSrcweir         /* Encode the URL */
641cdf0e10cSrcweir 
642cdf0e10cSrcweir         _osl_encodeURL( strTempURL, &strEncodedURL );
643cdf0e10cSrcweir 
644cdf0e10cSrcweir         /* Provide URL via unicode string */
645cdf0e10cSrcweir 
646cdf0e10cSrcweir         rtl_string2UString( pstrURL, rtl_string_getStr(strEncodedURL), rtl_string_getLength(strEncodedURL), RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
647cdf0e10cSrcweir         OSL_ASSERT(*pstrURL != 0);
648cdf0e10cSrcweir         rtl_string_release( strEncodedURL );
649cdf0e10cSrcweir     }
650cdf0e10cSrcweir 
651cdf0e10cSrcweir     /* Release temp URL */
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     if ( strTempURL )
654cdf0e10cSrcweir         rtl_uString_release( strTempURL );
655cdf0e10cSrcweir 
656cdf0e10cSrcweir     /*
657cdf0e10cSrcweir     OSL_ENSURE_FILE( !nError, "osl_getFileURLFromSystemPath: \"%s\" is not a systemPath !!!", strPath );
658cdf0e10cSrcweir     */
659cdf0e10cSrcweir 
660cdf0e10cSrcweir     return nError;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir 
663cdf0e10cSrcweir oslFileError SAL_CALL osl_getFileURLFromSystemPath( rtl_uString *ustrSystemPath, rtl_uString **pustrFileURL )
664cdf0e10cSrcweir {
665cdf0e10cSrcweir     return _osl_getFileURLFromSystemPath( ustrSystemPath, pustrFileURL );
666cdf0e10cSrcweir #if 0
667cdf0e10cSrcweir     static const sal_Unicode pDoubleSlash[2] = { '/', '/' };
668cdf0e10cSrcweir 
669cdf0e10cSrcweir     rtl_uString *pTmp = NULL;
670cdf0e10cSrcweir     sal_Int32 nIndex;
671cdf0e10cSrcweir 
672cdf0e10cSrcweir     if( 0 == ustrSystemPath->length )
673cdf0e10cSrcweir         return osl_File_E_INVAL;
674cdf0e10cSrcweir 
675cdf0e10cSrcweir     /* YD convert '\' to '/' */
676cdf0e10cSrcweir     rtl_ustr_replaceChar( ustrSystemPath->buffer, '\\', '/' );
677cdf0e10cSrcweir 
678cdf0e10cSrcweir     /* temporary hack: if already file url, return ustrSystemPath */
679cdf0e10cSrcweir     if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file:", 5 ) )
680cdf0e10cSrcweir     {
681cdf0e10cSrcweir     /*
682cdf0e10cSrcweir         if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file://", 7 ) )
683cdf0e10cSrcweir         {
684cdf0e10cSrcweir             OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is already file URL" );
685cdf0e10cSrcweir             rtl_uString_assign( pustrFileURL, ustrSystemPath );
686cdf0e10cSrcweir         }
687cdf0e10cSrcweir         else
688cdf0e10cSrcweir         {
689cdf0e10cSrcweir             rtl_uString *pTmp2 = NULL;
690cdf0e10cSrcweir 
691cdf0e10cSrcweir             OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is wrong file URL" );
692cdf0e10cSrcweir             rtl_uString_newFromStr_WithLength( pustrFileURL, ustrSystemPath->buffer + 5, ustrSystemPath->length - 5 );
693cdf0e10cSrcweir             rtl_uString_newFromAscii( &pTmp2, "file://" );
694cdf0e10cSrcweir             rtl_uString_newConcat( pustrFileURL, *pustrFileURL, pTmp2 );
695cdf0e10cSrcweir             rtl_uString_release( pTmp2 );
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir         return osl_File_E_None;
698cdf0e10cSrcweir         */
699cdf0e10cSrcweir         return osl_File_E_INVAL;
700cdf0e10cSrcweir     }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 
703cdf0e10cSrcweir     /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
704cdf0e10cSrcweir     if( (sal_Unicode) '~' == ustrSystemPath->buffer[0] )
705cdf0e10cSrcweir     {
706cdf0e10cSrcweir         /* check if another user is specified */
707cdf0e10cSrcweir         if( ( 1 == ustrSystemPath->length ) || ( (sal_Unicode)'/' == ustrSystemPath->buffer[1] ) )
708cdf0e10cSrcweir         {
709cdf0e10cSrcweir             /* osl_getHomeDir returns file URL */
710cdf0e10cSrcweir             osl_getHomeDir( osl_getCurrentSecurity(), &pTmp );
711cdf0e10cSrcweir 
712cdf0e10cSrcweir             /* remove "file://" prefix */
713cdf0e10cSrcweir             rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + 7, pTmp->length - 7 );
714cdf0e10cSrcweir 
715cdf0e10cSrcweir             /* replace '~' in original string */
716cdf0e10cSrcweir             rtl_uString_newReplaceStrAt( &pTmp, ustrSystemPath, 0, 1, pTmp );
717cdf0e10cSrcweir         }
718cdf0e10cSrcweir 
719cdf0e10cSrcweir         else
720cdf0e10cSrcweir         {
721cdf0e10cSrcweir             /* FIXME: replace ~user with users home directory */
722cdf0e10cSrcweir             return osl_File_E_INVAL;
723cdf0e10cSrcweir         }
724cdf0e10cSrcweir     }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir     /* check if initial string contains double instances of '/' */
727cdf0e10cSrcweir     nIndex = rtl_ustr_indexOfStr_WithLength( ustrSystemPath->buffer, ustrSystemPath->length, pDoubleSlash, 2 );
728cdf0e10cSrcweir     if( -1 != nIndex )
729cdf0e10cSrcweir     {
730cdf0e10cSrcweir         sal_Int32 nSrcIndex;
731cdf0e10cSrcweir         sal_Int32 nDeleted = 0;
732cdf0e10cSrcweir 
733cdf0e10cSrcweir         /* if pTmp is not already allocated, copy ustrSystemPath for modification */
734cdf0e10cSrcweir         if( NULL == pTmp )
735cdf0e10cSrcweir             rtl_uString_newFromString( &pTmp, ustrSystemPath );
736cdf0e10cSrcweir 
737cdf0e10cSrcweir         /* adapt index to pTmp */
738cdf0e10cSrcweir         nIndex += pTmp->length - ustrSystemPath->length;
739cdf0e10cSrcweir 
740cdf0e10cSrcweir         /* remove all occurances of '//' */
741cdf0e10cSrcweir         for( nSrcIndex = nIndex + 1; nSrcIndex < pTmp->length; nSrcIndex++ )
742cdf0e10cSrcweir         {
743cdf0e10cSrcweir             if( ((sal_Unicode) '/' == pTmp->buffer[nSrcIndex]) && ((sal_Unicode) '/' == pTmp->buffer[nIndex]) )
744cdf0e10cSrcweir                 nDeleted++;
745cdf0e10cSrcweir             else
746cdf0e10cSrcweir                 pTmp->buffer[++nIndex] = pTmp->buffer[nSrcIndex];
747cdf0e10cSrcweir         }
748cdf0e10cSrcweir 
749cdf0e10cSrcweir         /* adjust length member */
750cdf0e10cSrcweir         pTmp->length -= nDeleted;
751cdf0e10cSrcweir     }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir     if( NULL == pTmp )
754cdf0e10cSrcweir         rtl_uString_assign( &pTmp, ustrSystemPath );
755cdf0e10cSrcweir 
756cdf0e10cSrcweir     /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
757cdf0e10cSrcweir     /*
758cdf0e10cSrcweir     OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
759cdf0e10cSrcweir     */
760cdf0e10cSrcweir 
761cdf0e10cSrcweir     /* file URLs must be URI encoded */
762cdf0e10cSrcweir     rtl_uriEncode( pTmp, uriCharClass, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8, pustrFileURL );
763cdf0e10cSrcweir 
764cdf0e10cSrcweir     rtl_uString_release( pTmp );
765cdf0e10cSrcweir 
766cdf0e10cSrcweir     /* absolute urls should start with 'file://' */
767cdf0e10cSrcweir     if( (sal_Unicode)'/' == (*pustrFileURL)->buffer[0] )
768cdf0e10cSrcweir     {
769cdf0e10cSrcweir         rtl_uString *pProtocol = NULL;
770cdf0e10cSrcweir 
771cdf0e10cSrcweir         rtl_uString_newFromAscii( &pProtocol, "file://" );
772cdf0e10cSrcweir         rtl_uString_newConcat( pustrFileURL, pProtocol, *pustrFileURL );
773cdf0e10cSrcweir         rtl_uString_release( pProtocol );
774cdf0e10cSrcweir     }
775cdf0e10cSrcweir 
776cdf0e10cSrcweir     return osl_File_E_None;
777cdf0e10cSrcweir #endif
778cdf0e10cSrcweir }
779cdf0e10cSrcweir 
780cdf0e10cSrcweir //#############################################
781cdf0e10cSrcweir oslFileError SAL_CALL _osl_getSystemPathFromFileURL( rtl_uString *strURL, rtl_uString **pustrPath, sal_Bool bAllowRelative )
782cdf0e10cSrcweir {
783cdf0e10cSrcweir     rtl_String          *strUTF8 = NULL;
784cdf0e10cSrcweir     rtl_uString         *strDecodedURL = NULL;
785cdf0e10cSrcweir     rtl_uString         *strTempPath = NULL;
786cdf0e10cSrcweir     const sal_Unicode   *pDecodedURL;
787cdf0e10cSrcweir     sal_uInt32          nDecodedLen;
788cdf0e10cSrcweir     sal_Bool            bValidEncoded;
789cdf0e10cSrcweir     oslFileError        nError = osl_File_E_INVAL;  /* Assume failure */
790cdf0e10cSrcweir 
791cdf0e10cSrcweir     /*  If someone hasn't encoded the complete URL we convert it to UTF8 now to prevent from
792cdf0e10cSrcweir         having a mixed encoded URL later */
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     rtl_uString2String( &strUTF8, rtl_uString_getStr( strURL ), rtl_uString_getLength( strURL ), RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS );
795cdf0e10cSrcweir 
796cdf0e10cSrcweir     /* If the length of strUTF8 and strURL differs it indicates that the URL was not correct encoded */
797cdf0e10cSrcweir 
798cdf0e10cSrcweir     OSL_ENSURE_FILE(
799cdf0e10cSrcweir         strUTF8->length == strURL->length ||
800cdf0e10cSrcweir         0 != rtl_ustr_ascii_shortenedCompare_WithLength( strURL->buffer, strURL->length, "file:\\\\", 7 )
801cdf0e10cSrcweir         ,"osl_getSystemPathFromFileURL: \"%s\" is not encoded !!!", strURL );
802cdf0e10cSrcweir 
803cdf0e10cSrcweir     bValidEncoded = _osl_decodeURL( strUTF8, &strDecodedURL );
804cdf0e10cSrcweir 
805cdf0e10cSrcweir     /* Release the encoded UTF8 string */
806cdf0e10cSrcweir 
807cdf0e10cSrcweir     rtl_string_release( strUTF8 );
808cdf0e10cSrcweir 
809cdf0e10cSrcweir 
810cdf0e10cSrcweir     if ( bValidEncoded )
811cdf0e10cSrcweir     {
812cdf0e10cSrcweir         /* Replace backslashes and pipes */
813cdf0e10cSrcweir 
814cdf0e10cSrcweir         rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '/', '\\' );
815cdf0e10cSrcweir         rtl_uString_newReplace( &strDecodedURL, strDecodedURL, '|', ':' );
816cdf0e10cSrcweir 
817cdf0e10cSrcweir         pDecodedURL = rtl_uString_getStr( strDecodedURL );
818cdf0e10cSrcweir         nDecodedLen = rtl_uString_getLength( strDecodedURL );
819cdf0e10cSrcweir 
820cdf0e10cSrcweir         /* Must start with "file://" */
821cdf0e10cSrcweir 
822cdf0e10cSrcweir         if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL, nDecodedLen, "file:\\\\", 7 ) )
823cdf0e10cSrcweir         {
824cdf0e10cSrcweir             sal_uInt32  nSkip;
825cdf0e10cSrcweir 
826cdf0e10cSrcweir             if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL, nDecodedLen, "file:\\\\\\", 8 ) )
827cdf0e10cSrcweir                 nSkip = 8;
828cdf0e10cSrcweir             else if (
829cdf0e10cSrcweir                 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL, nDecodedLen, "file:\\\\localhost\\", 17 ) ||
830cdf0e10cSrcweir                 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pDecodedURL, nDecodedLen, "file:\\\\127.0.0.1\\", 17 )
831cdf0e10cSrcweir             )
832cdf0e10cSrcweir                 nSkip = 17;
833cdf0e10cSrcweir             else
834cdf0e10cSrcweir                 nSkip = 5;
835cdf0e10cSrcweir 
836cdf0e10cSrcweir             /* Indicates local root */
837cdf0e10cSrcweir             if ( nDecodedLen == nSkip )
838cdf0e10cSrcweir                 rtl_uString_newFromStr_WithLength( &strTempPath, (const sal_Unicode*)WSTR_SYSTEM_ROOT_PATH, ELEMENTS_OF_ARRAY(WSTR_SYSTEM_ROOT_PATH) - 1 );
839cdf0e10cSrcweir             else
840cdf0e10cSrcweir                 rtl_uString_newFromStr_WithLength( &strTempPath, pDecodedURL + nSkip, nDecodedLen - nSkip );
841cdf0e10cSrcweir 
842cdf0e10cSrcweir             if ( IsValidFilePath( strTempPath->buffer, NULL, VALIDATEPATH_ALLOW_ELLIPSE ) )
843cdf0e10cSrcweir                 nError = osl_File_E_None;
844cdf0e10cSrcweir         }
845cdf0e10cSrcweir         else if ( bAllowRelative )  /* This maybe a relative file URL */
846cdf0e10cSrcweir         {
847cdf0e10cSrcweir             rtl_uString_assign( &strTempPath, strDecodedURL );
848cdf0e10cSrcweir 
849cdf0e10cSrcweir             if ( IsValidFilePath( strTempPath->buffer, NULL, VALIDATEPATH_ALLOW_RELATIVE | VALIDATEPATH_ALLOW_ELLIPSE ) )
850cdf0e10cSrcweir                 nError = osl_File_E_None;
851cdf0e10cSrcweir         }
852cdf0e10cSrcweir     /*
853cdf0e10cSrcweir         else
854cdf0e10cSrcweir             OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not an absolute FileURL !!!", strURL );
855cdf0e10cSrcweir      */
856cdf0e10cSrcweir 
857cdf0e10cSrcweir     }
858cdf0e10cSrcweir 
859cdf0e10cSrcweir     if ( strDecodedURL )
860cdf0e10cSrcweir         rtl_uString_release( strDecodedURL );
861cdf0e10cSrcweir 
862cdf0e10cSrcweir     if ( osl_File_E_None == nError )
863cdf0e10cSrcweir         rtl_uString_assign( pustrPath, strTempPath );
864cdf0e10cSrcweir 
865cdf0e10cSrcweir     if ( strTempPath )
866cdf0e10cSrcweir         rtl_uString_release( strTempPath );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir     /*
869cdf0e10cSrcweir     OSL_ENSURE_FILE( !nError, "osl_getSystemPathFromFileURL: \"%s\" is not a FileURL !!!", strURL );
870cdf0e10cSrcweir     */
871cdf0e10cSrcweir 
872cdf0e10cSrcweir     return nError;
873cdf0e10cSrcweir }
874cdf0e10cSrcweir 
875cdf0e10cSrcweir /****************************************************************************/
876cdf0e10cSrcweir /*  osl_getSystemPathFromFileURL */
877cdf0e10cSrcweir /****************************************************************************/
878cdf0e10cSrcweir 
879cdf0e10cSrcweir oslFileError SAL_CALL osl_getSystemPathFromFileURL( rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath )
880cdf0e10cSrcweir {
881cdf0e10cSrcweir     return _osl_getSystemPathFromFileURL( ustrFileURL, pustrSystemPath, sal_True );
882cdf0e10cSrcweir #if 0
883cdf0e10cSrcweir     sal_Int32 nIndex = 0;
884cdf0e10cSrcweir     rtl_uString * pTmp = NULL;
885cdf0e10cSrcweir 
886cdf0e10cSrcweir     sal_Unicode encodedSlash[3] = { '%', '2', 'F' };
887cdf0e10cSrcweir 
888cdf0e10cSrcweir     /* temporary hack: if already system path, return ustrFileURL */
889cdf0e10cSrcweir     /*
890cdf0e10cSrcweir     if( (sal_Unicode) '/' == ustrFileURL->buffer[0] )
891cdf0e10cSrcweir     {
892cdf0e10cSrcweir         OSL_ENSURE( 0, "osl_getSystemPathFromFileURL: input is already system path" );
893cdf0e10cSrcweir         rtl_uString_assign( pustrSystemPath, ustrFileURL );
894cdf0e10cSrcweir         return osl_File_E_None;
895cdf0e10cSrcweir     }
896cdf0e10cSrcweir     */
897cdf0e10cSrcweir 
898cdf0e10cSrcweir     /* a valid file url may not start with '/' */
899cdf0e10cSrcweir     if( ( 0 == ustrFileURL->length ) || ( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) )
900cdf0e10cSrcweir     {
901cdf0e10cSrcweir         return osl_File_E_INVAL;
902cdf0e10cSrcweir     }
903cdf0e10cSrcweir 
904cdf0e10cSrcweir     /* search for encoded slashes (%2F) and decode every single token if we find one */
905cdf0e10cSrcweir     if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, encodedSlash, 3 ) )
906cdf0e10cSrcweir     {
907cdf0e10cSrcweir         rtl_uString * ustrPathToken = NULL;
908cdf0e10cSrcweir         sal_Int32 nOffset = 7;
909cdf0e10cSrcweir 
910cdf0e10cSrcweir         do
911cdf0e10cSrcweir         {
912cdf0e10cSrcweir             nOffset += nIndex;
913cdf0e10cSrcweir 
914cdf0e10cSrcweir             /* break url down in '/' devided tokens tokens */
915cdf0e10cSrcweir             nIndex = rtl_ustr_indexOfChar_WithLength( ustrFileURL->buffer + nOffset, ustrFileURL->length - nOffset, (sal_Unicode) '/' );
916cdf0e10cSrcweir 
917cdf0e10cSrcweir             /* copy token to new string */
918cdf0e10cSrcweir             rtl_uString_newFromStr_WithLength( &ustrPathToken, ustrFileURL->buffer + nOffset,
919cdf0e10cSrcweir                 -1 == nIndex ? ustrFileURL->length - nOffset : nIndex++ );
920cdf0e10cSrcweir 
921cdf0e10cSrcweir             /* decode token */
922cdf0e10cSrcweir             rtl_uriDecode( ustrPathToken, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
923cdf0e10cSrcweir 
924cdf0e10cSrcweir             /* the result should not contain any '/' */
925cdf0e10cSrcweir             if( -1 != rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, (sal_Unicode) '/' ) )
926cdf0e10cSrcweir             {
927cdf0e10cSrcweir                 rtl_uString_release( pTmp );
928cdf0e10cSrcweir                 rtl_uString_release( ustrPathToken );
929cdf0e10cSrcweir 
930cdf0e10cSrcweir                 return osl_File_E_INVAL;
931cdf0e10cSrcweir             }
932cdf0e10cSrcweir 
933cdf0e10cSrcweir         } while( -1 != nIndex );
934cdf0e10cSrcweir 
935cdf0e10cSrcweir         /* release temporary string and restore index variable */
936cdf0e10cSrcweir         rtl_uString_release( ustrPathToken );
937cdf0e10cSrcweir         nIndex = 0;
938cdf0e10cSrcweir     }
939cdf0e10cSrcweir 
940cdf0e10cSrcweir     /* protocol and server should not be encoded, so decode the whole string */
941cdf0e10cSrcweir     rtl_uriDecode( ustrFileURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
942cdf0e10cSrcweir 
943cdf0e10cSrcweir     /* check if file protocol specified */
944cdf0e10cSrcweir     /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
945cdf0e10cSrcweir     if( 7 <= pTmp->length )
946cdf0e10cSrcweir     {
947cdf0e10cSrcweir         rtl_uString * pProtocol = NULL;
948cdf0e10cSrcweir         rtl_uString_newFromStr_WithLength( &pProtocol, pTmp->buffer, 7 );
949cdf0e10cSrcweir 
950cdf0e10cSrcweir         /* protocol is case insensitive */
951cdf0e10cSrcweir         rtl_ustr_toAsciiLowerCase_WithLength( pProtocol->buffer, pProtocol->length );
952cdf0e10cSrcweir 
953cdf0e10cSrcweir         if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pProtocol->buffer, pProtocol->length,"file://", 7 ) )
954cdf0e10cSrcweir             nIndex = 7;
955cdf0e10cSrcweir 
956cdf0e10cSrcweir         rtl_uString_release( pProtocol );
957cdf0e10cSrcweir     }
958cdf0e10cSrcweir 
959cdf0e10cSrcweir     /* skip "localhost" or "127.0.0.1" if "file://" is specified */
960cdf0e10cSrcweir     /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
961cdf0e10cSrcweir     if( nIndex && ( 10 <= pTmp->length - nIndex ) )
962cdf0e10cSrcweir     {
963cdf0e10cSrcweir         rtl_uString * pServer = NULL;
964cdf0e10cSrcweir         rtl_uString_newFromStr_WithLength( &pServer, pTmp->buffer + nIndex, 10 );
965cdf0e10cSrcweir 
966cdf0e10cSrcweir         /* server is case insensitive */
967cdf0e10cSrcweir         rtl_ustr_toAsciiLowerCase_WithLength( pServer->buffer, pServer->length );
968cdf0e10cSrcweir 
969cdf0e10cSrcweir         if( ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"localhost/", 10 ) ) ||
970cdf0e10cSrcweir             ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"127.0.0.1/", 10 ) ) )
971cdf0e10cSrcweir         {
972cdf0e10cSrcweir             /* don't exclude the '/' */
973cdf0e10cSrcweir             nIndex += 9;
974cdf0e10cSrcweir         }
975cdf0e10cSrcweir 
976cdf0e10cSrcweir         rtl_uString_release( pServer );
977cdf0e10cSrcweir     }
978cdf0e10cSrcweir 
979cdf0e10cSrcweir     if( nIndex )
980cdf0e10cSrcweir         rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + nIndex, pTmp->length - nIndex );
981cdf0e10cSrcweir 
982cdf0e10cSrcweir     /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
983cdf0e10cSrcweir     if( (sal_Unicode) '~' == pTmp->buffer[0] )
984cdf0e10cSrcweir     {
985cdf0e10cSrcweir         /* check if another user is specified */
986cdf0e10cSrcweir         if( ( 1 == pTmp->length ) || ( (sal_Unicode)'/' == pTmp->buffer[1] ) )
987cdf0e10cSrcweir         {
988cdf0e10cSrcweir             rtl_uString *pTmp2 = NULL;
989cdf0e10cSrcweir 
990cdf0e10cSrcweir             /* osl_getHomeDir returns file URL */
991cdf0e10cSrcweir             osl_getHomeDir( osl_getCurrentSecurity(), &pTmp2 );
992cdf0e10cSrcweir 
993cdf0e10cSrcweir             /* remove "file://" prefix */
994cdf0e10cSrcweir             rtl_uString_newFromStr_WithLength( &pTmp2, pTmp2->buffer + 7, pTmp2->length - 7 );
995cdf0e10cSrcweir 
996cdf0e10cSrcweir             /* replace '~' in original string */
997cdf0e10cSrcweir             rtl_uString_newReplaceStrAt( &pTmp, pTmp, 0, 1, pTmp2 );
998cdf0e10cSrcweir             rtl_uString_release( pTmp2 );
999cdf0e10cSrcweir         }
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir         else
1002cdf0e10cSrcweir         {
1003cdf0e10cSrcweir             /* FIXME: replace ~user with users home directory */
1004cdf0e10cSrcweir             return osl_File_E_INVAL;
1005cdf0e10cSrcweir         }
1006cdf0e10cSrcweir     }
1007cdf0e10cSrcweir 
1008cdf0e10cSrcweir     /* temporary check for top 5 wrong usage strings (which are valid but unlikly filenames) */
1009cdf0e10cSrcweir     /*
1010cdf0e10cSrcweir     OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
1011cdf0e10cSrcweir     */
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir     *pustrSystemPath = pTmp;
1014cdf0e10cSrcweir     return osl_File_E_None;
1015cdf0e10cSrcweir #endif // 0
1016cdf0e10cSrcweir }
1017cdf0e10cSrcweir 
1018cdf0e10cSrcweir 
1019cdf0e10cSrcweir /****************************************************************************
1020cdf0e10cSrcweir  * osl_getSystemPathFromFileURL_Ex - helper function
1021cdf0e10cSrcweir  * clients may specify if they want to accept relative
1022cdf0e10cSrcweir  * URLs or not
1023cdf0e10cSrcweir  ****************************************************************************/
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir oslFileError osl_getSystemPathFromFileURL_Ex(
1026cdf0e10cSrcweir     rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath, sal_Bool bAllowRelative)
1027cdf0e10cSrcweir {
1028cdf0e10cSrcweir     return _osl_getSystemPathFromFileURL( ustrFileURL, pustrSystemPath, bAllowRelative);
1029cdf0e10cSrcweir #if 0
1030cdf0e10cSrcweir     rtl_uString* temp = 0;
1031cdf0e10cSrcweir     oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &temp);
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir     if (osl_File_E_None == osl_error)
1034cdf0e10cSrcweir     {
1035cdf0e10cSrcweir         if (bAllowRelative
1036cdf0e10cSrcweir             || (UNICHAR_SLASH == temp->buffer[0])
1037cdf0e10cSrcweir             || (UNICHAR_COLON == temp->buffer[1] && UNICHAR_SLASH == temp->buffer[2]))
1038cdf0e10cSrcweir         {
1039cdf0e10cSrcweir             *pustrSystemPath = temp;
1040cdf0e10cSrcweir         }
1041cdf0e10cSrcweir         else
1042cdf0e10cSrcweir         {
1043cdf0e10cSrcweir             rtl_uString_release(temp);
1044cdf0e10cSrcweir             osl_error = osl_File_E_INVAL;
1045cdf0e10cSrcweir         }
1046cdf0e10cSrcweir     }
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir     return osl_error;
1049cdf0e10cSrcweir #endif
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir namespace /* private */
1053cdf0e10cSrcweir {
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir #if 0 // YD
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir     /******************************************************
1058cdf0e10cSrcweir      * Helper function, return a pinter to the final '\0'
1059cdf0e10cSrcweir      * of a string
1060cdf0e10cSrcweir      ******************************************************/
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir     sal_Unicode* ustrtoend(sal_Unicode* pStr)
1063cdf0e10cSrcweir     {
1064cdf0e10cSrcweir         return (pStr + rtl_ustr_getLength(pStr));
1065cdf0e10cSrcweir     }
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir     /*********************************************
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir      ********************************************/
1070cdf0e10cSrcweir     sal_Unicode* ustrcpy(const sal_Unicode* s, sal_Unicode* d)
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir         const sal_Unicode* sc = s;
1073cdf0e10cSrcweir         sal_Unicode*       dc = d;
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir         while ((*dc++ = *sc++))
1076cdf0e10cSrcweir             /**/;
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir         return d;
1079cdf0e10cSrcweir     }
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir     /*********************************************
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir      ********************************************/
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir     sal_Unicode* ustrncpy(const sal_Unicode* s, sal_Unicode* d, unsigned int n)
1086cdf0e10cSrcweir     {
1087cdf0e10cSrcweir         const sal_Unicode* sc = s;
1088cdf0e10cSrcweir         sal_Unicode*       dc = d;
1089cdf0e10cSrcweir         unsigned int       i  = n;
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir         while (i--)
1092cdf0e10cSrcweir             *dc++ = *sc++;
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir         if (n)
1095cdf0e10cSrcweir             *dc = 0;
1096cdf0e10cSrcweir 
1097cdf0e10cSrcweir         return d;
1098cdf0e10cSrcweir     }
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir     /*********************************************
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir      ********************************************/
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir     sal_Unicode* ustrchrcat(const sal_Unicode chr, sal_Unicode* d)
1105cdf0e10cSrcweir     {
1106cdf0e10cSrcweir         sal_Unicode* p = ustrtoend(d);
1107cdf0e10cSrcweir         *p++ = chr;
1108cdf0e10cSrcweir         *p   = 0;
1109cdf0e10cSrcweir         return d;
1110cdf0e10cSrcweir     }
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir     /*********************************************
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir      ********************************************/
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir     sal_Unicode* ustrcat(const sal_Unicode* s, sal_Unicode* d)
1117cdf0e10cSrcweir     {
1118cdf0e10cSrcweir         sal_Unicode* dc = ustrtoend(d);
1119cdf0e10cSrcweir         ustrcpy(s, dc);
1120cdf0e10cSrcweir         return d;
1121cdf0e10cSrcweir     }
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir     /******************************************************
1124cdf0e10cSrcweir      *
1125cdf0e10cSrcweir      ******************************************************/
1126cdf0e10cSrcweir 
1127cdf0e10cSrcweir     bool _islastchr(sal_Unicode* pStr, sal_Unicode Chr)
1128cdf0e10cSrcweir     {
1129cdf0e10cSrcweir         sal_Unicode* p = ustrtoend(pStr);
1130cdf0e10cSrcweir         if (p > pStr)
1131cdf0e10cSrcweir             p--;
1132cdf0e10cSrcweir         return (*p == Chr);
1133cdf0e10cSrcweir     }
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir     /******************************************************
1136cdf0e10cSrcweir      * Ensure that the given string has the specified last
1137cdf0e10cSrcweir      * character if necessary append it
1138cdf0e10cSrcweir      ******************************************************/
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir     sal_Unicode* _strensurelast(sal_Unicode* pStr, sal_Unicode Chr)
1141cdf0e10cSrcweir     {
1142cdf0e10cSrcweir         if (!_islastchr(pStr, Chr))
1143cdf0e10cSrcweir             ustrchrcat(Chr, pStr);
1144cdf0e10cSrcweir         return pStr;
1145cdf0e10cSrcweir     }
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir     /******************************************************
1148cdf0e10cSrcweir      * Remove the last part of a path, a path that has
1149cdf0e10cSrcweir      * only a '/' or no '/' at all will be returned
1150cdf0e10cSrcweir      * unmodified
1151cdf0e10cSrcweir      ******************************************************/
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir     sal_Unicode* _rmlastpathtoken(sal_Unicode* aPath)
1154cdf0e10cSrcweir     {
1155cdf0e10cSrcweir         /*  we always may skip -2 because we
1156cdf0e10cSrcweir             may at least stand on a '/' but
1157cdf0e10cSrcweir             either there is no other character
1158cdf0e10cSrcweir             before this '/' or it's another
1159cdf0e10cSrcweir             character than the '/'
1160cdf0e10cSrcweir         */
1161cdf0e10cSrcweir         sal_Unicode* p = ustrtoend(aPath) - 2;
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir         // move back to the next path separator
1164cdf0e10cSrcweir         // or to the start of the string
1165cdf0e10cSrcweir         while ((p > aPath) && (*p != UNICHAR_SLASH))
1166cdf0e10cSrcweir             p--;
1167cdf0e10cSrcweir 
1168cdf0e10cSrcweir         if (p >= aPath)
1169cdf0e10cSrcweir         {
1170cdf0e10cSrcweir             if (UNICHAR_SLASH == *p)
1171cdf0e10cSrcweir             {
1172cdf0e10cSrcweir                 p++;
1173cdf0e10cSrcweir                *p = '\0';
1174cdf0e10cSrcweir             }
1175cdf0e10cSrcweir             else
1176cdf0e10cSrcweir             {
1177cdf0e10cSrcweir                 *p = '\0';
1178cdf0e10cSrcweir             }
1179cdf0e10cSrcweir         }
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir         return aPath;
1182cdf0e10cSrcweir     }
1183cdf0e10cSrcweir 
1184cdf0e10cSrcweir     /******************************************************
1185cdf0e10cSrcweir      *
1186cdf0e10cSrcweir      ******************************************************/
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     oslFileError _osl_resolvepath(
1189cdf0e10cSrcweir         /*inout*/ sal_Unicode* path,
1190cdf0e10cSrcweir         /*inout*/ sal_Unicode* current_pos,
1191cdf0e10cSrcweir         /*in   */ sal_Unicode* sentinel,
1192cdf0e10cSrcweir         /*inout*/ bool* failed)
1193cdf0e10cSrcweir     {
1194cdf0e10cSrcweir         oslFileError ferr = osl_File_E_None;
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir         if (!*failed)
1197cdf0e10cSrcweir         {
1198cdf0e10cSrcweir             char unresolved_path[PATH_MAX];
1199cdf0e10cSrcweir             if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), path, rtl_ustr_getLength(path)))
1200cdf0e10cSrcweir                 return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir             char resolved_path[PATH_MAX];
1203cdf0e10cSrcweir             if (realpath(unresolved_path, resolved_path))
1204cdf0e10cSrcweir             {
1205cdf0e10cSrcweir                 if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX))
1206cdf0e10cSrcweir                     return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir                 current_pos = ustrtoend(path) - 1;
1209cdf0e10cSrcweir             }
1210cdf0e10cSrcweir             else
1211cdf0e10cSrcweir             {
1212cdf0e10cSrcweir                 if (EACCES == errno || ENOTDIR == errno || ENOENT == errno)
1213cdf0e10cSrcweir                     *failed = true;
1214cdf0e10cSrcweir                 else
1215cdf0e10cSrcweir                     ferr = oslTranslateFileError(OSL_FET_ERROR, errno);
1216cdf0e10cSrcweir             }
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir         return ferr;
1220cdf0e10cSrcweir     }
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir     /******************************************************
1223cdf0e10cSrcweir      * Works even with non existing paths. The resulting
1224cdf0e10cSrcweir      * path must not exceed PATH_MAX else
1225cdf0e10cSrcweir      * osl_File_E_NAMETOOLONG is the result
1226cdf0e10cSrcweir      ******************************************************/
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir     oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved_path, rtl::OUString& resolved_path)
1229cdf0e10cSrcweir     {
1230cdf0e10cSrcweir         // the given unresolved path must not exceed PATH_MAX
1231cdf0e10cSrcweir         if (unresolved_path.getLength() >= (PATH_MAX - 2))
1232cdf0e10cSrcweir             return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir         sal_Unicode        path_resolved_so_far[PATH_MAX];
1235cdf0e10cSrcweir         const sal_Unicode* punresolved = unresolved_path.getStr();
1236cdf0e10cSrcweir         sal_Unicode*       presolvedsf = path_resolved_so_far;
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir         // reserve space for leading '/' and trailing '\0'
1239cdf0e10cSrcweir         // do not exceed this limit
1240cdf0e10cSrcweir         sal_Unicode* sentinel = path_resolved_so_far + PATH_MAX - 2;
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir         // if realpath fails with error ENOTDIR, EACCES or ENOENT
1243cdf0e10cSrcweir         // we will not call it again, because _osl_realpath should also
1244cdf0e10cSrcweir         // work with non existing directories etc.
1245cdf0e10cSrcweir         bool realpath_failed = false;
1246cdf0e10cSrcweir         oslFileError ferr;
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir         path_resolved_so_far[0] = '\0';
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir         while (*punresolved != '\0')
1251cdf0e10cSrcweir         {
1252cdf0e10cSrcweir             // ignore '/.' , skip one part back when '/..'
1253cdf0e10cSrcweir 
1254cdf0e10cSrcweir             if ((UNICHAR_DOT == *punresolved) && (UNICHAR_SLASH == *presolvedsf))
1255cdf0e10cSrcweir             {
1256cdf0e10cSrcweir                 if ('\0' == *(punresolved + 1))
1257cdf0e10cSrcweir                 {
1258cdf0e10cSrcweir                     punresolved++;
1259cdf0e10cSrcweir                     continue;
1260cdf0e10cSrcweir                 }
1261cdf0e10cSrcweir                 else if (UNICHAR_SLASH == *(punresolved + 1))
1262cdf0e10cSrcweir                 {
1263cdf0e10cSrcweir                     punresolved += 2;
1264cdf0e10cSrcweir                     continue;
1265cdf0e10cSrcweir                 }
1266cdf0e10cSrcweir                 else if ((UNICHAR_DOT == *(punresolved + 1)) && ('\0' == *(punresolved + 2) || (UNICHAR_SLASH == *(punresolved + 2))))
1267cdf0e10cSrcweir                 {
1268cdf0e10cSrcweir                     _rmlastpathtoken(path_resolved_so_far);
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir                     presolvedsf = ustrtoend(path_resolved_so_far) - 1;
1271cdf0e10cSrcweir 
1272cdf0e10cSrcweir                     if (UNICHAR_SLASH == *(punresolved + 2))
1273cdf0e10cSrcweir                         punresolved += 3;
1274cdf0e10cSrcweir                     else
1275cdf0e10cSrcweir                         punresolved += 2;
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir                     continue;
1278cdf0e10cSrcweir                 }
1279cdf0e10cSrcweir                 else // a file or directory name may start with '.'
1280cdf0e10cSrcweir                 {
1281cdf0e10cSrcweir                     if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
1282cdf0e10cSrcweir                         return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1283cdf0e10cSrcweir 
1284cdf0e10cSrcweir                     ustrchrcat(*punresolved++, path_resolved_so_far);
1285cdf0e10cSrcweir 
1286cdf0e10cSrcweir                     if ('\0' == *punresolved && !realpath_failed)
1287cdf0e10cSrcweir                     {
1288cdf0e10cSrcweir                         ferr = _osl_resolvepath(
1289cdf0e10cSrcweir                             path_resolved_so_far,
1290cdf0e10cSrcweir                             presolvedsf,
1291cdf0e10cSrcweir                             sentinel,
1292cdf0e10cSrcweir                             &realpath_failed);
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir                         if (osl_File_E_None != ferr)
1295cdf0e10cSrcweir                             return ferr;
1296cdf0e10cSrcweir                     }
1297cdf0e10cSrcweir                 }
1298cdf0e10cSrcweir             }
1299cdf0e10cSrcweir             else if (UNICHAR_SLASH == *punresolved)
1300cdf0e10cSrcweir             {
1301cdf0e10cSrcweir                 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
1302cdf0e10cSrcweir                     return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir                 ustrchrcat(*punresolved++, path_resolved_so_far);
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir                 if (!realpath_failed)
1307cdf0e10cSrcweir                 {
1308cdf0e10cSrcweir                     ferr = _osl_resolvepath(
1309cdf0e10cSrcweir                         path_resolved_so_far,
1310cdf0e10cSrcweir                         presolvedsf,
1311cdf0e10cSrcweir                         sentinel,
1312cdf0e10cSrcweir                         &realpath_failed);
1313cdf0e10cSrcweir 
1314cdf0e10cSrcweir                     if (osl_File_E_None != ferr)
1315cdf0e10cSrcweir                         return ferr;
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir                     if (!_islastchr(path_resolved_so_far, UNICHAR_SLASH))
1318cdf0e10cSrcweir                     {
1319cdf0e10cSrcweir                         if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
1320cdf0e10cSrcweir                             return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1321cdf0e10cSrcweir 
1322cdf0e10cSrcweir                         ustrchrcat(UNICHAR_SLASH, path_resolved_so_far);
1323cdf0e10cSrcweir                     }
1324cdf0e10cSrcweir                 }
1325cdf0e10cSrcweir             }
1326cdf0e10cSrcweir             else // any other character
1327cdf0e10cSrcweir             {
1328cdf0e10cSrcweir                 if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
1329cdf0e10cSrcweir                     return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir                 ustrchrcat(*punresolved++, path_resolved_so_far);
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir                 if ('\0' == *punresolved && !realpath_failed)
1334cdf0e10cSrcweir                 {
1335cdf0e10cSrcweir                     ferr = _osl_resolvepath(
1336cdf0e10cSrcweir                         path_resolved_so_far,
1337cdf0e10cSrcweir                         presolvedsf,
1338cdf0e10cSrcweir                         sentinel,
1339cdf0e10cSrcweir                         &realpath_failed);
1340cdf0e10cSrcweir 
1341cdf0e10cSrcweir                     if (osl_File_E_None != ferr)
1342cdf0e10cSrcweir                         return ferr;
1343cdf0e10cSrcweir                 }
1344cdf0e10cSrcweir             }
1345cdf0e10cSrcweir         }
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir         sal_Int32 len = rtl_ustr_getLength(path_resolved_so_far);
1348cdf0e10cSrcweir 
1349cdf0e10cSrcweir         OSL_ASSERT(len < PATH_MAX);
1350cdf0e10cSrcweir 
1351cdf0e10cSrcweir         resolved_path = rtl::OUString(path_resolved_so_far, len);
1352cdf0e10cSrcweir 
1353cdf0e10cSrcweir         return osl_File_E_None;
1354cdf0e10cSrcweir     }
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir #endif // 0 // YD
1357cdf0e10cSrcweir 
1358cdf0e10cSrcweir } // end namespace private
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
1361cdf0e10cSrcweir 
1362cdf0e10cSrcweir     //#####################################################
1363cdf0e10cSrcweir     void _osl_warnFile( const char *message, rtl_uString *ustrFile )
1364cdf0e10cSrcweir     {
1365cdf0e10cSrcweir         char szBuffer[2048];
1366cdf0e10cSrcweir 
1367cdf0e10cSrcweir         if (ustrFile)
1368cdf0e10cSrcweir         {
1369cdf0e10cSrcweir             rtl_String  *strFile = NULL;
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir             rtl_uString2String( &strFile, rtl_uString_getStr( ustrFile ), rtl_uString_getLength( ustrFile ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
1372cdf0e10cSrcweir             snprintf( szBuffer, sizeof(szBuffer), message, strFile->buffer );
1373cdf0e10cSrcweir             rtl_string_release( strFile );
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir             message = szBuffer;
1376cdf0e10cSrcweir         }
1377cdf0e10cSrcweir         OSL_ENSURE( 0, message );
1378cdf0e10cSrcweir     }
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir #endif // OSL_DEBUG_LEVEL > 0
1381cdf0e10cSrcweir 
1382cdf0e10cSrcweir /******************************************************
1383cdf0e10cSrcweir  * osl_getAbsoluteFileURL
1384cdf0e10cSrcweir  ******************************************************/
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir //oslFileError osl_getAbsoluteFileURL(rtl_uString*  ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
1387cdf0e10cSrcweir oslFileError SAL_CALL osl_getAbsoluteFileURL( rtl_uString* ustrBaseURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL )
1388cdf0e10cSrcweir {
1389cdf0e10cSrcweir     oslFileError    eError;
1390cdf0e10cSrcweir     rtl_uString     *ustrRelSysPath = NULL;
1391cdf0e10cSrcweir     rtl_uString     *ustrBaseSysPath = NULL;
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir     if ( ustrBaseURL && ustrBaseURL->length )
1394cdf0e10cSrcweir     {
1395cdf0e10cSrcweir         eError = _osl_getSystemPathFromFileURL( ustrBaseURL, &ustrBaseSysPath, sal_False );
1396cdf0e10cSrcweir         OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with relative or invalid base URL" );
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir         eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_True );
1399cdf0e10cSrcweir     }
1400cdf0e10cSrcweir     else
1401cdf0e10cSrcweir     {
1402cdf0e10cSrcweir         eError = _osl_getSystemPathFromFileURL( ustrRelativeURL, &ustrRelSysPath, sal_False );
1403cdf0e10cSrcweir         OSL_ENSURE( osl_File_E_None == eError, "osl_getAbsoluteFileURL called with empty base URL and/or invalid relative URL" );
1404cdf0e10cSrcweir     }
1405cdf0e10cSrcweir 
1406cdf0e10cSrcweir     if ( !eError )
1407cdf0e10cSrcweir     {
1408cdf0e10cSrcweir         CHAR    szBuffer[_MAX_PATH];
1409cdf0e10cSrcweir         CHAR    szRelSysPath[_MAX_PATH];
1410cdf0e10cSrcweir         CHAR    szCurrentDir[_MAX_PATH];
1411cdf0e10cSrcweir         int     result;
1412cdf0e10cSrcweir         char*   cwd;
1413cdf0e10cSrcweir         int     rc;
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir /*@@@ToDo
1416cdf0e10cSrcweir   Bad, bad hack, this only works if the base path
1417cdf0e10cSrcweir   really exists which is not necessary according
1418cdf0e10cSrcweir   to RFC2396
1419cdf0e10cSrcweir   The whole FileURL implementation should be merged
1420cdf0e10cSrcweir   with the rtl/uri class.
1421cdf0e10cSrcweir */
1422cdf0e10cSrcweir         if ( ustrBaseSysPath )
1423cdf0e10cSrcweir         {
1424cdf0e10cSrcweir             CHAR    szBaseSysPath[_MAX_PATH];
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir             if (!g_CurrentDirectoryMutex)
1427cdf0e10cSrcweir                 g_CurrentDirectoryMutex = osl_createMutex();
1428cdf0e10cSrcweir 
1429cdf0e10cSrcweir             osl_acquireMutex( g_CurrentDirectoryMutex );
1430cdf0e10cSrcweir 
1431cdf0e10cSrcweir             cwd = getcwd( szCurrentDir, sizeof(szCurrentDir) );
1432cdf0e10cSrcweir             UnicodeToText( szBaseSysPath, sizeof(szBaseSysPath), ustrBaseSysPath->buffer, ustrBaseSysPath->length);
1433cdf0e10cSrcweir             rc = chdir( szBaseSysPath);
1434cdf0e10cSrcweir         }
1435cdf0e10cSrcweir 
1436cdf0e10cSrcweir         UnicodeToText( szRelSysPath, sizeof(szRelSysPath), ustrRelSysPath->buffer, ustrRelSysPath->length);
1437cdf0e10cSrcweir         result = !_abspath( szBuffer, szRelSysPath, sizeof(szBuffer));
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir         if ( ustrBaseSysPath )
1440cdf0e10cSrcweir         {
1441cdf0e10cSrcweir             rc = chdir( szCurrentDir );
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir             osl_releaseMutex( g_CurrentDirectoryMutex );
1444cdf0e10cSrcweir         }
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir         if ( result )
1447cdf0e10cSrcweir         {
1448cdf0e10cSrcweir                 rtl_uString *ustrAbsSysPath = NULL;
1449cdf0e10cSrcweir 
1450cdf0e10cSrcweir                 oslMakeUStrFromPsz( szBuffer, &ustrAbsSysPath);
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir                 eError = osl_getFileURLFromSystemPath( ustrAbsSysPath, pustrAbsoluteURL );
1453cdf0e10cSrcweir 
1454cdf0e10cSrcweir                 if ( ustrAbsSysPath )
1455cdf0e10cSrcweir                     rtl_uString_release( ustrAbsSysPath );
1456cdf0e10cSrcweir         }
1457cdf0e10cSrcweir         else
1458cdf0e10cSrcweir             eError = osl_File_E_INVAL;
1459cdf0e10cSrcweir     }
1460cdf0e10cSrcweir 
1461cdf0e10cSrcweir     if ( ustrBaseSysPath )
1462cdf0e10cSrcweir         rtl_uString_release( ustrBaseSysPath );
1463cdf0e10cSrcweir 
1464cdf0e10cSrcweir     if ( ustrRelSysPath )
1465cdf0e10cSrcweir         rtl_uString_release( ustrRelSysPath );
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir     return  eError;
1468cdf0e10cSrcweir #if 0
1469cdf0e10cSrcweir     FileBase::RC  rc;
1470cdf0e10cSrcweir     rtl::OUString unresolved_path;
1471cdf0e10cSrcweir 
1472cdf0e10cSrcweir     rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrRelativeURL), unresolved_path);
1473cdf0e10cSrcweir 
1474cdf0e10cSrcweir     if(FileBase::E_None != rc)
1475cdf0e10cSrcweir         return oslFileError(rc);
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir     if (systemPathIsRelativePath(unresolved_path))
1478cdf0e10cSrcweir     {
1479cdf0e10cSrcweir         rtl::OUString base_path;
1480cdf0e10cSrcweir         rc = (FileBase::RC) osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL, &base_path.pData, sal_False);
1481cdf0e10cSrcweir 
1482cdf0e10cSrcweir         if (FileBase::E_None != rc)
1483cdf0e10cSrcweir             return oslFileError(rc);
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir         rtl::OUString abs_path;
1486cdf0e10cSrcweir         systemPathMakeAbsolutePath(base_path, unresolved_path, abs_path);
1487cdf0e10cSrcweir 
1488cdf0e10cSrcweir         unresolved_path = abs_path;
1489cdf0e10cSrcweir     }
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir     rtl::OUString resolved_path;
1492cdf0e10cSrcweir     rc = (FileBase::RC) osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir     if (FileBase::E_None == rc)
1495cdf0e10cSrcweir     {
1496cdf0e10cSrcweir         rc = (FileBase::RC) osl_getFileURLFromSystemPath(resolved_path.pData, pustrAbsoluteURL);
1497cdf0e10cSrcweir         OSL_ASSERT(FileBase::E_None == rc);
1498cdf0e10cSrcweir     }
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir     return oslFileError(rc);
1501cdf0e10cSrcweir #endif // 0
1502cdf0e10cSrcweir }
1503cdf0e10cSrcweir 
1504cdf0e10cSrcweir 
1505cdf0e10cSrcweir namespace /* private */
1506cdf0e10cSrcweir {
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir     /*********************************************
1509cdf0e10cSrcweir      No separate error code if unicode to text
1510cdf0e10cSrcweir      conversion or getenv fails because for the
1511cdf0e10cSrcweir      caller there is no difference why a file
1512cdf0e10cSrcweir      could not be found in $PATH
1513cdf0e10cSrcweir      ********************************************/
1514cdf0e10cSrcweir 
1515cdf0e10cSrcweir     bool find_in_PATH(const rtl::OUString& file_path, rtl::OUString& result)
1516cdf0e10cSrcweir     {
1517cdf0e10cSrcweir         bool          bfound = false;
1518cdf0e10cSrcweir         rtl::OUString path   = rtl::OUString::createFromAscii("PATH");
1519cdf0e10cSrcweir         rtl::OUString env_path;
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir         if (osl_Process_E_None == osl_getEnvironment(path.pData, &env_path.pData))
1522cdf0e10cSrcweir             bfound = osl::searchPath(file_path, env_path, result);
1523cdf0e10cSrcweir 
1524cdf0e10cSrcweir         return bfound;
1525cdf0e10cSrcweir     }
1526cdf0e10cSrcweir 
1527cdf0e10cSrcweir     /*********************************************
1528cdf0e10cSrcweir      No separate error code if unicode to text
1529cdf0e10cSrcweir      conversion or getcwd fails because for the
1530cdf0e10cSrcweir      caller there is no difference why a file
1531cdf0e10cSrcweir      could not be found in CDW
1532cdf0e10cSrcweir      ********************************************/
1533cdf0e10cSrcweir 
1534cdf0e10cSrcweir     bool find_in_CWD(const rtl::OUString& file_path, rtl::OUString& result)
1535cdf0e10cSrcweir     {
1536cdf0e10cSrcweir         bool bfound = false;
1537cdf0e10cSrcweir         rtl::OUString cwd_url;
1538cdf0e10cSrcweir 
1539cdf0e10cSrcweir         if (osl_Process_E_None == osl_getProcessWorkingDir(&cwd_url.pData))
1540cdf0e10cSrcweir         {
1541cdf0e10cSrcweir             rtl::OUString cwd;
1542cdf0e10cSrcweir             FileBase::getSystemPathFromFileURL(cwd_url, cwd);
1543cdf0e10cSrcweir             bfound = osl::searchPath(file_path, cwd, result);
1544cdf0e10cSrcweir         }
1545cdf0e10cSrcweir         return bfound;
1546cdf0e10cSrcweir     }
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir     /*********************************************
1549cdf0e10cSrcweir 
1550cdf0e10cSrcweir      ********************************************/
1551cdf0e10cSrcweir 
1552cdf0e10cSrcweir     bool find_in_searchPath(const rtl::OUString& file_path, rtl_uString* search_path, rtl::OUString& result)
1553cdf0e10cSrcweir     {
1554cdf0e10cSrcweir         return (search_path && osl::searchPath(file_path, rtl::OUString(search_path), result));
1555cdf0e10cSrcweir     }
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir } // end namespace private
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir 
1560cdf0e10cSrcweir /****************************************************************************
1561cdf0e10cSrcweir  *  osl_searchFileURL
1562cdf0e10cSrcweir  ***************************************************************************/
1563cdf0e10cSrcweir 
1564cdf0e10cSrcweir oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL)
1565cdf0e10cSrcweir {
1566cdf0e10cSrcweir     OSL_PRECOND(ustrFilePath && pustrURL, "osl_searchFileURL: invalid parameter");
1567cdf0e10cSrcweir 
1568cdf0e10cSrcweir     FileBase::RC  rc;
1569cdf0e10cSrcweir     rtl::OUString file_path;
1570cdf0e10cSrcweir 
1571cdf0e10cSrcweir     // try to interpret search path as file url else assume it's a system path list
1572cdf0e10cSrcweir     rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrFilePath), file_path);
1573cdf0e10cSrcweir     if ((FileBase::E_None != rc) && (FileBase::E_INVAL == rc))
1574cdf0e10cSrcweir         file_path = ustrFilePath;
1575cdf0e10cSrcweir     else if (FileBase::E_None != rc)
1576cdf0e10cSrcweir         return oslFileError(rc);
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir     bool          bfound = false;
1579cdf0e10cSrcweir     rtl::OUString result;
1580cdf0e10cSrcweir 
1581cdf0e10cSrcweir     if (find_in_searchPath(file_path, ustrSearchPath, result) ||
1582cdf0e10cSrcweir         find_in_PATH(file_path, result) ||
1583cdf0e10cSrcweir         find_in_CWD(file_path, result))
1584cdf0e10cSrcweir     {
1585cdf0e10cSrcweir         rtl::OUString resolved;
1586cdf0e10cSrcweir 
1587cdf0e10cSrcweir         if (osl::realpath(result, resolved))
1588cdf0e10cSrcweir         {
1589cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
1590cdf0e10cSrcweir             oslFileError osl_error =
1591cdf0e10cSrcweir #endif
1592cdf0e10cSrcweir                 osl_getFileURLFromSystemPath(resolved.pData, pustrURL);
1593cdf0e10cSrcweir             OSL_ASSERT(osl_File_E_None == osl_error);
1594cdf0e10cSrcweir             bfound = true;
1595cdf0e10cSrcweir         }
1596cdf0e10cSrcweir     }
1597cdf0e10cSrcweir     return bfound ? osl_File_E_None : osl_File_E_NOENT;
1598cdf0e10cSrcweir }
1599cdf0e10cSrcweir 
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir /****************************************************************************
1602cdf0e10cSrcweir  * FileURLToPath
1603cdf0e10cSrcweir  ***************************************************************************/
1604cdf0e10cSrcweir 
1605cdf0e10cSrcweir oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL)
1606cdf0e10cSrcweir {
1607cdf0e10cSrcweir     rtl_uString* ustrSystemPath = NULL;
1608cdf0e10cSrcweir     oslFileError osl_error      = osl_getSystemPathFromFileURL(ustrFileURL, &ustrSystemPath);
1609cdf0e10cSrcweir 
1610cdf0e10cSrcweir     if(osl_File_E_None != osl_error)
1611cdf0e10cSrcweir         return osl_error;
1612cdf0e10cSrcweir 
1613cdf0e10cSrcweir     osl_systemPathRemoveSeparator(ustrSystemPath);
1614cdf0e10cSrcweir 
1615cdf0e10cSrcweir     /* convert unicode path to text */
1616cdf0e10cSrcweir     if(!UnicodeToText( buffer, bufLen, ustrSystemPath->buffer, ustrSystemPath->length))
1617cdf0e10cSrcweir         osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
1618cdf0e10cSrcweir 
1619cdf0e10cSrcweir     rtl_uString_release(ustrSystemPath);
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir     return osl_error;
1622cdf0e10cSrcweir }
1623