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