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