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