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
10cdf0e10cSrcweir *
1187d2adbcSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
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.
19cdf0e10cSrcweir *
2087d2adbcSAndrew Rist *************************************************************/
2187d2adbcSAndrew Rist
2287d2adbcSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "file_url.h"
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include "system.h"
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <limits.h>
32cdf0e10cSrcweir #include <errno.h>
33cdf0e10cSrcweir #include <strings.h>
34cdf0e10cSrcweir #include <unistd.h>
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include "osl/file.hxx"
37cdf0e10cSrcweir #include <osl/security.h>
38cdf0e10cSrcweir #include <osl/diagnose.h>
39cdf0e10cSrcweir #include <osl/thread.h>
40cdf0e10cSrcweir #include <osl/process.h>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #include <rtl/uri.h>
43cdf0e10cSrcweir #include <rtl/ustring.hxx>
44cdf0e10cSrcweir #include <rtl/ustrbuf.h>
45cdf0e10cSrcweir #include "rtl/textcvt.h"
46cdf0e10cSrcweir
47cdf0e10cSrcweir #include "file_error_transl.h"
48cdf0e10cSrcweir #include "file_path_helper.hxx"
49cdf0e10cSrcweir
50cdf0e10cSrcweir #include "uunxapi.hxx"
51cdf0e10cSrcweir
52cdf0e10cSrcweir /***************************************************
53cdf0e10cSrcweir
54cdf0e10cSrcweir General note
55cdf0e10cSrcweir
56cdf0e10cSrcweir This file contains the part that handles File URLs.
57cdf0e10cSrcweir
58cdf0e10cSrcweir File URLs as scheme specific notion of URIs
59*0170220dSmseidel (RFC2396) may be handled platform independent, but
60cdf0e10cSrcweir will not in osl which is considered wrong.
61cdf0e10cSrcweir Future version of osl should handle File URLs this
62cdf0e10cSrcweir way. In rtl/uri there is already an URI parser etc.
63cdf0e10cSrcweir so this code should be consolidated.
64cdf0e10cSrcweir
65cdf0e10cSrcweir **************************************************/
66cdf0e10cSrcweir /************************************************************************
67cdf0e10cSrcweir * ToDo
68cdf0e10cSrcweir *
69cdf0e10cSrcweir * Fix osl_getCanonicalName
70cdf0e10cSrcweir ***********************************************************************/
71cdf0e10cSrcweir
72cdf0e10cSrcweir
73cdf0e10cSrcweir /***************************************************
74cdf0e10cSrcweir * namespace directives
75cdf0e10cSrcweir **************************************************/
76cdf0e10cSrcweir
77cdf0e10cSrcweir using namespace osl;
78cdf0e10cSrcweir
79cdf0e10cSrcweir /***************************************************
80cdf0e10cSrcweir * constants
81cdf0e10cSrcweir **************************************************/
82cdf0e10cSrcweir
83cdf0e10cSrcweir const sal_Unicode UNICHAR_SLASH = ((sal_Unicode)'/');
84cdf0e10cSrcweir const sal_Unicode UNICHAR_COLON = ((sal_Unicode)':');
85cdf0e10cSrcweir const sal_Unicode UNICHAR_DOT = ((sal_Unicode)'.');
86cdf0e10cSrcweir
87cdf0e10cSrcweir /******************************************************************************
88cdf0e10cSrcweir * Exported Module Functions
89cdf0e10cSrcweir *****************************************************************************/
90cdf0e10cSrcweir
91cdf0e10cSrcweir /* a slightly modified version of Pchar in rtl/source/uri.c */
92cdf0e10cSrcweir const sal_Bool uriCharClass[128] =
93cdf0e10cSrcweir {
94cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Pchar but without encoding slashes */
95cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
96cdf0e10cSrcweir 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* !"#$%&'()*+,-./ */
97cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, /* 0123456789:;<=>? */
98cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ABCDEFGHIJKLMNO */
99cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* PQRSTUVWXYZ[\]^_ */
100cdf0e10cSrcweir 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* `abcdefghijklmno */
101cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /* pqrstuvwxyz{|}~ */
102cdf0e10cSrcweir };
103cdf0e10cSrcweir
104cdf0e10cSrcweir
105cdf0e10cSrcweir /* check for top wrong usage strings */
106cdf0e10cSrcweir /*
107cdf0e10cSrcweir static sal_Bool findWrongUsage( const sal_Unicode *path, sal_Int32 len )
108cdf0e10cSrcweir {
109cdf0e10cSrcweir rtl_uString *pTmp = NULL;
110cdf0e10cSrcweir sal_Bool bRet;
111cdf0e10cSrcweir
112cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pTmp, path, len );
113cdf0e10cSrcweir
114cdf0e10cSrcweir rtl_ustr_toAsciiLowerCase_WithLength( pTmp->buffer, pTmp->length );
115cdf0e10cSrcweir
116cdf0e10cSrcweir bRet = ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "ftp://", 6 ) ) ||
117cdf0e10cSrcweir ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "http://", 7 ) ) ||
118cdf0e10cSrcweir ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "vnd.sun.star", 12 ) ) ||
119cdf0e10cSrcweir ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "private:", 8 ) ) ||
120cdf0e10cSrcweir ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pTmp->buffer, pTmp->length, "slot:", 5) );
121cdf0e10cSrcweir
122cdf0e10cSrcweir rtl_uString_release( pTmp );
123cdf0e10cSrcweir return bRet;
124cdf0e10cSrcweir }
125cdf0e10cSrcweir */
126cdf0e10cSrcweir
127cdf0e10cSrcweir /****************************************************************************/
128cdf0e10cSrcweir /* osl_getCanonicalName */
129cdf0e10cSrcweir /****************************************************************************/
130cdf0e10cSrcweir
osl_getCanonicalName(rtl_uString * ustrFileURL,rtl_uString ** pustrValidURL)131cdf0e10cSrcweir oslFileError SAL_CALL osl_getCanonicalName( rtl_uString* ustrFileURL, rtl_uString** pustrValidURL )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir OSL_ENSURE(0, "osl_getCanonicalName not implemented");
134cdf0e10cSrcweir
135cdf0e10cSrcweir rtl_uString_newFromString(pustrValidURL, ustrFileURL);
136cdf0e10cSrcweir return osl_File_E_None;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
139cdf0e10cSrcweir /****************************************************************************/
140cdf0e10cSrcweir /* osl_getSystemPathFromFileURL */
141cdf0e10cSrcweir /****************************************************************************/
142cdf0e10cSrcweir
osl_getSystemPathFromFileURL(rtl_uString * ustrFileURL,rtl_uString ** pustrSystemPath)143cdf0e10cSrcweir oslFileError SAL_CALL osl_getSystemPathFromFileURL( rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir sal_Int32 nIndex;
146cdf0e10cSrcweir rtl_uString * pTmp = NULL;
147cdf0e10cSrcweir
148cdf0e10cSrcweir sal_Unicode encodedSlash[3] = { '%', '2', 'F' };
149cdf0e10cSrcweir sal_Unicode protocolDelimiter[3] = { ':', '/', '/' };
150cdf0e10cSrcweir
151cdf0e10cSrcweir /* temporary hack: if already system path, return ustrFileURL */
152cdf0e10cSrcweir /*
153cdf0e10cSrcweir if( (sal_Unicode) '/' == ustrFileURL->buffer[0] )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir OSL_ENSURE( 0, "osl_getSystemPathFromFileURL: input is already system path" );
156cdf0e10cSrcweir rtl_uString_assign( pustrSystemPath, ustrFileURL );
157cdf0e10cSrcweir return osl_File_E_None;
158cdf0e10cSrcweir }
159cdf0e10cSrcweir */
160cdf0e10cSrcweir
161cdf0e10cSrcweir /* a valid file url may not start with '/' */
162cdf0e10cSrcweir if( ( 0 == ustrFileURL->length ) || ( (sal_Unicode) '/' == ustrFileURL->buffer[0] ) )
163cdf0e10cSrcweir {
164cdf0e10cSrcweir return osl_File_E_INVAL;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir /* Check for non file:// protocols */
168cdf0e10cSrcweir
169cdf0e10cSrcweir nIndex = rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, protocolDelimiter, 3 );
170cdf0e10cSrcweir if ( -1 != nIndex && (4 != nIndex || 0 != rtl_ustr_ascii_shortenedCompare_WithLength( ustrFileURL->buffer, ustrFileURL->length,"file", 4 ) ) )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir return osl_File_E_INVAL;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
175cdf0e10cSrcweir /* search for encoded slashes (%2F) and decode every single token if we find one */
176cdf0e10cSrcweir
177cdf0e10cSrcweir nIndex = 0;
178cdf0e10cSrcweir
179cdf0e10cSrcweir if( -1 != rtl_ustr_indexOfStr_WithLength( ustrFileURL->buffer, ustrFileURL->length, encodedSlash, 3 ) )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir rtl_uString * ustrPathToken = NULL;
182cdf0e10cSrcweir sal_Int32 nOffset = 7;
183cdf0e10cSrcweir
184cdf0e10cSrcweir do
185cdf0e10cSrcweir {
186cdf0e10cSrcweir nOffset += nIndex;
187cdf0e10cSrcweir
18886e1cf34SPedro Giffuni /* break url down in '/' divided tokens tokens */
189cdf0e10cSrcweir nIndex = rtl_ustr_indexOfChar_WithLength( ustrFileURL->buffer + nOffset, ustrFileURL->length - nOffset, (sal_Unicode) '/' );
190cdf0e10cSrcweir
191cdf0e10cSrcweir /* copy token to new string */
192cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &ustrPathToken, ustrFileURL->buffer + nOffset,
193cdf0e10cSrcweir -1 == nIndex ? ustrFileURL->length - nOffset : nIndex++ );
194cdf0e10cSrcweir
195cdf0e10cSrcweir /* decode token */
196cdf0e10cSrcweir rtl_uriDecode( ustrPathToken, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
197cdf0e10cSrcweir
198cdf0e10cSrcweir /* the result should not contain any '/' */
199cdf0e10cSrcweir if( -1 != rtl_ustr_indexOfChar_WithLength( pTmp->buffer, pTmp->length, (sal_Unicode) '/' ) )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir rtl_uString_release( pTmp );
202cdf0e10cSrcweir rtl_uString_release( ustrPathToken );
203cdf0e10cSrcweir
204cdf0e10cSrcweir return osl_File_E_INVAL;
205cdf0e10cSrcweir }
206cdf0e10cSrcweir
207cdf0e10cSrcweir } while( -1 != nIndex );
208cdf0e10cSrcweir
209cdf0e10cSrcweir /* release temporary string and restore index variable */
210cdf0e10cSrcweir rtl_uString_release( ustrPathToken );
211cdf0e10cSrcweir nIndex = 0;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
214cdf0e10cSrcweir /* protocol and server should not be encoded, so decode the whole string */
215cdf0e10cSrcweir rtl_uriDecode( ustrFileURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8, &pTmp );
216cdf0e10cSrcweir
217cdf0e10cSrcweir /* check if file protocol specified */
218cdf0e10cSrcweir /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
219cdf0e10cSrcweir if( 7 <= pTmp->length )
220cdf0e10cSrcweir {
221cdf0e10cSrcweir rtl_uString * pProtocol = NULL;
222cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pProtocol, pTmp->buffer, 7 );
223cdf0e10cSrcweir
224cdf0e10cSrcweir /* protocol is case insensitive */
225cdf0e10cSrcweir rtl_ustr_toAsciiLowerCase_WithLength( pProtocol->buffer, pProtocol->length );
226cdf0e10cSrcweir
227cdf0e10cSrcweir if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pProtocol->buffer, pProtocol->length,"file://", 7 ) )
228cdf0e10cSrcweir nIndex = 7;
229cdf0e10cSrcweir
230cdf0e10cSrcweir rtl_uString_release( pProtocol );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir /* skip "localhost" or "127.0.0.1" if "file://" is specified */
234cdf0e10cSrcweir /* FIXME: use rtl_ustr_ascii_shortenedCompareIgnoreCase_WithLength when available */
235cdf0e10cSrcweir if( nIndex && ( 10 <= pTmp->length - nIndex ) )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir rtl_uString * pServer = NULL;
238cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pServer, pTmp->buffer + nIndex, 10 );
239cdf0e10cSrcweir
240cdf0e10cSrcweir /* server is case insensitive */
241cdf0e10cSrcweir rtl_ustr_toAsciiLowerCase_WithLength( pServer->buffer, pServer->length );
242cdf0e10cSrcweir
243cdf0e10cSrcweir if( ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"localhost/", 10 ) ) ||
244cdf0e10cSrcweir ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( pServer->buffer, pServer->length,"127.0.0.1/", 10 ) ) )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir /* don't exclude the '/' */
247cdf0e10cSrcweir nIndex += 9;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir
250cdf0e10cSrcweir rtl_uString_release( pServer );
251cdf0e10cSrcweir }
252cdf0e10cSrcweir
253cdf0e10cSrcweir if( nIndex )
254cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + nIndex, pTmp->length - nIndex );
255cdf0e10cSrcweir
256cdf0e10cSrcweir /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
257cdf0e10cSrcweir if( (sal_Unicode) '~' == pTmp->buffer[0] )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir /* check if another user is specified */
260cdf0e10cSrcweir if( ( 1 == pTmp->length ) || ( (sal_Unicode)'/' == pTmp->buffer[1] ) )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir rtl_uString *pTmp2 = NULL;
2639717b33aSPedro Giffuni oslSecurity pSecTemp;
264cdf0e10cSrcweir
265cdf0e10cSrcweir /* osl_getHomeDir returns file URL */
2669717b33aSPedro Giffuni osl_getHomeDir( pSecTemp = osl_getCurrentSecurity(), &pTmp2 );
2679717b33aSPedro Giffuni osl_freeSecurityHandle( pSecTemp );
268cdf0e10cSrcweir
269cdf0e10cSrcweir /* remove "file://" prefix */
270cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pTmp2, pTmp2->buffer + 7, pTmp2->length - 7 );
271cdf0e10cSrcweir
272cdf0e10cSrcweir /* replace '~' in original string */
273cdf0e10cSrcweir rtl_uString_newReplaceStrAt( &pTmp, pTmp, 0, 1, pTmp2 );
274cdf0e10cSrcweir rtl_uString_release( pTmp2 );
275cdf0e10cSrcweir }
276cdf0e10cSrcweir
277cdf0e10cSrcweir else
278cdf0e10cSrcweir {
279cdf0e10cSrcweir /* FIXME: replace ~user with users home directory */
280cdf0e10cSrcweir return osl_File_E_INVAL;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir }
283cdf0e10cSrcweir
284*0170220dSmseidel /* temporary check for top 5 wrong usage strings (which are valid but unlikely filenames) */
285cdf0e10cSrcweir /*
286cdf0e10cSrcweir OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
287cdf0e10cSrcweir */
288cdf0e10cSrcweir
289cdf0e10cSrcweir *pustrSystemPath = pTmp;
290cdf0e10cSrcweir return osl_File_E_None;
291cdf0e10cSrcweir }
292cdf0e10cSrcweir
293cdf0e10cSrcweir /****************************************************************************/
294cdf0e10cSrcweir /* osl_getFileURLFromSystemPath */
295cdf0e10cSrcweir /****************************************************************************/
296cdf0e10cSrcweir
osl_getFileURLFromSystemPath(rtl_uString * ustrSystemPath,rtl_uString ** pustrFileURL)297cdf0e10cSrcweir oslFileError SAL_CALL osl_getFileURLFromSystemPath( rtl_uString *ustrSystemPath, rtl_uString **pustrFileURL )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir static const sal_Unicode pDoubleSlash[2] = { '/', '/' };
300cdf0e10cSrcweir
301cdf0e10cSrcweir rtl_uString *pTmp = NULL;
302cdf0e10cSrcweir sal_Int32 nIndex;
303cdf0e10cSrcweir
304cdf0e10cSrcweir if( 0 == ustrSystemPath->length )
305cdf0e10cSrcweir return osl_File_E_INVAL;
306cdf0e10cSrcweir
307cdf0e10cSrcweir /* temporary hack: if already file url, return ustrSystemPath */
308cdf0e10cSrcweir
309cdf0e10cSrcweir if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file:", 5 ) )
310cdf0e10cSrcweir {
311cdf0e10cSrcweir /*
312cdf0e10cSrcweir if( 0 == rtl_ustr_ascii_shortenedCompare_WithLength( ustrSystemPath->buffer, ustrSystemPath->length,"file://", 7 ) )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is already file URL" );
315cdf0e10cSrcweir rtl_uString_assign( pustrFileURL, ustrSystemPath );
316cdf0e10cSrcweir }
317cdf0e10cSrcweir else
318cdf0e10cSrcweir {
319cdf0e10cSrcweir rtl_uString *pTmp2 = NULL;
320cdf0e10cSrcweir
321cdf0e10cSrcweir OSL_ENSURE( 0, "osl_getFileURLFromSystemPath: input is wrong file URL" );
322cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( pustrFileURL, ustrSystemPath->buffer + 5, ustrSystemPath->length - 5 );
323cdf0e10cSrcweir rtl_uString_newFromAscii( &pTmp2, "file://" );
324cdf0e10cSrcweir rtl_uString_newConcat( pustrFileURL, *pustrFileURL, pTmp2 );
325cdf0e10cSrcweir rtl_uString_release( pTmp2 );
326cdf0e10cSrcweir }
327cdf0e10cSrcweir return osl_File_E_None;
328cdf0e10cSrcweir */
329cdf0e10cSrcweir return osl_File_E_INVAL;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir
332cdf0e10cSrcweir
333cdf0e10cSrcweir /* check if system path starts with ~ or ~user and replace it with the appropriate home dir */
334cdf0e10cSrcweir if( (sal_Unicode) '~' == ustrSystemPath->buffer[0] )
335cdf0e10cSrcweir {
336cdf0e10cSrcweir /* check if another user is specified */
337cdf0e10cSrcweir if( ( 1 == ustrSystemPath->length ) || ( (sal_Unicode)'/' == ustrSystemPath->buffer[1] ) )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir /* osl_getHomeDir returns file URL */
340cdf0e10cSrcweir osl_getHomeDir( osl_getCurrentSecurity(), &pTmp );
341cdf0e10cSrcweir
342cdf0e10cSrcweir /* remove "file://" prefix */
343cdf0e10cSrcweir rtl_uString_newFromStr_WithLength( &pTmp, pTmp->buffer + 7, pTmp->length - 7 );
344cdf0e10cSrcweir
345cdf0e10cSrcweir /* replace '~' in original string */
346cdf0e10cSrcweir rtl_uString_newReplaceStrAt( &pTmp, ustrSystemPath, 0, 1, pTmp );
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
349cdf0e10cSrcweir else
350cdf0e10cSrcweir {
351cdf0e10cSrcweir /* FIXME: replace ~user with users home directory */
352cdf0e10cSrcweir return osl_File_E_INVAL;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
356cdf0e10cSrcweir /* check if initial string contains double instances of '/' */
357cdf0e10cSrcweir nIndex = rtl_ustr_indexOfStr_WithLength( ustrSystemPath->buffer, ustrSystemPath->length, pDoubleSlash, 2 );
358cdf0e10cSrcweir if( -1 != nIndex )
359cdf0e10cSrcweir {
360cdf0e10cSrcweir sal_Int32 nSrcIndex;
361cdf0e10cSrcweir sal_Int32 nDeleted = 0;
362cdf0e10cSrcweir
363cdf0e10cSrcweir /* if pTmp is not already allocated, copy ustrSystemPath for modification */
364cdf0e10cSrcweir if( NULL == pTmp )
365cdf0e10cSrcweir rtl_uString_newFromString( &pTmp, ustrSystemPath );
366cdf0e10cSrcweir
367cdf0e10cSrcweir /* adapt index to pTmp */
368cdf0e10cSrcweir nIndex += pTmp->length - ustrSystemPath->length;
369cdf0e10cSrcweir
37086e1cf34SPedro Giffuni /* remove all occurrences of '//' */
371cdf0e10cSrcweir for( nSrcIndex = nIndex + 1; nSrcIndex < pTmp->length; nSrcIndex++ )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir if( ((sal_Unicode) '/' == pTmp->buffer[nSrcIndex]) && ((sal_Unicode) '/' == pTmp->buffer[nIndex]) )
374cdf0e10cSrcweir nDeleted++;
375cdf0e10cSrcweir else
376cdf0e10cSrcweir pTmp->buffer[++nIndex] = pTmp->buffer[nSrcIndex];
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
379cdf0e10cSrcweir /* adjust length member */
380cdf0e10cSrcweir pTmp->length -= nDeleted;
381cdf0e10cSrcweir }
382cdf0e10cSrcweir
383cdf0e10cSrcweir if( NULL == pTmp )
384cdf0e10cSrcweir rtl_uString_assign( &pTmp, ustrSystemPath );
385cdf0e10cSrcweir
386*0170220dSmseidel /* temporary check for top 5 wrong usage strings (which are valid but unlikely filenames) */
387cdf0e10cSrcweir /*
388cdf0e10cSrcweir OSL_ASSERT( !findWrongUsage( pTmp->buffer, pTmp->length ) );
389cdf0e10cSrcweir */
390cdf0e10cSrcweir
391cdf0e10cSrcweir /* file URLs must be URI encoded */
392cdf0e10cSrcweir rtl_uriEncode( pTmp, uriCharClass, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8, pustrFileURL );
393cdf0e10cSrcweir
394cdf0e10cSrcweir rtl_uString_release( pTmp );
395cdf0e10cSrcweir
396cdf0e10cSrcweir /* absolute urls should start with 'file://' */
397cdf0e10cSrcweir if( (sal_Unicode)'/' == (*pustrFileURL)->buffer[0] )
398cdf0e10cSrcweir {
399cdf0e10cSrcweir rtl_uString *pProtocol = NULL;
400cdf0e10cSrcweir
401cdf0e10cSrcweir rtl_uString_newFromAscii( &pProtocol, "file://" );
402cdf0e10cSrcweir rtl_uString_newConcat( pustrFileURL, pProtocol, *pustrFileURL );
403cdf0e10cSrcweir rtl_uString_release( pProtocol );
404cdf0e10cSrcweir }
405cdf0e10cSrcweir
406cdf0e10cSrcweir return osl_File_E_None;
407cdf0e10cSrcweir }
408cdf0e10cSrcweir
409cdf0e10cSrcweir /****************************************************************************
410cdf0e10cSrcweir * osl_getSystemPathFromFileURL_Ex - helper function
411cdf0e10cSrcweir * clients may specify if they want to accept relative
412cdf0e10cSrcweir * URLs or not
413cdf0e10cSrcweir ****************************************************************************/
414cdf0e10cSrcweir
osl_getSystemPathFromFileURL_Ex(rtl_uString * ustrFileURL,rtl_uString ** pustrSystemPath,sal_Bool bAllowRelative)415cdf0e10cSrcweir oslFileError osl_getSystemPathFromFileURL_Ex(
416cdf0e10cSrcweir rtl_uString *ustrFileURL, rtl_uString **pustrSystemPath, sal_Bool bAllowRelative)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir rtl_uString* temp = 0;
419cdf0e10cSrcweir oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &temp);
420cdf0e10cSrcweir
421cdf0e10cSrcweir if (osl_File_E_None == osl_error)
422cdf0e10cSrcweir {
423cdf0e10cSrcweir if (bAllowRelative || (UNICHAR_SLASH == temp->buffer[0]))
424cdf0e10cSrcweir {
425cdf0e10cSrcweir *pustrSystemPath = temp;
426cdf0e10cSrcweir }
427cdf0e10cSrcweir else
428cdf0e10cSrcweir {
429cdf0e10cSrcweir rtl_uString_release(temp);
430cdf0e10cSrcweir osl_error = osl_File_E_INVAL;
431cdf0e10cSrcweir }
432cdf0e10cSrcweir }
433cdf0e10cSrcweir
434cdf0e10cSrcweir return osl_error;
435cdf0e10cSrcweir }
436cdf0e10cSrcweir
437cdf0e10cSrcweir namespace /* private */
438cdf0e10cSrcweir {
439cdf0e10cSrcweir
440cdf0e10cSrcweir /******************************************************
441cdf0e10cSrcweir * Helper function, return a pinter to the final '\0'
442cdf0e10cSrcweir * of a string
443cdf0e10cSrcweir ******************************************************/
444cdf0e10cSrcweir
ustrtoend(sal_Unicode * pStr)445cdf0e10cSrcweir sal_Unicode* ustrtoend(sal_Unicode* pStr)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir return (pStr + rtl_ustr_getLength(pStr));
448cdf0e10cSrcweir }
449cdf0e10cSrcweir
450cdf0e10cSrcweir /*********************************************
451cdf0e10cSrcweir
452cdf0e10cSrcweir ********************************************/
453cdf0e10cSrcweir
ustrchrcat(const sal_Unicode chr,sal_Unicode * d)454cdf0e10cSrcweir sal_Unicode* ustrchrcat(const sal_Unicode chr, sal_Unicode* d)
455cdf0e10cSrcweir {
456cdf0e10cSrcweir sal_Unicode* p = ustrtoend(d);
457cdf0e10cSrcweir *p++ = chr;
458cdf0e10cSrcweir *p = 0;
459cdf0e10cSrcweir return d;
460cdf0e10cSrcweir }
461cdf0e10cSrcweir
462cdf0e10cSrcweir /******************************************************
463cdf0e10cSrcweir *
464cdf0e10cSrcweir ******************************************************/
465cdf0e10cSrcweir
_islastchr(sal_Unicode * pStr,sal_Unicode Chr)466cdf0e10cSrcweir bool _islastchr(sal_Unicode* pStr, sal_Unicode Chr)
467cdf0e10cSrcweir {
468cdf0e10cSrcweir sal_Unicode* p = ustrtoend(pStr);
469cdf0e10cSrcweir if (p > pStr)
470cdf0e10cSrcweir p--;
471cdf0e10cSrcweir return (*p == Chr);
472cdf0e10cSrcweir }
473cdf0e10cSrcweir
474cdf0e10cSrcweir /******************************************************
475cdf0e10cSrcweir * Remove the last part of a path, a path that has
476cdf0e10cSrcweir * only a '/' or no '/' at all will be returned
477cdf0e10cSrcweir * unmodified
478cdf0e10cSrcweir ******************************************************/
479cdf0e10cSrcweir
_rmlastpathtoken(sal_Unicode * aPath)480cdf0e10cSrcweir sal_Unicode* _rmlastpathtoken(sal_Unicode* aPath)
481cdf0e10cSrcweir {
482cdf0e10cSrcweir /* we always may skip -2 because we
483cdf0e10cSrcweir may at least stand on a '/' but
484cdf0e10cSrcweir either there is no other character
485cdf0e10cSrcweir before this '/' or it's another
486cdf0e10cSrcweir character than the '/'
487cdf0e10cSrcweir */
488cdf0e10cSrcweir sal_Unicode* p = ustrtoend(aPath) - 2;
489cdf0e10cSrcweir
490cdf0e10cSrcweir // move back to the next path separator
491cdf0e10cSrcweir // or to the start of the string
492cdf0e10cSrcweir while ((p > aPath) && (*p != UNICHAR_SLASH))
493cdf0e10cSrcweir p--;
494cdf0e10cSrcweir
495cdf0e10cSrcweir if (p >= aPath)
496cdf0e10cSrcweir {
497cdf0e10cSrcweir if (UNICHAR_SLASH == *p)
498cdf0e10cSrcweir {
499cdf0e10cSrcweir p++;
500cdf0e10cSrcweir *p = '\0';
501cdf0e10cSrcweir }
502cdf0e10cSrcweir else
503cdf0e10cSrcweir {
504cdf0e10cSrcweir *p = '\0';
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir return aPath;
509cdf0e10cSrcweir }
510cdf0e10cSrcweir
511cdf0e10cSrcweir /******************************************************
512cdf0e10cSrcweir *
513cdf0e10cSrcweir ******************************************************/
514cdf0e10cSrcweir
_osl_resolvepath(sal_Unicode * path,sal_Unicode * current_pos,bool * failed)515cdf0e10cSrcweir oslFileError _osl_resolvepath(
516cdf0e10cSrcweir /*inout*/ sal_Unicode* path,
517cdf0e10cSrcweir /*inout*/ sal_Unicode* current_pos,
518cdf0e10cSrcweir /*inout*/ bool* failed)
519cdf0e10cSrcweir {
520cdf0e10cSrcweir oslFileError ferr = osl_File_E_None;
521cdf0e10cSrcweir
522cdf0e10cSrcweir if (!*failed)
523cdf0e10cSrcweir {
524cdf0e10cSrcweir char unresolved_path[PATH_MAX];
525cdf0e10cSrcweir if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), path, rtl_ustr_getLength(path)))
526cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
527cdf0e10cSrcweir
528cdf0e10cSrcweir char resolved_path[PATH_MAX];
529cdf0e10cSrcweir if (realpath(unresolved_path, resolved_path))
530cdf0e10cSrcweir {
531cdf0e10cSrcweir if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX))
532cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
533cdf0e10cSrcweir
534cdf0e10cSrcweir current_pos = ustrtoend(path) - 1;
535cdf0e10cSrcweir }
536cdf0e10cSrcweir else
537cdf0e10cSrcweir {
538cdf0e10cSrcweir if (EACCES == errno || ENOTDIR == errno || ENOENT == errno)
539cdf0e10cSrcweir *failed = true;
540cdf0e10cSrcweir else
541cdf0e10cSrcweir ferr = oslTranslateFileError(OSL_FET_ERROR, errno);
542cdf0e10cSrcweir }
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
545cdf0e10cSrcweir return ferr;
546cdf0e10cSrcweir }
547cdf0e10cSrcweir
548cdf0e10cSrcweir /******************************************************
549cdf0e10cSrcweir * Works even with non existing paths. The resulting
550cdf0e10cSrcweir * path must not exceed PATH_MAX else
551cdf0e10cSrcweir * osl_File_E_NAMETOOLONG is the result
552cdf0e10cSrcweir ******************************************************/
553cdf0e10cSrcweir
osl_getAbsoluteFileURL_impl_(const rtl::OUString & unresolved_path,rtl::OUString & resolved_path)554cdf0e10cSrcweir oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved_path, rtl::OUString& resolved_path)
555cdf0e10cSrcweir {
556cdf0e10cSrcweir // the given unresolved path must not exceed PATH_MAX
557cdf0e10cSrcweir if (unresolved_path.getLength() >= (PATH_MAX - 2))
558cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
559cdf0e10cSrcweir
560cdf0e10cSrcweir sal_Unicode path_resolved_so_far[PATH_MAX];
561cdf0e10cSrcweir const sal_Unicode* punresolved = unresolved_path.getStr();
562cdf0e10cSrcweir sal_Unicode* presolvedsf = path_resolved_so_far;
563cdf0e10cSrcweir
564cdf0e10cSrcweir // reserve space for leading '/' and trailing '\0'
565cdf0e10cSrcweir // do not exceed this limit
566cdf0e10cSrcweir sal_Unicode* sentinel = path_resolved_so_far + PATH_MAX - 2;
567cdf0e10cSrcweir
568cdf0e10cSrcweir // if realpath fails with error ENOTDIR, EACCES or ENOENT
569cdf0e10cSrcweir // we will not call it again, because _osl_realpath should also
570cdf0e10cSrcweir // work with non existing directories etc.
571cdf0e10cSrcweir bool realpath_failed = false;
572cdf0e10cSrcweir oslFileError ferr;
573cdf0e10cSrcweir
574cdf0e10cSrcweir path_resolved_so_far[0] = '\0';
575cdf0e10cSrcweir
576cdf0e10cSrcweir while (*punresolved != '\0')
577cdf0e10cSrcweir {
578cdf0e10cSrcweir // ignore '/.' , skip one part back when '/..'
579cdf0e10cSrcweir
580cdf0e10cSrcweir if ((UNICHAR_DOT == *punresolved) && (UNICHAR_SLASH == *presolvedsf))
581cdf0e10cSrcweir {
582cdf0e10cSrcweir if ('\0' == *(punresolved + 1))
583cdf0e10cSrcweir {
584cdf0e10cSrcweir punresolved++;
585cdf0e10cSrcweir continue;
586cdf0e10cSrcweir }
587cdf0e10cSrcweir else if (UNICHAR_SLASH == *(punresolved + 1))
588cdf0e10cSrcweir {
589cdf0e10cSrcweir punresolved += 2;
590cdf0e10cSrcweir continue;
591cdf0e10cSrcweir }
592cdf0e10cSrcweir else if ((UNICHAR_DOT == *(punresolved + 1)) && ('\0' == *(punresolved + 2) || (UNICHAR_SLASH == *(punresolved + 2))))
593cdf0e10cSrcweir {
594cdf0e10cSrcweir _rmlastpathtoken(path_resolved_so_far);
595cdf0e10cSrcweir
596cdf0e10cSrcweir presolvedsf = ustrtoend(path_resolved_so_far) - 1;
597cdf0e10cSrcweir
598cdf0e10cSrcweir if (UNICHAR_SLASH == *(punresolved + 2))
599cdf0e10cSrcweir punresolved += 3;
600cdf0e10cSrcweir else
601cdf0e10cSrcweir punresolved += 2;
602cdf0e10cSrcweir
603cdf0e10cSrcweir continue;
604cdf0e10cSrcweir }
605cdf0e10cSrcweir else // a file or directory name may start with '.'
606cdf0e10cSrcweir {
607cdf0e10cSrcweir if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
608cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
609cdf0e10cSrcweir
610cdf0e10cSrcweir ustrchrcat(*punresolved++, path_resolved_so_far);
611cdf0e10cSrcweir
612cdf0e10cSrcweir if ('\0' == *punresolved && !realpath_failed)
613cdf0e10cSrcweir {
614cdf0e10cSrcweir ferr = _osl_resolvepath(
615cdf0e10cSrcweir path_resolved_so_far,
616cdf0e10cSrcweir presolvedsf,
617cdf0e10cSrcweir &realpath_failed);
618cdf0e10cSrcweir
619cdf0e10cSrcweir if (osl_File_E_None != ferr)
620cdf0e10cSrcweir return ferr;
621cdf0e10cSrcweir }
622cdf0e10cSrcweir }
623cdf0e10cSrcweir }
624cdf0e10cSrcweir else if (UNICHAR_SLASH == *punresolved)
625cdf0e10cSrcweir {
626cdf0e10cSrcweir if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
627cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
628cdf0e10cSrcweir
629cdf0e10cSrcweir ustrchrcat(*punresolved++, path_resolved_so_far);
630cdf0e10cSrcweir
631cdf0e10cSrcweir if (!realpath_failed)
632cdf0e10cSrcweir {
633cdf0e10cSrcweir ferr = _osl_resolvepath(
634cdf0e10cSrcweir path_resolved_so_far,
635cdf0e10cSrcweir presolvedsf,
636cdf0e10cSrcweir &realpath_failed);
637cdf0e10cSrcweir
638cdf0e10cSrcweir if (osl_File_E_None != ferr)
639cdf0e10cSrcweir return ferr;
640cdf0e10cSrcweir
641cdf0e10cSrcweir if (!_islastchr(path_resolved_so_far, UNICHAR_SLASH))
642cdf0e10cSrcweir {
643cdf0e10cSrcweir if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
644cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
645cdf0e10cSrcweir
646cdf0e10cSrcweir ustrchrcat(UNICHAR_SLASH, path_resolved_so_far);
647cdf0e10cSrcweir }
648cdf0e10cSrcweir }
649cdf0e10cSrcweir }
650cdf0e10cSrcweir else // any other character
651cdf0e10cSrcweir {
652cdf0e10cSrcweir if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel)
653cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG);
654cdf0e10cSrcweir
655cdf0e10cSrcweir ustrchrcat(*punresolved++, path_resolved_so_far);
656cdf0e10cSrcweir
657cdf0e10cSrcweir if ('\0' == *punresolved && !realpath_failed)
658cdf0e10cSrcweir {
659cdf0e10cSrcweir ferr = _osl_resolvepath(
660cdf0e10cSrcweir path_resolved_so_far,
661cdf0e10cSrcweir presolvedsf,
662cdf0e10cSrcweir &realpath_failed);
663cdf0e10cSrcweir
664cdf0e10cSrcweir if (osl_File_E_None != ferr)
665cdf0e10cSrcweir return ferr;
666cdf0e10cSrcweir }
667cdf0e10cSrcweir }
668cdf0e10cSrcweir }
669cdf0e10cSrcweir
670cdf0e10cSrcweir sal_Int32 len = rtl_ustr_getLength(path_resolved_so_far);
671cdf0e10cSrcweir
672cdf0e10cSrcweir OSL_ASSERT(len < PATH_MAX);
673cdf0e10cSrcweir
674cdf0e10cSrcweir resolved_path = rtl::OUString(path_resolved_so_far, len);
675cdf0e10cSrcweir
676cdf0e10cSrcweir return osl_File_E_None;
677cdf0e10cSrcweir }
678cdf0e10cSrcweir
679cdf0e10cSrcweir } // end namespace private
680cdf0e10cSrcweir
681cdf0e10cSrcweir
682cdf0e10cSrcweir /******************************************************
683cdf0e10cSrcweir * osl_getAbsoluteFileURL
684cdf0e10cSrcweir ******************************************************/
685cdf0e10cSrcweir
osl_getAbsoluteFileURL(rtl_uString * ustrBaseDirURL,rtl_uString * ustrRelativeURL,rtl_uString ** pustrAbsoluteURL)686cdf0e10cSrcweir oslFileError osl_getAbsoluteFileURL(rtl_uString* ustrBaseDirURL, rtl_uString* ustrRelativeURL, rtl_uString** pustrAbsoluteURL)
687cdf0e10cSrcweir {
688cdf0e10cSrcweir FileBase::RC rc;
689cdf0e10cSrcweir rtl::OUString unresolved_path;
690cdf0e10cSrcweir
691cdf0e10cSrcweir rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrRelativeURL), unresolved_path);
692cdf0e10cSrcweir
693cdf0e10cSrcweir if(FileBase::E_None != rc)
694cdf0e10cSrcweir return oslFileError(rc);
695cdf0e10cSrcweir
696cdf0e10cSrcweir if (systemPathIsRelativePath(unresolved_path))
697cdf0e10cSrcweir {
698cdf0e10cSrcweir rtl::OUString base_path;
699cdf0e10cSrcweir rc = (FileBase::RC) osl_getSystemPathFromFileURL_Ex(ustrBaseDirURL, &base_path.pData, sal_False);
700cdf0e10cSrcweir
701cdf0e10cSrcweir if (FileBase::E_None != rc)
702cdf0e10cSrcweir return oslFileError(rc);
703cdf0e10cSrcweir
704cdf0e10cSrcweir rtl::OUString abs_path;
705cdf0e10cSrcweir systemPathMakeAbsolutePath(base_path, unresolved_path, abs_path);
706cdf0e10cSrcweir
707cdf0e10cSrcweir unresolved_path = abs_path;
708cdf0e10cSrcweir }
709cdf0e10cSrcweir
710cdf0e10cSrcweir rtl::OUString resolved_path;
711cdf0e10cSrcweir rc = (FileBase::RC) osl_getAbsoluteFileURL_impl_(unresolved_path, resolved_path);
712cdf0e10cSrcweir
713cdf0e10cSrcweir if (FileBase::E_None == rc)
714cdf0e10cSrcweir {
715cdf0e10cSrcweir rc = (FileBase::RC) osl_getFileURLFromSystemPath(resolved_path.pData, pustrAbsoluteURL);
716cdf0e10cSrcweir OSL_ASSERT(FileBase::E_None == rc);
717cdf0e10cSrcweir }
718cdf0e10cSrcweir
719cdf0e10cSrcweir return oslFileError(rc);
720cdf0e10cSrcweir }
721cdf0e10cSrcweir
722cdf0e10cSrcweir
723cdf0e10cSrcweir namespace /* private */
724cdf0e10cSrcweir {
725cdf0e10cSrcweir
726cdf0e10cSrcweir /*********************************************
727cdf0e10cSrcweir No separate error code if unicode to text
728cdf0e10cSrcweir conversion or getenv fails because for the
729cdf0e10cSrcweir caller there is no difference why a file
730cdf0e10cSrcweir could not be found in $PATH
731cdf0e10cSrcweir ********************************************/
732cdf0e10cSrcweir
find_in_PATH(const rtl::OUString & file_path,rtl::OUString & result)733cdf0e10cSrcweir bool find_in_PATH(const rtl::OUString& file_path, rtl::OUString& result)
734cdf0e10cSrcweir {
735cdf0e10cSrcweir bool bfound = false;
736cdf0e10cSrcweir rtl::OUString path = rtl::OUString::createFromAscii("PATH");
737cdf0e10cSrcweir rtl::OUString env_path;
738cdf0e10cSrcweir
739cdf0e10cSrcweir if (osl_Process_E_None == osl_getEnvironment(path.pData, &env_path.pData))
740cdf0e10cSrcweir bfound = osl::searchPath(file_path, env_path, result);
741cdf0e10cSrcweir
742cdf0e10cSrcweir return bfound;
743cdf0e10cSrcweir }
744cdf0e10cSrcweir
745cdf0e10cSrcweir /*********************************************
746cdf0e10cSrcweir No separate error code if unicode to text
747cdf0e10cSrcweir conversion or getcwd fails because for the
748cdf0e10cSrcweir caller there is no difference why a file
749cdf0e10cSrcweir could not be found in CDW
750cdf0e10cSrcweir ********************************************/
751cdf0e10cSrcweir
find_in_CWD(const rtl::OUString & file_path,rtl::OUString & result)752cdf0e10cSrcweir bool find_in_CWD(const rtl::OUString& file_path, rtl::OUString& result)
753cdf0e10cSrcweir {
754cdf0e10cSrcweir bool bfound = false;
755cdf0e10cSrcweir rtl::OUString cwd_url;
756cdf0e10cSrcweir
757cdf0e10cSrcweir if (osl_Process_E_None == osl_getProcessWorkingDir(&cwd_url.pData))
758cdf0e10cSrcweir {
759cdf0e10cSrcweir rtl::OUString cwd;
760cdf0e10cSrcweir FileBase::getSystemPathFromFileURL(cwd_url, cwd);
761cdf0e10cSrcweir bfound = osl::searchPath(file_path, cwd, result);
762cdf0e10cSrcweir }
763cdf0e10cSrcweir return bfound;
764cdf0e10cSrcweir }
765cdf0e10cSrcweir
766cdf0e10cSrcweir /*********************************************
767cdf0e10cSrcweir
768cdf0e10cSrcweir ********************************************/
769cdf0e10cSrcweir
find_in_searchPath(const rtl::OUString & file_path,rtl_uString * search_path,rtl::OUString & result)770cdf0e10cSrcweir bool find_in_searchPath(const rtl::OUString& file_path, rtl_uString* search_path, rtl::OUString& result)
771cdf0e10cSrcweir {
772cdf0e10cSrcweir return (search_path && osl::searchPath(file_path, rtl::OUString(search_path), result));
773cdf0e10cSrcweir }
774cdf0e10cSrcweir
775cdf0e10cSrcweir } // end namespace private
776cdf0e10cSrcweir
777cdf0e10cSrcweir
778cdf0e10cSrcweir /****************************************************************************
779cdf0e10cSrcweir * osl_searchFileURL
780cdf0e10cSrcweir ***************************************************************************/
781cdf0e10cSrcweir
osl_searchFileURL(rtl_uString * ustrFilePath,rtl_uString * ustrSearchPath,rtl_uString ** pustrURL)782cdf0e10cSrcweir oslFileError osl_searchFileURL(rtl_uString* ustrFilePath, rtl_uString* ustrSearchPath, rtl_uString** pustrURL)
783cdf0e10cSrcweir {
784cdf0e10cSrcweir OSL_PRECOND(ustrFilePath && pustrURL, "osl_searchFileURL: invalid parameter");
785cdf0e10cSrcweir
786cdf0e10cSrcweir FileBase::RC rc;
787cdf0e10cSrcweir rtl::OUString file_path;
788cdf0e10cSrcweir
789cdf0e10cSrcweir // try to interpret search path as file url else assume it's a system path list
790cdf0e10cSrcweir rc = FileBase::getSystemPathFromFileURL(rtl::OUString(ustrFilePath), file_path);
791cdf0e10cSrcweir if ((FileBase::E_None != rc) && (FileBase::E_INVAL == rc))
792cdf0e10cSrcweir file_path = ustrFilePath;
793cdf0e10cSrcweir else if (FileBase::E_None != rc)
794cdf0e10cSrcweir return oslFileError(rc);
795cdf0e10cSrcweir
796cdf0e10cSrcweir bool bfound = false;
797cdf0e10cSrcweir rtl::OUString result;
798cdf0e10cSrcweir
799cdf0e10cSrcweir if (find_in_searchPath(file_path, ustrSearchPath, result) ||
800cdf0e10cSrcweir find_in_PATH(file_path, result) ||
801cdf0e10cSrcweir find_in_CWD(file_path, result))
802cdf0e10cSrcweir {
803cdf0e10cSrcweir rtl::OUString resolved;
804cdf0e10cSrcweir
805cdf0e10cSrcweir if (osl::realpath(result, resolved))
806cdf0e10cSrcweir {
807cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
808cdf0e10cSrcweir oslFileError osl_error =
809cdf0e10cSrcweir #endif
810cdf0e10cSrcweir osl_getFileURLFromSystemPath(resolved.pData, pustrURL);
811cdf0e10cSrcweir OSL_ASSERT(osl_File_E_None == osl_error);
812cdf0e10cSrcweir bfound = true;
813cdf0e10cSrcweir }
814cdf0e10cSrcweir }
815cdf0e10cSrcweir return bfound ? osl_File_E_None : osl_File_E_NOENT;
816cdf0e10cSrcweir }
817cdf0e10cSrcweir
818cdf0e10cSrcweir
819cdf0e10cSrcweir /****************************************************************************
820cdf0e10cSrcweir * FileURLToPath
821cdf0e10cSrcweir ***************************************************************************/
822cdf0e10cSrcweir
FileURLToPath(char * buffer,size_t bufLen,rtl_uString * ustrFileURL)823cdf0e10cSrcweir oslFileError FileURLToPath(char * buffer, size_t bufLen, rtl_uString* ustrFileURL)
824cdf0e10cSrcweir {
825cdf0e10cSrcweir rtl_uString* ustrSystemPath = NULL;
826cdf0e10cSrcweir oslFileError osl_error = osl_getSystemPathFromFileURL(ustrFileURL, &ustrSystemPath);
827cdf0e10cSrcweir
828cdf0e10cSrcweir if(osl_File_E_None != osl_error)
829cdf0e10cSrcweir return osl_error;
830cdf0e10cSrcweir
831cdf0e10cSrcweir osl_systemPathRemoveSeparator(ustrSystemPath);
832cdf0e10cSrcweir
833cdf0e10cSrcweir /* convert unicode path to text */
834cdf0e10cSrcweir if(!UnicodeToText( buffer, bufLen, ustrSystemPath->buffer, ustrSystemPath->length))
835cdf0e10cSrcweir osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
836cdf0e10cSrcweir
837cdf0e10cSrcweir rtl_uString_release(ustrSystemPath);
838cdf0e10cSrcweir
839cdf0e10cSrcweir return osl_error;
840cdf0e10cSrcweir }
841cdf0e10cSrcweir
842cdf0e10cSrcweir /*****************************************************************************
843cdf0e10cSrcweir * UnicodeToText
844cdf0e10cSrcweir ****************************************************************************/
845cdf0e10cSrcweir
846cdf0e10cSrcweir namespace /* private */
847cdf0e10cSrcweir {
848cdf0e10cSrcweir class UnicodeToTextConverter_Impl
849cdf0e10cSrcweir {
850cdf0e10cSrcweir rtl_UnicodeToTextConverter m_converter;
851cdf0e10cSrcweir
UnicodeToTextConverter_Impl()852cdf0e10cSrcweir UnicodeToTextConverter_Impl()
853cdf0e10cSrcweir : m_converter (rtl_createUnicodeToTextConverter (osl_getThreadTextEncoding()))
854cdf0e10cSrcweir {}
855cdf0e10cSrcweir
~UnicodeToTextConverter_Impl()856cdf0e10cSrcweir ~UnicodeToTextConverter_Impl()
857cdf0e10cSrcweir {
858cdf0e10cSrcweir rtl_destroyUnicodeToTextConverter (m_converter);
859cdf0e10cSrcweir }
860cdf0e10cSrcweir public:
getInstance()861cdf0e10cSrcweir static UnicodeToTextConverter_Impl & getInstance()
862cdf0e10cSrcweir {
863cdf0e10cSrcweir static UnicodeToTextConverter_Impl g_theConverter;
864cdf0e10cSrcweir return g_theConverter;
865cdf0e10cSrcweir }
866cdf0e10cSrcweir
convert(sal_Unicode const * pSrcBuf,sal_Size nSrcChars,sal_Char * pDstBuf,sal_Size nDstBytes,sal_uInt32 nFlags,sal_uInt32 * pInfo,sal_Size * pSrcCvtChars)867cdf0e10cSrcweir sal_Size convert(
868cdf0e10cSrcweir sal_Unicode const * pSrcBuf, sal_Size nSrcChars, sal_Char * pDstBuf, sal_Size nDstBytes,
869cdf0e10cSrcweir sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtChars)
870cdf0e10cSrcweir {
871cdf0e10cSrcweir OSL_ASSERT(m_converter != 0);
872cdf0e10cSrcweir return rtl_convertUnicodeToText (
873cdf0e10cSrcweir m_converter, 0, pSrcBuf, nSrcChars, pDstBuf, nDstBytes, nFlags, pInfo, pSrcCvtChars);
874cdf0e10cSrcweir }
875cdf0e10cSrcweir };
876cdf0e10cSrcweir } // end namespace private
877cdf0e10cSrcweir
UnicodeToText(char * buffer,size_t bufLen,const sal_Unicode * uniText,sal_Int32 uniTextLen)878cdf0e10cSrcweir int UnicodeToText( char * buffer, size_t bufLen, const sal_Unicode * uniText, sal_Int32 uniTextLen )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir sal_uInt32 nInfo = 0;
881cdf0e10cSrcweir sal_Size nSrcChars = 0;
882cdf0e10cSrcweir
883cdf0e10cSrcweir sal_Size nDestBytes = UnicodeToTextConverter_Impl::getInstance().convert (
884cdf0e10cSrcweir uniText, uniTextLen, buffer, bufLen,
885cdf0e10cSrcweir OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH, &nInfo, &nSrcChars);
886cdf0e10cSrcweir
887cdf0e10cSrcweir if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
888cdf0e10cSrcweir {
889cdf0e10cSrcweir errno = EOVERFLOW;
890cdf0e10cSrcweir return 0;
891cdf0e10cSrcweir }
892cdf0e10cSrcweir
893cdf0e10cSrcweir /* ensure trailing '\0' */
894cdf0e10cSrcweir buffer[nDestBytes] = '\0';
895cdf0e10cSrcweir return nDestBytes;
896cdf0e10cSrcweir }
897cdf0e10cSrcweir
898cdf0e10cSrcweir /*****************************************************************************
899cdf0e10cSrcweir * TextToUnicode
900cdf0e10cSrcweir ****************************************************************************/
901cdf0e10cSrcweir
902cdf0e10cSrcweir namespace /* private */
903cdf0e10cSrcweir {
904cdf0e10cSrcweir class TextToUnicodeConverter_Impl
905cdf0e10cSrcweir {
906cdf0e10cSrcweir rtl_TextToUnicodeConverter m_converter;
907cdf0e10cSrcweir
TextToUnicodeConverter_Impl()908cdf0e10cSrcweir TextToUnicodeConverter_Impl()
909cdf0e10cSrcweir : m_converter (rtl_createTextToUnicodeConverter (osl_getThreadTextEncoding()))
910cdf0e10cSrcweir {}
911cdf0e10cSrcweir
~TextToUnicodeConverter_Impl()912cdf0e10cSrcweir ~TextToUnicodeConverter_Impl()
913cdf0e10cSrcweir {
914cdf0e10cSrcweir rtl_destroyTextToUnicodeConverter (m_converter);
915cdf0e10cSrcweir }
916cdf0e10cSrcweir
917cdf0e10cSrcweir public:
getInstance()918cdf0e10cSrcweir static TextToUnicodeConverter_Impl & getInstance()
919cdf0e10cSrcweir {
920cdf0e10cSrcweir static TextToUnicodeConverter_Impl g_theConverter;
921cdf0e10cSrcweir return g_theConverter;
922cdf0e10cSrcweir }
923cdf0e10cSrcweir
convert(sal_Char const * pSrcBuf,sal_Size nSrcBytes,sal_Unicode * pDstBuf,sal_Size nDstChars,sal_uInt32 nFlags,sal_uInt32 * pInfo,sal_Size * pSrcCvtBytes)924cdf0e10cSrcweir sal_Size convert(
925cdf0e10cSrcweir sal_Char const * pSrcBuf, sal_Size nSrcBytes, sal_Unicode * pDstBuf, sal_Size nDstChars,
926cdf0e10cSrcweir sal_uInt32 nFlags, sal_uInt32 * pInfo, sal_Size * pSrcCvtBytes)
927cdf0e10cSrcweir {
928cdf0e10cSrcweir OSL_ASSERT(m_converter != 0);
929cdf0e10cSrcweir return rtl_convertTextToUnicode (
930cdf0e10cSrcweir m_converter, 0, pSrcBuf, nSrcBytes, pDstBuf, nDstChars, nFlags, pInfo, pSrcCvtBytes);
931cdf0e10cSrcweir }
932cdf0e10cSrcweir };
933cdf0e10cSrcweir } // end namespace private
934cdf0e10cSrcweir
TextToUnicode(const char * text,size_t text_buffer_size,sal_Unicode * unic_text,sal_Int32 unic_text_buffer_size)935cdf0e10cSrcweir int TextToUnicode(
936cdf0e10cSrcweir const char* text,
937cdf0e10cSrcweir size_t text_buffer_size,
938cdf0e10cSrcweir sal_Unicode* unic_text,
939cdf0e10cSrcweir sal_Int32 unic_text_buffer_size)
940cdf0e10cSrcweir {
941cdf0e10cSrcweir sal_uInt32 nInfo = 0;
942cdf0e10cSrcweir sal_Size nSrcChars = 0;
943cdf0e10cSrcweir
944cdf0e10cSrcweir sal_Size nDestBytes = TextToUnicodeConverter_Impl::getInstance().convert(
945cdf0e10cSrcweir text, text_buffer_size, unic_text, unic_text_buffer_size,
946cdf0e10cSrcweir OSTRING_TO_OUSTRING_CVTFLAGS | RTL_TEXTTOUNICODE_FLAGS_FLUSH, &nInfo, &nSrcChars);
947cdf0e10cSrcweir
948cdf0e10cSrcweir if (nInfo & RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)
949cdf0e10cSrcweir {
950cdf0e10cSrcweir errno = EOVERFLOW;
951cdf0e10cSrcweir return 0;
952cdf0e10cSrcweir }
953cdf0e10cSrcweir
954cdf0e10cSrcweir /* ensure trailing '\0' */
955cdf0e10cSrcweir unic_text[nDestBytes] = '\0';
956cdf0e10cSrcweir return nDestBytes;
957cdf0e10cSrcweir }
958