xref: /AOO41X/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