1*c82f2877SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*c82f2877SAndrew Rist * distributed with this work for additional information 6*c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*c82f2877SAndrew Rist * "License"); you may not use this file except in compliance 9*c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at 10*c82f2877SAndrew Rist * 11*c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*c82f2877SAndrew Rist * 13*c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*c82f2877SAndrew Rist * software distributed under the License is distributed on an 15*c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*c82f2877SAndrew Rist * KIND, either express or implied. See the License for the 17*c82f2877SAndrew Rist * specific language governing permissions and limitations 18*c82f2877SAndrew Rist * under the License. 19*c82f2877SAndrew Rist * 20*c82f2877SAndrew Rist *************************************************************/ 21*c82f2877SAndrew Rist 22*c82f2877SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <cstring> 28cdf0e10cSrcweir #include <sys/stat.h> 29cdf0e10cSrcweir #include <unistd.h> 30cdf0e10cSrcweir #include <limits.h> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "vcl/helper.hxx" 33cdf0e10cSrcweir #include "vcl/ppdparser.hxx" 34cdf0e10cSrcweir #include "tools/string.hxx" 35cdf0e10cSrcweir #include "tools/urlobj.hxx" 36cdf0e10cSrcweir #include "osl/file.hxx" 37cdf0e10cSrcweir #include "osl/process.h" 38cdf0e10cSrcweir #include "rtl/bootstrap.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir using namespace rtl; 41cdf0e10cSrcweir 42cdf0e10cSrcweir namespace psp { 43cdf0e10cSrcweir 44cdf0e10cSrcweir OUString getOfficePath( enum whichOfficePath ePath ) 45cdf0e10cSrcweir { 46cdf0e10cSrcweir static OUString aNetPath; 47cdf0e10cSrcweir static OUString aUserPath; 48cdf0e10cSrcweir static OUString aConfigPath; 49cdf0e10cSrcweir static OUString aEmpty; 50cdf0e10cSrcweir static bool bOnce = false; 51cdf0e10cSrcweir 52cdf0e10cSrcweir if( ! bOnce ) 53cdf0e10cSrcweir { 54cdf0e10cSrcweir bOnce = true; 55cdf0e10cSrcweir OUString aIni; 56cdf0e10cSrcweir Bootstrap::get( OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ), aIni ); 57cdf0e10cSrcweir aIni += OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" SAL_CONFIGFILE( "bootstrap" ) ) ); 58cdf0e10cSrcweir Bootstrap aBootstrap( aIni ); 59cdf0e10cSrcweir aBootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "CustomDataUrl" ) ), aConfigPath ); 60cdf0e10cSrcweir aBootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "BaseInstallation" ) ), aNetPath ); 61cdf0e10cSrcweir aBootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "UserInstallation" ) ), aUserPath ); 62cdf0e10cSrcweir OUString aUPath = aUserPath; 63cdf0e10cSrcweir 64cdf0e10cSrcweir if( ! aConfigPath.compareToAscii( "file://", 7 ) ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir OUString aSysPath; 67cdf0e10cSrcweir if( osl_getSystemPathFromFileURL( aConfigPath.pData, &aSysPath.pData ) == osl_File_E_None ) 68cdf0e10cSrcweir aConfigPath = aSysPath; 69cdf0e10cSrcweir } 70cdf0e10cSrcweir if( ! aNetPath.compareToAscii( "file://", 7 ) ) 71cdf0e10cSrcweir { 72cdf0e10cSrcweir OUString aSysPath; 73cdf0e10cSrcweir if( osl_getSystemPathFromFileURL( aNetPath.pData, &aSysPath.pData ) == osl_File_E_None ) 74cdf0e10cSrcweir aNetPath = aSysPath; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir if( ! aUserPath.compareToAscii( "file://", 7 ) ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir OUString aSysPath; 79cdf0e10cSrcweir if( osl_getSystemPathFromFileURL( aUserPath.pData, &aSysPath.pData ) == osl_File_E_None ) 80cdf0e10cSrcweir aUserPath = aSysPath; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir // ensure user path exists 83cdf0e10cSrcweir aUPath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/psprint" ) ); 84cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 85cdf0e10cSrcweir oslFileError eErr = 86cdf0e10cSrcweir #endif 87cdf0e10cSrcweir osl_createDirectoryPath( aUPath.pData, NULL, NULL ); 88cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 89cdf0e10cSrcweir fprintf( stderr, "try to create \"%s\" = %d\n", OUStringToOString( aUPath, RTL_TEXTENCODING_UTF8 ).getStr(), eErr ); 90cdf0e10cSrcweir #endif 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir switch( ePath ) 94cdf0e10cSrcweir { 95cdf0e10cSrcweir case ConfigPath: return aConfigPath; 96cdf0e10cSrcweir case NetPath: return aNetPath; 97cdf0e10cSrcweir case UserPath: return aUserPath; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir return aEmpty; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir static OString getEnvironmentPath( const char* pKey ) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir OString aPath; 105cdf0e10cSrcweir 106cdf0e10cSrcweir const char* pValue = getenv( pKey ); 107cdf0e10cSrcweir if( pValue && *pValue ) 108cdf0e10cSrcweir { 109cdf0e10cSrcweir aPath = OString( pValue ); 110cdf0e10cSrcweir } 111cdf0e10cSrcweir return aPath; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir } // namespace psp 115cdf0e10cSrcweir 116cdf0e10cSrcweir void psp::getPrinterPathList( std::list< OUString >& rPathList, const char* pSubDir ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir rPathList.clear(); 119cdf0e10cSrcweir rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); 120cdf0e10cSrcweir 121cdf0e10cSrcweir OUStringBuffer aPathBuffer( 256 ); 122cdf0e10cSrcweir 123cdf0e10cSrcweir // append net path 124cdf0e10cSrcweir aPathBuffer.append( getOfficePath( psp::NetPath ) ); 125cdf0e10cSrcweir if( aPathBuffer.getLength() ) 126cdf0e10cSrcweir { 127cdf0e10cSrcweir aPathBuffer.appendAscii( "/share/psprint" ); 128cdf0e10cSrcweir if( pSubDir ) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir aPathBuffer.append( sal_Unicode('/') ); 131cdf0e10cSrcweir aPathBuffer.appendAscii( pSubDir ); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir rPathList.push_back( aPathBuffer.makeStringAndClear() ); 134cdf0e10cSrcweir } 135cdf0e10cSrcweir // append user path 136cdf0e10cSrcweir aPathBuffer.append( getOfficePath( psp::UserPath ) ); 137cdf0e10cSrcweir if( aPathBuffer.getLength() ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir aPathBuffer.appendAscii( "/user/psprint" ); 140cdf0e10cSrcweir if( pSubDir ) 141cdf0e10cSrcweir { 142cdf0e10cSrcweir aPathBuffer.append( sal_Unicode('/') ); 143cdf0e10cSrcweir aPathBuffer.appendAscii( pSubDir ); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir rPathList.push_back( aPathBuffer.makeStringAndClear() ); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir OString aPath( getEnvironmentPath("SAL_PSPRINT") ); 149cdf0e10cSrcweir sal_Int32 nIndex = 0; 150cdf0e10cSrcweir do 151cdf0e10cSrcweir { 152cdf0e10cSrcweir OString aDir( aPath.getToken( 0, ':', nIndex ) ); 153cdf0e10cSrcweir if( ! aDir.getLength() ) 154cdf0e10cSrcweir continue; 155cdf0e10cSrcweir 156cdf0e10cSrcweir if( pSubDir ) 157cdf0e10cSrcweir { 158cdf0e10cSrcweir aDir += "/"; 159cdf0e10cSrcweir aDir += pSubDir; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir struct stat aStat; 162cdf0e10cSrcweir if( stat( aDir.getStr(), &aStat ) || ! S_ISDIR( aStat.st_mode ) ) 163cdf0e10cSrcweir continue; 164cdf0e10cSrcweir 165cdf0e10cSrcweir rPathList.push_back( OStringToOUString( aDir, aEncoding ) ); 166cdf0e10cSrcweir } while( nIndex != -1 ); 167cdf0e10cSrcweir 168cdf0e10cSrcweir #ifdef SYSTEM_PPD_DIR 169cdf0e10cSrcweir if( pSubDir && rtl_str_compare( pSubDir, PRINTER_PPDDIR ) == 0 ) 170cdf0e10cSrcweir { 171cdf0e10cSrcweir rPathList.push_back( rtl::OStringToOUString( rtl::OString( SYSTEM_PPD_DIR ), RTL_TEXTENCODING_UTF8 ) ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir #endif 174cdf0e10cSrcweir 175cdf0e10cSrcweir if( rPathList.empty() ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir // last resort: next to program file (mainly for setup) 178cdf0e10cSrcweir OUString aExe; 179cdf0e10cSrcweir if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None ) 180cdf0e10cSrcweir { 181cdf0e10cSrcweir INetURLObject aDir( aExe ); 182cdf0e10cSrcweir aDir.removeSegment(); 183cdf0e10cSrcweir aExe = aDir.GetMainURL( INetURLObject::NO_DECODE ); 184cdf0e10cSrcweir OUString aSysPath; 185cdf0e10cSrcweir if( osl_getSystemPathFromFileURL( aExe.pData, &aSysPath.pData ) == osl_File_E_None ) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir rPathList.push_back( aSysPath ); 188cdf0e10cSrcweir } 189cdf0e10cSrcweir } 190cdf0e10cSrcweir } 191cdf0e10cSrcweir } 192cdf0e10cSrcweir 193cdf0e10cSrcweir OUString psp::getFontPath() 194cdf0e10cSrcweir { 195cdf0e10cSrcweir static OUString aPath; 196cdf0e10cSrcweir 197cdf0e10cSrcweir if( ! aPath.getLength() ) 198cdf0e10cSrcweir { 199cdf0e10cSrcweir OUStringBuffer aPathBuffer( 512 ); 200cdf0e10cSrcweir 201cdf0e10cSrcweir OUString aConfigPath( getOfficePath( psp::ConfigPath ) ); 202cdf0e10cSrcweir OUString aNetPath( getOfficePath( psp::NetPath ) ); 203cdf0e10cSrcweir OUString aUserPath( getOfficePath( psp::UserPath ) ); 204cdf0e10cSrcweir if( aConfigPath.getLength() ) 205cdf0e10cSrcweir { 206cdf0e10cSrcweir // #i53530# Path from CustomDataUrl will completely 207cdf0e10cSrcweir // replace net and user paths if the path exists 208cdf0e10cSrcweir aPathBuffer.append(aConfigPath); 209cdf0e10cSrcweir aPathBuffer.appendAscii("/share/fonts"); 210cdf0e10cSrcweir // check existance of config path 211cdf0e10cSrcweir struct stat aStat; 212cdf0e10cSrcweir if( 0 != stat( OUStringToOString( aPathBuffer.makeStringAndClear(), osl_getThreadTextEncoding() ).getStr(), &aStat ) 213cdf0e10cSrcweir || ! S_ISDIR( aStat.st_mode ) ) 214cdf0e10cSrcweir aConfigPath = OUString(); 215cdf0e10cSrcweir else 216cdf0e10cSrcweir { 217cdf0e10cSrcweir aPathBuffer.append(aConfigPath); 218cdf0e10cSrcweir aPathBuffer.appendAscii("/share/fonts"); 219cdf0e10cSrcweir } 220cdf0e10cSrcweir } 221cdf0e10cSrcweir if( aConfigPath.getLength() == 0 ) 222cdf0e10cSrcweir { 223cdf0e10cSrcweir if( aNetPath.getLength() ) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir aPathBuffer.append( aNetPath ); 226cdf0e10cSrcweir aPathBuffer.appendAscii( "/share/fonts/truetype;"); 227cdf0e10cSrcweir aPathBuffer.append( aNetPath ); 228cdf0e10cSrcweir aPathBuffer.appendAscii( "/share/fonts/type1;" ); 229cdf0e10cSrcweir } 230cdf0e10cSrcweir if( aUserPath.getLength() ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir aPathBuffer.append( aUserPath ); 233cdf0e10cSrcweir aPathBuffer.appendAscii( "/user/fonts" ); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir } 236cdf0e10cSrcweir OString aEnvPath( getEnvironmentPath( "SAL_FONTPATH_PRIVATE" ) ); 237cdf0e10cSrcweir if( aEnvPath.getLength() ) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir aPathBuffer.append( sal_Unicode(';') ); 240cdf0e10cSrcweir aPathBuffer.append( OStringToOUString( aEnvPath, osl_getThreadTextEncoding() ) ); 241cdf0e10cSrcweir } 242cdf0e10cSrcweir 243cdf0e10cSrcweir aPath = aPathBuffer.makeStringAndClear(); 244cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 245cdf0e10cSrcweir fprintf( stderr, "initializing font path to \"%s\"\n", OUStringToOString( aPath, RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); 246cdf0e10cSrcweir #endif 247cdf0e10cSrcweir } 248cdf0e10cSrcweir return aPath; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir bool psp::convertPfbToPfa( ::osl::File& rInFile, ::osl::File& rOutFile ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir static unsigned char hexDigits[] = 254cdf0e10cSrcweir { 255cdf0e10cSrcweir '0', '1', '2', '3', '4', '5', '6', '7', 256cdf0e10cSrcweir '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 257cdf0e10cSrcweir }; 258cdf0e10cSrcweir 259cdf0e10cSrcweir bool bSuccess = true; 260cdf0e10cSrcweir bool bEof = false; 261cdf0e10cSrcweir unsigned char buffer[256]; 262cdf0e10cSrcweir sal_uInt64 nRead; 263cdf0e10cSrcweir sal_uInt64 nOrgPos = 0; 264cdf0e10cSrcweir rInFile.getPos( nOrgPos ); 265cdf0e10cSrcweir 266cdf0e10cSrcweir while( bSuccess && ! bEof ) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir // read leading bytes 269cdf0e10cSrcweir bEof = ! rInFile.read( buffer, 6, nRead ) && nRead == 6 ? false : true; 270cdf0e10cSrcweir unsigned int nType = buffer[ 1 ]; 271cdf0e10cSrcweir unsigned int nBytesToRead = buffer[2] | buffer[3] << 8 | buffer[4] << 16 | buffer[5] << 24; 272cdf0e10cSrcweir if( buffer[0] != 0x80 ) // test for pfb m_agic number 273cdf0e10cSrcweir { 274cdf0e10cSrcweir // this migt be a pfa font already 275cdf0e10cSrcweir sal_uInt64 nWrite = 0; 276cdf0e10cSrcweir if( ! rInFile.read( buffer+6, 9, nRead ) && nRead == 9 && 277cdf0e10cSrcweir ( ! std::strncmp( (char*)buffer, "%!FontType1-", 12 ) || 278cdf0e10cSrcweir ! std::strncmp( (char*)buffer, "%!PS-AdobeFont-", 15 ) ) ) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir if( rOutFile.write( buffer, 15, nWrite ) || nWrite != 15 ) 281cdf0e10cSrcweir bSuccess = false; 282cdf0e10cSrcweir while( bSuccess && 283cdf0e10cSrcweir ! rInFile.read( buffer, sizeof( buffer ), nRead ) && 284cdf0e10cSrcweir nRead != 0 ) 285cdf0e10cSrcweir { 286cdf0e10cSrcweir if( rOutFile.write( buffer, nRead, nWrite ) || 287cdf0e10cSrcweir nWrite != nRead ) 288cdf0e10cSrcweir bSuccess = false; 289cdf0e10cSrcweir } 290cdf0e10cSrcweir bEof = true; 291cdf0e10cSrcweir } 292cdf0e10cSrcweir else 293cdf0e10cSrcweir bSuccess = false; 294cdf0e10cSrcweir } 295cdf0e10cSrcweir else if( nType == 1 || nType == 2 ) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir unsigned char* pBuffer = new unsigned char[ nBytesToRead+1 ]; 298cdf0e10cSrcweir 299cdf0e10cSrcweir if( ! rInFile.read( pBuffer, nBytesToRead, nRead ) && nRead == nBytesToRead ) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir if( nType == 1 ) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir // ascii data, convert dos lineends( \r\n ) and 304cdf0e10cSrcweir // m_ac lineends( \r ) to \n 305cdf0e10cSrcweir unsigned char * pWriteBuffer = new unsigned char[ nBytesToRead ]; 306cdf0e10cSrcweir unsigned int nBytesToWrite = 0; 307cdf0e10cSrcweir for( unsigned int i = 0; i < nBytesToRead; i++ ) 308cdf0e10cSrcweir { 309cdf0e10cSrcweir if( pBuffer[i] != '\r' ) 310cdf0e10cSrcweir pWriteBuffer[ nBytesToWrite++ ] = pBuffer[i]; 311cdf0e10cSrcweir else if( pBuffer[ i+1 ] == '\n' ) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir i++; 314cdf0e10cSrcweir pWriteBuffer[ nBytesToWrite++ ] = '\n'; 315cdf0e10cSrcweir } 316cdf0e10cSrcweir else 317cdf0e10cSrcweir pWriteBuffer[ nBytesToWrite++ ] = '\n'; 318cdf0e10cSrcweir } 319cdf0e10cSrcweir if( rOutFile.write( pWriteBuffer, nBytesToWrite, nRead ) || nRead != nBytesToWrite ) 320cdf0e10cSrcweir bSuccess = false; 321cdf0e10cSrcweir 322cdf0e10cSrcweir delete [] pWriteBuffer; 323cdf0e10cSrcweir } 324cdf0e10cSrcweir else 325cdf0e10cSrcweir { 326cdf0e10cSrcweir // binary data 327cdf0e10cSrcweir unsigned int nBuffer = 0; 328cdf0e10cSrcweir for( unsigned int i = 0; i < nBytesToRead && bSuccess; i++ ) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] >> 4 ]; 331cdf0e10cSrcweir buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] & 15 ]; 332cdf0e10cSrcweir if( nBuffer >= 80 ) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir buffer[ nBuffer++ ] = '\n'; 335cdf0e10cSrcweir if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer ) 336cdf0e10cSrcweir bSuccess = false; 337cdf0e10cSrcweir nBuffer = 0; 338cdf0e10cSrcweir } 339cdf0e10cSrcweir } 340cdf0e10cSrcweir if( nBuffer > 0 && bSuccess ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir buffer[ nBuffer++ ] = '\n'; 343cdf0e10cSrcweir if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer ) 344cdf0e10cSrcweir bSuccess = false; 345cdf0e10cSrcweir } 346cdf0e10cSrcweir } 347cdf0e10cSrcweir } 348cdf0e10cSrcweir else 349cdf0e10cSrcweir bSuccess = false; 350cdf0e10cSrcweir 351cdf0e10cSrcweir delete [] pBuffer; 352cdf0e10cSrcweir } 353cdf0e10cSrcweir else if( nType == 3 ) 354cdf0e10cSrcweir bEof = true; 355cdf0e10cSrcweir else 356cdf0e10cSrcweir bSuccess = false; 357cdf0e10cSrcweir } 358cdf0e10cSrcweir 359cdf0e10cSrcweir return bSuccess; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir void psp::normPath( OString& rPath ) 363cdf0e10cSrcweir { 364cdf0e10cSrcweir char buf[PATH_MAX]; 365cdf0e10cSrcweir 366cdf0e10cSrcweir ByteString aPath( rPath ); 367cdf0e10cSrcweir 368cdf0e10cSrcweir // double slashes and slash at end are probably 369cdf0e10cSrcweir // removed by realpath anyway, but since this runs 370cdf0e10cSrcweir // on many different platforms let's play it safe 371cdf0e10cSrcweir while( aPath.SearchAndReplace( "//", "/" ) != STRING_NOTFOUND ) 372cdf0e10cSrcweir ; 373cdf0e10cSrcweir if( aPath.Len() > 0 && aPath.GetChar( aPath.Len()-1 ) == '/' ) 374cdf0e10cSrcweir aPath.Erase( aPath.Len()-1 ); 375cdf0e10cSrcweir 376cdf0e10cSrcweir if( ( aPath.Search( "./" ) != STRING_NOTFOUND || 377cdf0e10cSrcweir aPath.Search( "~" ) != STRING_NOTFOUND ) 378cdf0e10cSrcweir && realpath( aPath.GetBuffer(), buf ) ) 379cdf0e10cSrcweir { 380cdf0e10cSrcweir rPath = buf; 381cdf0e10cSrcweir } 382cdf0e10cSrcweir else 383cdf0e10cSrcweir { 384cdf0e10cSrcweir rPath = aPath; 385cdf0e10cSrcweir } 386cdf0e10cSrcweir } 387cdf0e10cSrcweir 388cdf0e10cSrcweir void psp::splitPath( OString& rPath, OString& rDir, OString& rBase ) 389cdf0e10cSrcweir { 390cdf0e10cSrcweir normPath( rPath ); 391cdf0e10cSrcweir sal_Int32 nIndex = rPath.lastIndexOf( '/' ); 392cdf0e10cSrcweir if( nIndex > 0 ) 393cdf0e10cSrcweir rDir = rPath.copy( 0, nIndex ); 394cdf0e10cSrcweir else if( nIndex == 0 ) // root dir 395cdf0e10cSrcweir rDir = rPath.copy( 0, 1 ); 396cdf0e10cSrcweir if( rPath.getLength() > nIndex+1 ) 397cdf0e10cSrcweir rBase = rPath.copy( nIndex+1 ); 398cdf0e10cSrcweir } 399cdf0e10cSrcweir 400cdf0e10cSrcweir 401