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