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