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