| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_tools.hxx" |
| |
| |
| #if !defined UNX |
| #include <io.h> |
| #include <process.h> |
| #endif |
| |
| #if defined(UNX) || defined(OS2) |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #endif |
| |
| #include <ctype.h> |
| #include <errno.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <tools/debug.hxx> |
| #include <tools/list.hxx> |
| #include "comdep.hxx" |
| #include <tools/fsys.hxx> |
| #define _TOOLS_HXX |
| #include <tools/urlobj.hxx> |
| |
| #ifdef UNX |
| #define _MAX_PATH 260 |
| #endif |
| #include <tools/stream.hxx> |
| |
| #ifndef _VOS_MUTEX_HXX |
| #include <vos/mutex.hxx> |
| #endif |
| |
| #include <osl/file.hxx> |
| #include <rtl/instance.hxx> |
| |
| |
| using namespace osl; |
| using namespace rtl; |
| |
| int ApiRet2ToSolarError_Impl( int nApiRet ); |
| |
| //-------------------------------------------------------------------- |
| int Sys2SolarError_Impl( int nSysErr ) |
| { |
| switch ( nSysErr ) |
| { |
| #ifdef WNT |
| case NO_ERROR: return ERRCODE_NONE; |
| case ERROR_INVALID_FUNCTION: return ERRCODE_IO_GENERAL; |
| case ERROR_FILE_NOT_FOUND: return ERRCODE_IO_NOTEXISTS; |
| case ERROR_PATH_NOT_FOUND: return ERRCODE_IO_NOTEXISTSPATH; |
| case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES; |
| case ERROR_ACCESS_DENIED: return ERRCODE_IO_ACCESSDENIED; |
| case ERROR_INVALID_HANDLE: return ERRCODE_IO_GENERAL; |
| case ERROR_NOT_ENOUGH_MEMORY: return ERRCODE_IO_OUTOFMEMORY; |
| case ERROR_INVALID_BLOCK: return ERRCODE_IO_GENERAL; |
| // case ERROR_BAD_ENVIRONMENT: return ERRCODE_IO_; |
| case ERROR_BAD_FORMAT: return ERRCODE_IO_WRONGFORMAT; |
| case ERROR_INVALID_ACCESS: return ERRCODE_IO_ACCESSDENIED; |
| // case ERROR_INVALID_DATA: return ERRCODE_IO_; |
| case ERROR_INVALID_DRIVE: return ERRCODE_IO_INVALIDDEVICE; |
| case ERROR_CURRENT_DIRECTORY: return ERRCODE_IO_CURRENTDIR; |
| case ERROR_NOT_SAME_DEVICE: return ERRCODE_IO_NOTSAMEDEVICE; |
| // case ERROR_NO_MORE_FILES: return ERRCODE_IO_; |
| case ERROR_WRITE_PROTECT: return ERRCODE_IO_CANTWRITE; |
| case ERROR_BAD_UNIT: return ERRCODE_IO_INVALIDDEVICE; |
| case ERROR_NOT_READY: return ERRCODE_IO_DEVICENOTREADY; |
| case ERROR_BAD_COMMAND: return ERRCODE_IO_GENERAL; |
| case ERROR_CRC: return ERRCODE_IO_BADCRC; |
| case ERROR_BAD_LENGTH: return ERRCODE_IO_INVALIDLENGTH; |
| case ERROR_SEEK: return ERRCODE_IO_CANTSEEK; |
| case ERROR_NOT_DOS_DISK: return ERRCODE_IO_WRONGFORMAT; |
| case ERROR_SECTOR_NOT_FOUND: return ERRCODE_IO_GENERAL; |
| case ERROR_WRITE_FAULT: return ERRCODE_IO_CANTWRITE; |
| case ERROR_READ_FAULT: return ERRCODE_IO_CANTREAD; |
| case ERROR_GEN_FAILURE: return ERRCODE_IO_GENERAL; |
| case ERROR_SHARING_VIOLATION: return ERRCODE_IO_LOCKVIOLATION; |
| case ERROR_LOCK_VIOLATION: return ERRCODE_IO_LOCKVIOLATION; |
| case ERROR_WRONG_DISK: return ERRCODE_IO_INVALIDDEVICE; |
| case ERROR_NOT_SUPPORTED: return ERRCODE_IO_NOTSUPPORTED; |
| #else |
| case 0: return ERRCODE_NONE; |
| case ENOENT: return ERRCODE_IO_NOTEXISTS; |
| case EACCES: return ERRCODE_IO_ACCESSDENIED; |
| case EEXIST: return ERRCODE_IO_ALREADYEXISTS; |
| case EINVAL: return ERRCODE_IO_INVALIDPARAMETER; |
| case EMFILE: return ERRCODE_IO_TOOMANYOPENFILES; |
| case ENOMEM: return ERRCODE_IO_OUTOFMEMORY; |
| case ENOSPC: return ERRCODE_IO_OUTOFSPACE; |
| #endif |
| } |
| |
| DBG_TRACE1( "FSys: unknown system error %d occured", nSysErr ); |
| return FSYS_ERR_UNKNOWN; |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| #ifndef BOOTSTRAP |
| |
| FSysRedirector* FSysRedirector::_pRedirector = 0; |
| sal_Bool FSysRedirector::_bEnabled = sal_True; |
| #ifdef UNX |
| sal_Bool bInRedirection = sal_True; |
| #else |
| sal_Bool bInRedirection = sal_False; |
| #endif |
| static vos:: OMutex * pRedirectMutex = 0; |
| |
| //------------------------------------------------------------------------ |
| void FSysRedirector::Register( FSysRedirector *pRedirector ) |
| { |
| if ( pRedirector ) |
| pRedirectMutex = new vos:: OMutex ; |
| else |
| DELETEZ( pRedirectMutex ); |
| _pRedirector = pRedirector; |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| void FSysRedirector::DoRedirect( String &rPath ) |
| { |
| String aURL(rPath); |
| |
| // if redirection is disabled or not even registered do nothing |
| if ( !_bEnabled || !pRedirectMutex ) |
| return; |
| |
| // redirect only removable or remote volumes |
| if ( !IsRedirectable_Impl( ByteString( aURL, osl_getThreadTextEncoding() ) ) ) |
| return; |
| |
| // Redirection is acessible only by one thread per time |
| // dont move the guard behind the bInRedirection check!!! |
| // think of nested calls (when called from callback) |
| vos:: OGuard aGuard( pRedirectMutex ); |
| |
| // if already in redirection, dont redirect |
| if ( bInRedirection ) |
| return; |
| |
| // dont redirect on nested calls |
| bInRedirection = sal_True; |
| |
| // convert to URL |
| #ifndef UNX |
| for ( sal_Unicode *p = (sal_Unicode*)aURL.GetBuffer(); *p; ++p ) |
| if ( '\\' == *p ) *p = '/'; |
| else if ( ':' == *p ) *p = '|'; |
| #endif |
| |
| aURL.Insert( String("file:///", osl_getThreadTextEncoding()), 0 ); |
| |
| // do redirection |
| Redirector(); |
| |
| bInRedirection = sal_False; |
| return; |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| FSysRedirector* FSysRedirector::Redirector() |
| { |
| if ( !_pRedirector ) |
| Register( new FSysRedirector ); |
| return _pRedirector; |
| } |
| |
| #endif // BOOTSTRAP |
| |
| //-------------------------------------------------------------------- |
| |
| class DirEntryStack: public List |
| { |
| public: |
| DirEntryStack() {}; |
| ~DirEntryStack(); |
| |
| inline void Push( DirEntry *pEntry ); |
| inline DirEntry* Pop(); |
| inline DirEntry* Top(); |
| inline DirEntry* Bottom(); |
| }; |
| |
| inline void DirEntryStack::Push( DirEntry *pEntry ) |
| { |
| List::Insert( pEntry, LIST_APPEND ); |
| } |
| |
| inline DirEntry* DirEntryStack::Pop() |
| { |
| return (DirEntry*) List::Remove( Count() - 1 ); |
| } |
| |
| inline DirEntry* DirEntryStack::Top() |
| { |
| return (DirEntry*) List::GetObject( Count() - 1 ); |
| } |
| |
| inline DirEntry* DirEntryStack::Bottom() |
| { |
| return (DirEntry*) List::GetObject( 0 ); |
| } |
| |
| //-------------------------------------------------------------------- |
| |
| DBG_NAME( DirEntry ); |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::~DirEntryStack() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 04.07.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntryStack::~DirEntryStack() |
| { |
| while ( Count() ) |
| delete Pop(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* ImpCheckDirEntry() |
| |* |
| |* Beschreibung Pruefung eines DirEntry fuer DBG_UTIL |
| |* Parameter void* p Zeiger auf den DirEntry |
| |* Return-Wert char* Fehlermeldungs-TExtension oder NULL |
| |* Ersterstellung MI 16.07.91 |
| |* Letzte Aenderung MI 26.05.93 |
| |* |
| *************************************************************************/ |
| |
| #ifdef DBG_UTIL |
| const char* ImpCheckDirEntry( const void* p ) |
| { |
| DirEntry* p0 = (DirEntry*)p; |
| |
| if ( p0->pParent ) |
| DBG_CHKOBJ( p0->pParent, DirEntry, ImpCheckDirEntry ); |
| |
| return NULL; |
| } |
| #endif |
| |
| /************************************************************************* |
| |* |
| |* ImplCutPath() |
| |* |
| |* Beschreibung Fuegt ... ein, damit maximal nMaxChars lang |
| |* Ersterstellung MI 06.04.94 |
| |* Letzte Aenderung DV 24.06.96 |
| |* |
| *************************************************************************/ |
| |
| ByteString ImplCutPath( const ByteString& rStr, sal_uInt16 nMax, char cAccDel ) |
| { |
| sal_uInt16 nMaxPathLen = nMax; |
| ByteString aCutPath( rStr ); |
| sal_Bool bInsertPrefix = sal_False; |
| sal_uInt16 nBegin = aCutPath.Search( cAccDel ); |
| |
| if( nBegin == STRING_NOTFOUND ) |
| nBegin = 0; |
| else |
| nMaxPathLen += 2; // fuer Prefix <Laufwerk>: |
| |
| while( aCutPath.Len() > nMaxPathLen ) |
| { |
| sal_uInt16 nEnd = aCutPath.Search( cAccDel, nBegin + 1 ); |
| sal_uInt16 nCount; |
| |
| if ( nEnd != STRING_NOTFOUND ) |
| { |
| nCount = nEnd - nBegin; |
| aCutPath.Erase( nBegin, nCount ); |
| bInsertPrefix = sal_True; |
| } |
| else |
| break; |
| } |
| |
| if ( aCutPath.Len() > nMaxPathLen ) |
| { |
| for ( sal_uInt16 n = nMaxPathLen; n > nMaxPathLen/2; --n ) |
| if ( !ByteString(aCutPath.GetChar(n)).IsAlphaNumericAscii() ) |
| { |
| aCutPath.Erase( n ); |
| aCutPath += "..."; |
| break; |
| } |
| } |
| |
| if ( bInsertPrefix ) |
| { |
| ByteString aIns( cAccDel ); |
| aIns += "..."; |
| aCutPath.Insert( aIns, nBegin ); |
| } |
| |
| return aCutPath; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpParseOs2Name() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 23.06.95 |
| |* |
| *************************************************************************/ |
| |
| FSysError DirEntry::ImpParseOs2Name( const ByteString& rPfad, FSysPathStyle eStyle ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // die einzelnen Namen auf einen Stack packen |
| String aPfad( rPfad, osl_getThreadTextEncoding() ); |
| DirEntryStack aStack; |
| |
| do |
| { |
| // den Namen vor dem ersten "\\" abspalten, |
| // falls '\\' am Anfang, ist der Name '\\', |
| // der Rest immer ohne die fuehrenden '\\'. |
| // ein ":" trennt ebenfalls, gehoert aber zum Namen |
| // den ersten '\\', '/' oder ':' suchen |
| sal_uInt16 nPos; |
| for ( nPos = 0; |
| nPos < aPfad.Len() && //?O |
| aPfad.GetChar(nPos) != '\\' && aPfad.GetChar(nPos) != '/' && //?O |
| aPfad.GetChar(nPos) != ':'; //?O |
| nPos++ ) |
| /* do nothing */; |
| |
| // ist der Name ein UNC Pathname? |
| if ( nPos == 0 && aPfad.Len() > 1 && |
| ( ( aPfad.GetChar(0) == '\\' && aPfad.GetChar(1) == '\\' ) || |
| ( aPfad.GetChar(0) == '/' && aPfad.GetChar(1) == '/' ) ) ) |
| { |
| for ( nPos = 2; aPfad.Len() > nPos; ++nPos ) |
| if ( aPfad.GetChar(nPos) == '\\' || aPfad.GetChar(nPos) == '/' ) |
| break; |
| aName = ByteString( aPfad.Copy( 2, nPos-2 ), osl_getThreadTextEncoding() ); |
| aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) ); |
| } |
| // ist der Name die Root des aktuellen Drives? |
| else if ( nPos == 0 && aPfad.Len() > 0 && |
| ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) ) |
| { |
| // Root-Directory des aktuellen Drives |
| aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) ); |
| } |
| else |
| { |
| // ist der Name ein Drive? |
| if ( nPos < aPfad.Len() && aPfad.GetChar(nPos) == ':' ) |
| { |
| aName = ByteString( aPfad.Copy( 0, nPos + 1 ), osl_getThreadTextEncoding() ); |
| |
| // ist der Name die Root des Drives |
| if ( (nPos + 1) < aPfad.Len() && |
| ( aPfad.GetChar(nPos+1) == '\\' || aPfad.GetChar(nPos+1) == '/' ) ) |
| { |
| // schon was auf dem Stack? |
| // oder Novell-Format? (not supported wegen URLs) |
| if ( aStack.Count() || aName.Len() > 2 ) |
| { |
| aName = rPfad; |
| return FSYS_ERR_MISPLACEDCHAR; |
| } |
| // Root-Directory des Drive |
| aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) ); |
| } |
| else |
| { |
| // liegt ein anderes Drive auf dem Stack? |
| if ( aStack.Count() && |
| COMPARE_EQUAL != aStack.Bottom()->aName.CompareIgnoreCaseToAscii(aName) ) |
| aStack.Clear(); |
| |
| // liegt jetzt nichts mehr auf dem Stack? |
| if ( !aStack.Count() ) |
| aStack.Push( new DirEntry( aName, FSYS_FLAG_RELROOT, eStyle ) ); |
| } |
| } |
| |
| // es ist kein Drive |
| else |
| { |
| // den Namen ohne Trenner abspalten |
| aName = ByteString( aPfad.Copy( 0, nPos ), osl_getThreadTextEncoding() ); |
| |
| // stellt der Name die aktuelle Directory dar? |
| if ( aName == "." ) |
| /* do nothing */; |
| |
| // stellt der Name die Parent-Directory dar? |
| else if ( aName == ".." ) |
| { |
| // ist nichts, ein Parent oder eine relative Root |
| // auf dem Stack? |
| if ( ( aStack.Count() == 0 ) || |
| ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) || |
| ( aStack.Top()->eFlag == FSYS_FLAG_RELROOT ) ) |
| // fuehrende Parents kommen auf den Stack |
| aStack.Push( new DirEntry( FSYS_FLAG_PARENT ) ); |
| |
| // ist es eine absolute Root |
| else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT ) |
| { |
| // die hat keine Parent-Directory |
| aName = rPfad; |
| return FSYS_ERR_NOTEXISTS; |
| } |
| else |
| // sonst hebt der Parent den TOS auf |
| delete aStack.Pop(); |
| } |
| |
| else |
| { |
| if ( eStyle == FSYS_STYLE_FAT ) |
| { |
| // ist der Name grundsaetzlich ungueltig? |
| int nPunkte = 0; |
| const char *pChar; |
| for ( pChar = aName.GetBuffer(); |
| nPunkte < 2 && *pChar != 0; |
| pChar++ ) |
| { |
| if ( *pChar == ';' ) |
| nPunkte = 0; |
| else |
| nPunkte += ( *pChar == '.' ) ? 1 : 0; |
| } |
| if ( nPunkte > 1 ) |
| { |
| aName = rPfad; |
| return FSYS_ERR_MISPLACEDCHAR; |
| } |
| } |
| |
| // normalen Entries kommen auf den Stack |
| DirEntry *pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle ); |
| if ( !pNew->IsValid() ) |
| { |
| aName = rPfad; |
| ErrCode eErr = pNew->GetError(); |
| delete pNew; |
| return eErr; |
| } |
| aStack.Push( pNew ); |
| } |
| } |
| } |
| |
| // den Restpfad bestimmen |
| aPfad.Erase( 0, nPos + 1 ); |
| while ( aPfad.Len() && ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) ) |
| aPfad.Erase( 0, 1 ); |
| } |
| while ( aPfad.Len() ); |
| |
| sal_uIntPtr nErr = ERRCODE_NONE; |
| // Haupt-Entry (selbst) zuweisen |
| if ( aStack.Count() == 0 ) |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| aName.Erase(); |
| } |
| else |
| { |
| eFlag = aStack.Top()->eFlag; |
| aName = aStack.Top()->aName; |
| nErr = aStack.Top()->nError; |
| delete aStack.Pop(); |
| } |
| |
| // die Parent-Entries vom Stack holen |
| DirEntry** pTemp = &pParent; // Zeiger auf den Member pParent setzen |
| while ( aStack.Count() ) |
| { |
| *pTemp = aStack.Pop(); |
| |
| // Zeiger auf den Member pParent des eigenen Parent setzen |
| pTemp = &( (*pTemp)->pParent ); |
| } |
| |
| // wird damit ein Volume beschrieben? |
| if ( !pParent && eFlag == FSYS_FLAG_RELROOT && aName.Len() ) |
| eFlag = FSYS_FLAG_VOLUME; |
| |
| // bei gesetztem ErrorCode den Namen komplett "ubernehmen |
| if ( nErr ) |
| aName = rPfad; |
| return nErr; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpParseName() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.08.91 |
| |* Letzte Aenderung MI 26.05.93 |
| |* |
| *************************************************************************/ |
| |
| FSysError DirEntry::ImpParseName( const ByteString& rbInitName, |
| FSysPathStyle eStyle ) |
| { |
| String rInitName( rbInitName, osl_getThreadTextEncoding() ); |
| if ( eStyle == FSYS_STYLE_HOST ) |
| eStyle = DEFSTYLE; |
| |
| // KI-Division of FSys |
| if ( eStyle == FSYS_STYLE_DETECT ) |
| { |
| sal_Unicode cFirst = rInitName.GetChar(0); |
| if ( rInitName.Len() == 2 && rInitName.GetChar(1) == ':' && |
| ((cFirst >= 'A' && cFirst <= 'Z') || |
| (cFirst >= 'a' && cFirst <= 'z'))) |
| eStyle = FSYS_STYLE_HPFS; |
| else if ( rInitName.Len() > 2 && rInitName.GetChar(1) == ':' ) |
| { |
| if ( rInitName.Search( ':', 2 ) == STRING_NOTFOUND ) |
| eStyle = FSYS_STYLE_HPFS; |
| else |
| eStyle = FSYS_STYLE_MAC; |
| } |
| else if ( rInitName.Search( '/' ) != STRING_NOTFOUND ) |
| eStyle = FSYS_STYLE_BSD; |
| else if ( rInitName.Search( '\\' ) != STRING_NOTFOUND ) |
| eStyle = FSYS_STYLE_HPFS; |
| else if ( rInitName.Search( ':' ) != STRING_NOTFOUND ) |
| eStyle = FSYS_STYLE_MAC; |
| else |
| eStyle = FSYS_STYLE_HPFS; |
| } |
| |
| switch ( eStyle ) |
| { |
| case FSYS_STYLE_FAT: |
| case FSYS_STYLE_VFAT: |
| case FSYS_STYLE_HPFS: |
| case FSYS_STYLE_NTFS: |
| case FSYS_STYLE_NWFS: |
| return ImpParseOs2Name( rbInitName, eStyle ); |
| |
| case FSYS_STYLE_BSD: |
| case FSYS_STYLE_SYSV: |
| return ImpParseUnixName( rbInitName, eStyle ); |
| |
| case FSYS_STYLE_MAC: |
| return FSYS_ERR_OK; |
| |
| default: |
| return FSYS_ERR_UNKNOWN; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* GetStyle() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 15.11.91 |
| |* Letzte Aenderung MI 15.11.91 |
| |* |
| *************************************************************************/ |
| |
| static FSysPathStyle GetStyle( FSysPathStyle eStyle ) |
| { |
| if ( eStyle == FSYS_STYLE_HOST || eStyle == FSYS_STYLE_DETECT ) |
| return DEFSTYLE; |
| else |
| return eStyle; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpTrim() |
| |* |
| |* Beschreibung bringt den Namen auf Betriebssystem-Norm |
| |* z.B. 8.3 lower beim MS-DOS Formatter |
| |* wirkt nicht rekursiv |
| |* Ersterstellung MI 12.08.91 |
| |* Letzte Aenderung MI 21.05.92 |
| |* |
| *************************************************************************/ |
| |
| void DirEntry::ImpTrim( FSysPathStyle eStyle ) |
| { |
| // Wildcards werden nicht geclipt |
| if ( ( aName.Search( '*' ) != STRING_NOTFOUND ) || |
| ( aName.Search( '?' ) != STRING_NOTFOUND ) || |
| ( aName.Search( ';' ) != STRING_NOTFOUND ) ) |
| return; |
| |
| switch ( eStyle ) |
| { |
| case FSYS_STYLE_FAT: |
| { |
| sal_uInt16 nPunktPos = aName.Search( '.' ); |
| if ( nPunktPos == STRING_NOTFOUND ) |
| { |
| if ( aName.Len() > 8 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 8 ); |
| } |
| } |
| else |
| { |
| if ( nPunktPos > 8 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 8, nPunktPos - 8 ); |
| nPunktPos = 8; |
| } |
| if ( aName.Len() > nPunktPos + 3 ) |
| { |
| if ( aName.Len() - nPunktPos > 4 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( nPunktPos + 4 ); |
| } |
| } |
| } |
| aName.ToLowerAscii(); |
| break; |
| } |
| |
| case FSYS_STYLE_VFAT: |
| case FSYS_STYLE_HPFS: |
| case FSYS_STYLE_NTFS: |
| case FSYS_STYLE_NWFS: |
| if ( aName.Len() > 254 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 254 ); |
| } |
| |
| if ( eStyle == FSYS_STYLE_HPFS && |
| ( eFlag == FSYS_FLAG_ABSROOT || eFlag == FSYS_FLAG_RELROOT ) ) |
| aName.ToUpperAscii(); |
| break; |
| |
| case FSYS_STYLE_SYSV: |
| if ( aName.Len() > 14 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 14 ); |
| } |
| break; |
| |
| case FSYS_STYLE_BSD: |
| if ( aName.Len() > 250 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 250 ); |
| } |
| break; |
| |
| case FSYS_STYLE_MAC: |
| if ( eFlag & ( FSYS_FLAG_ABSROOT | FSYS_FLAG_VOLUME ) ) |
| { |
| if ( aName.Len() > 27 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 27 ); |
| } |
| } |
| else |
| { |
| if ( aName.Len() > 31 ) |
| { |
| nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK; |
| aName.Erase( 31 ); |
| } |
| } |
| break; |
| |
| default: |
| /* kann nicht sein */; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::DirEntry() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry::DirEntry( const ByteString& rName, DirEntryFlag eDirFlag, |
| FSysPathStyle eStyle ) : |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| pStat( 0 ), |
| #endif |
| aName( rName ) |
| { |
| DBG_CTOR( DirEntry, ImpCheckDirEntry ); |
| |
| pParent = NULL; |
| eFlag = eDirFlag; |
| nError = FSYS_ERR_OK; |
| |
| ImpTrim( eStyle ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::DirEntry() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry::DirEntry( const DirEntry& rOrig ) : |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| pStat( rOrig.pStat ? new FileStat(*rOrig.pStat) : 0 ), |
| #endif |
| aName( rOrig.aName ) |
| { |
| DBG_CTOR( DirEntry, ImpCheckDirEntry ); |
| |
| eFlag = rOrig.eFlag; |
| nError = rOrig.nError; |
| |
| if ( rOrig.pParent ) |
| { |
| pParent = new DirEntry( *rOrig.pParent ); |
| } |
| else |
| { |
| pParent = NULL; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::DirEntry() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry::DirEntry( const String& rInitName, FSysPathStyle eStyle ) |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| : pStat( 0 ) |
| #endif |
| { |
| DBG_CTOR( DirEntry, ImpCheckDirEntry ); |
| |
| pParent = NULL; |
| |
| // schnelle Loesung fuer Leerstring |
| if ( !rInitName.Len()) |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| nError = FSYS_ERR_OK; |
| return; |
| } |
| |
| ByteString aTmpName(rInitName, osl_getThreadTextEncoding()); |
| if( eStyle == FSYS_STYLE_URL || aTmpName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL ) |
| { |
| #ifndef BOOTSTRAP |
| DBG_WARNING( "File URLs are not permitted but accepted" ); |
| aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding()); |
| eStyle = FSYS_STYLE_HOST; |
| #endif // BOOTSTRAP |
| } |
| else |
| { |
| ::rtl::OUString aTmp; |
| ::rtl::OUString aOInitName; |
| if ( FileBase::getFileURLFromSystemPath( OUString( rInitName ), aTmp ) == FileBase::E_None ) |
| { |
| aOInitName = OUString( rInitName ); |
| aTmpName = ByteString( String(aOInitName), osl_getThreadTextEncoding() ); |
| } |
| |
| #ifdef DBG_UTIL |
| // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName() |
| if( eStyle == FSYS_STYLE_HOST && |
| aTmpName.Search( "://" ) != STRING_NOTFOUND ) |
| { |
| ByteString aErr = "DirEntries akzeptieren nur File URLS: "; |
| aErr += aTmpName; |
| DBG_WARNING( aErr.GetBuffer() ); |
| } |
| #endif |
| } |
| |
| nError = ImpParseName( aTmpName, eStyle ); |
| |
| if ( nError != FSYS_ERR_OK ) |
| eFlag = FSYS_FLAG_INVALID; |
| } |
| |
| /*************************************************************************/ |
| |
| DirEntry::DirEntry( const ByteString& rInitName, FSysPathStyle eStyle ) |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| : pStat( 0 ) |
| #endif |
| { |
| DBG_CTOR( DirEntry, ImpCheckDirEntry ); |
| |
| pParent = NULL; |
| |
| // schnelle Loesung fuer Leerstring |
| if ( !rInitName.Len() ) |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| nError = FSYS_ERR_OK; |
| return; |
| } |
| |
| ByteString aTmpName( rInitName ); |
| if( eStyle == FSYS_STYLE_URL || rInitName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL ) |
| { |
| #ifndef BOOTSTRAP |
| DBG_WARNING( "File URLs are not permitted but accepted" ); |
| aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding()); |
| eStyle = FSYS_STYLE_HOST; |
| #endif |
| } |
| #ifdef DBG_UTIL |
| else |
| // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName() |
| if( eStyle == FSYS_STYLE_HOST && |
| rInitName.Search( "://" ) != STRING_NOTFOUND ) |
| { |
| ByteString aErr = "DirEntries akzeptieren nur File URLS: "; |
| aErr += rInitName; |
| DBG_WARNING( aErr.GetBuffer() ); |
| } |
| #endif |
| |
| nError = ImpParseName( aTmpName, eStyle ); |
| |
| if ( nError != FSYS_ERR_OK ) |
| eFlag = FSYS_FLAG_INVALID; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::DirEntry() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry::DirEntry( DirEntryFlag eDirFlag ) |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| : pStat( 0 ) |
| #endif |
| { |
| DBG_CTOR( DirEntry, ImpCheckDirEntry ); |
| |
| eFlag = eDirFlag; |
| nError = ( eFlag == FSYS_FLAG_INVALID ) ? FSYS_ERR_UNKNOWN : FSYS_ERR_OK; |
| pParent = NULL; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::~DirEntry() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry::~DirEntry() |
| { |
| DBG_DTOR( DirEntry, ImpCheckDirEntry ); |
| |
| delete pParent; |
| #ifdef FEAT_FSYS_DOUBLESPEED |
| delete pStat; |
| #endif |
| |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpGetTopPtr() const |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| const DirEntry* DirEntry::ImpGetTopPtr() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const DirEntry *pTemp = this; |
| while ( pTemp->pParent ) |
| pTemp = pTemp->pParent; |
| |
| return pTemp; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpGetTopPtr() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 13.11.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry* DirEntry::ImpGetTopPtr() |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry *pTemp = this; |
| while ( pTemp->pParent ) |
| pTemp = pTemp->pParent; |
| |
| return pTemp; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpGetPreTopPtr() |
| |* |
| |* Beschreibung liefert einen Pointer auf den vorletzten Entry |
| |* Ersterstellung MI 01.11.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry* DirEntry::ImpGetPreTopPtr() |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry *pTemp = this; |
| if ( pTemp->pParent ) |
| { |
| while ( pTemp->pParent->pParent ) |
| pTemp = pTemp->pParent; |
| } |
| |
| return pTemp; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpChangeParent() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 21.05.92 |
| |* |
| *************************************************************************/ |
| |
| DirEntry* DirEntry::ImpChangeParent( DirEntry* pNewParent, sal_Bool bNormalize ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry *pTemp = pParent; |
| if ( bNormalize && pNewParent && |
| pNewParent->eFlag == FSYS_FLAG_RELROOT && !pNewParent->aName.Len() ) |
| { |
| pParent = 0; |
| delete pNewParent; |
| } |
| else |
| pParent = pNewParent; |
| |
| return pTemp; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::Exists() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 24.09.91 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::Exists( FSysAccess nAccess ) const |
| { |
| #ifndef BOOTSTRAP |
| static vos::OMutex aLocalMutex; |
| vos::OGuard aGuard( aLocalMutex ); |
| #endif |
| if ( !IsValid() ) |
| return sal_False; |
| |
| #if defined WNT || defined OS2 |
| // spezielle Filenamen sind vom System da |
| if ( ( aName.CompareIgnoreCaseToAscii("CLOCK$") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("CON") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("AUX") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("COM1") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("COM2") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("COM3") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("COM4") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("LPT1") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("LPT2") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("LPT3") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("NUL") == COMPARE_EQUAL || |
| aName.CompareIgnoreCaseToAscii("PRN") == COMPARE_EQUAL ) ) |
| return sal_True; |
| #endif |
| |
| FSysFailOnErrorImpl(); |
| DirEntryKind eKind = FileStat( *this, nAccess ).GetKind(); |
| if ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) ) |
| { |
| return sal_True; |
| } |
| |
| #if defined WNT || defined OS2 |
| if ( 0 != ( eKind & FSYS_KIND_DEV ) ) |
| { |
| return DRIVE_EXISTS( ImpGetTopPtr()->aName.GetChar(0) ); |
| } |
| #endif |
| |
| return 0 != ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::First() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 15.01.92 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::First() |
| { |
| FSysFailOnErrorImpl(); |
| |
| String aUniPathName( GetPath().GetFull() ); |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aUniPathName ); |
| ByteString aPathName(aUniPathName, osl_getThreadTextEncoding()); |
| #else |
| ByteString aPathName(aUniPathName, gsl_getSystemTextEncoding()); |
| #endif |
| aPathName = GUI2FSYS( aPathName ); |
| |
| DIR *pDir = opendir( (char*) aPathName.GetBuffer() ); |
| if ( pDir ) |
| { |
| #ifndef BOOTSTRAP |
| WildCard aWildeKarte( String(CMP_LOWER( aName ), osl_getThreadTextEncoding()) ); |
| #else |
| WildCard aWildeKarte( String(CMP_LOWER( aName ), gsl_getSystemTextEncoding()) ); |
| #endif |
| for ( dirent* pEntry = readdir( pDir ); |
| pEntry; |
| pEntry = readdir( pDir ) ) |
| { |
| ByteString aFound( FSYS2GUI( ByteString( pEntry->d_name ) ) ); |
| if ( aWildeKarte.Matches( String(CMP_LOWER( aFound ), osl_getThreadTextEncoding()))) |
| { |
| aName = aFound; |
| closedir( pDir ); |
| return sal_True; |
| } |
| } |
| closedir( pDir ); |
| } |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetFull() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetFull( FSysPathStyle eStyle, sal_Bool bWithDelimiter, |
| sal_uInt16 nMaxChars ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| ByteString aRet; |
| eStyle = GetStyle( eStyle ); |
| if ( pParent ) |
| { |
| if ( ( pParent->eFlag == FSYS_FLAG_ABSROOT || |
| pParent->eFlag == FSYS_FLAG_RELROOT || |
| pParent->eFlag == FSYS_FLAG_VOLUME ) ) |
| { |
| aRet = ByteString(pParent->GetName( eStyle ), osl_getThreadTextEncoding()); |
| aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding()); |
| } |
| else |
| { |
| aRet = ByteString(pParent->GetFull( eStyle ), osl_getThreadTextEncoding()); |
| aRet += ACCESSDELIM_C(eStyle); |
| aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding()); |
| } |
| } |
| else |
| { |
| aRet = ByteString(GetName( eStyle ), osl_getThreadTextEncoding()); |
| } |
| |
| if ( ( eStyle == FSYS_STYLE_MAC ) && |
| ( ImpGetTopPtr()->eFlag != FSYS_FLAG_VOLUME ) && |
| ( ImpGetTopPtr()->eFlag != FSYS_FLAG_ABSROOT ) && |
| ( aRet.GetChar(0) != ':' ) ) |
| aRet.Insert( ACCESSDELIM_C(eStyle), 0 ); |
| |
| //! Hack |
| if ( bWithDelimiter ) |
| if ( aRet.GetChar( aRet.Len()-1 ) != ACCESSDELIM_C(eStyle) ) |
| aRet += ACCESSDELIM_C(eStyle); |
| |
| //! noch ein Hack |
| if ( nMaxChars < STRING_MAXLEN ) |
| aRet = ImplCutPath( aRet, nMaxChars, ACCESSDELIM_C(eStyle) ); |
| |
| return String(aRet, osl_getThreadTextEncoding()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetPath() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry DirEntry::GetPath() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( pParent ) |
| return DirEntry( *pParent ); |
| |
| return DirEntry(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetExtension() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetExtension( char cSep ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const char *p0 = ( aName.GetBuffer() ); |
| const char *p1 = p0 + aName.Len() - 1; |
| while ( p1 >= p0 && *p1 != cSep ) |
| p1--; |
| |
| if ( p1 >= p0 ) |
| // es wurde ein cSep an der Position p1 gefunden |
| return String( |
| aName.Copy( static_cast< xub_StrLen >(p1 - p0 + 1) ), |
| osl_getThreadTextEncoding()); |
| return String(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetBase() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetBase( char cSep ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const char *p0 = ( aName.GetBuffer() ); |
| const char *p1 = p0 + aName.Len() - 1; |
| while ( p1 >= p0 && *p1 != cSep ) |
| p1--; |
| |
| if ( p1 >= p0 ) |
| // es wurde ein cSep an der Position p1 gefunden |
| return String( |
| aName.Copy( 0, static_cast< xub_StrLen >(p1 - p0) ), |
| osl_getThreadTextEncoding()); |
| |
| else |
| // es wurde kein cSep gefunden |
| return String(aName, osl_getThreadTextEncoding()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetName() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 13:47 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetName( FSysPathStyle eStyle ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| ByteString aRet; |
| eStyle = GetStyle( eStyle ); |
| |
| switch( eFlag ) |
| { |
| case FSYS_FLAG_PARENT: |
| aRet = ACTPARENT(eStyle); |
| break; |
| |
| case FSYS_FLAG_ABSROOT: |
| { |
| if ( eStyle == FSYS_STYLE_URL ) |
| { |
| aRet = "file:///"; |
| aRet += aName; |
| |
| #ifndef UNX |
| if ( aName.Len()) |
| { |
| if ( aName.GetChar(aName.Len()-1) == ':' ) |
| { |
| aRet.SetChar(aRet.Len()-1, '|'); |
| } |
| else |
| { |
| aRet.Insert( '/', 5 ); |
| } |
| aRet += "/"; |
| } |
| #endif |
| } |
| else if ( eStyle != FSYS_STYLE_MAC && |
| aName.Len() > 1 && aName.GetChar( 1 ) != ':' ) |
| { |
| // UNC-Pathname |
| aRet = ACCESSDELIM_C(eStyle); |
| aRet += ACCESSDELIM_C(eStyle); |
| aRet += aName ; |
| aRet += ACCESSDELIM_C(eStyle); |
| } |
| else |
| { |
| aRet = aName; |
| aRet += ACCESSDELIM_C(eStyle); |
| } |
| break; |
| } |
| |
| case FSYS_FLAG_INVALID: |
| case FSYS_FLAG_VOLUME: |
| { |
| if ( eStyle == FSYS_STYLE_URL ) |
| { |
| aRet = "file:///"; |
| aRet += aName; |
| #ifndef UNX |
| if ( aName.Len() && aName.GetChar(aName.Len()-1) == ':' ) |
| { |
| aRet.SetChar(aRet.Len()-1, '|'); |
| } |
| #endif |
| } |
| else |
| { |
| aRet = aName; |
| } |
| |
| break; |
| } |
| |
| case FSYS_FLAG_RELROOT: |
| if ( !aName.Len() ) |
| { |
| aRet = ACTCURRENT(eStyle); |
| break; |
| } |
| |
| default: |
| aRet = aName; |
| } |
| |
| return String(aRet, osl_getThreadTextEncoding()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::IsAbs() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| bool DirEntry::IsAbs() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| #ifdef UNX |
| return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT ); |
| #else |
| return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT && aName.Len() > 0 ); |
| #endif |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::CutName() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::CutName( FSysPathStyle eStyle ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| eStyle = GetStyle( eStyle ); |
| |
| String aOldName( GetName( eStyle ) ); |
| |
| if ( pParent ) |
| { |
| DirEntry *pOldParent = pParent; |
| if ( pOldParent ) |
| { |
| pParent = pOldParent->pParent; |
| eFlag = pOldParent->eFlag; |
| aName = pOldParent->aName; |
| pOldParent->pParent = NULL; |
| delete pOldParent; |
| } |
| else |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| aName.Erase(); |
| } |
| } |
| else |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| aName.Erase(); |
| delete pParent; |
| pParent = NULL; |
| } |
| |
| return aOldName; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::NameCompare |
| |* |
| |* Beschreibung Vergleich nur die Namen (ohne Pfad, aber mit Gross/Klein) |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| StringCompare DirEntry::NameCompare( const DirEntry &rWith ) const |
| { |
| ByteString aThisName; |
| ByteString aParameterName; |
| |
| #ifdef UNX |
| aThisName = aName; |
| aParameterName = rWith.aName; |
| #else |
| aThisName = ByteString(aName).ToLowerAscii(); |
| aParameterName = ByteString(rWith.aName).ToLowerAscii(); |
| #endif |
| |
| return aThisName.CompareTo( aParameterName ); |
| } |
| |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::operator==() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::operator==( const DirEntry& rEntry ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // test wheather the contents are textual the same |
| |
| if ( nError && ( nError == rEntry.nError ) ) |
| return sal_True; |
| if ( nError || rEntry.nError || |
| ( eFlag == FSYS_FLAG_INVALID ) || |
| ( rEntry.eFlag == FSYS_FLAG_INVALID ) ) |
| return sal_False; |
| |
| #ifndef OS2 |
| const |
| #endif |
| DirEntry *pThis = (DirEntry *)this; |
| #ifndef OS2 |
| const |
| #endif |
| DirEntry *pWith = (DirEntry *)&rEntry; |
| while( pThis && pWith && (pThis->eFlag == pWith->eFlag) ) |
| { |
| if ( CMP_LOWER(pThis->aName) != CMP_LOWER(pWith->aName) ) |
| break; |
| pThis = pThis->pParent; |
| pWith = pWith->pParent; |
| } |
| |
| return ( !pThis && !pWith ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::operator=() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry& DirEntry::operator=( const DirEntry& rEntry ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( this == &rEntry ) |
| return *this; |
| if ( rEntry.nError != FSYS_ERR_OK ) { |
| DBG_ERROR("Zuweisung mit invalidem DirEntry"); |
| nError = rEntry.nError; |
| return *this; |
| } |
| |
| // Name und Typ uebernehmen, Refs beibehalten |
| aName = rEntry.aName; |
| eFlag = rEntry.eFlag; |
| nError = FSYS_ERR_OK; |
| |
| DirEntry *pOldParent = pParent; |
| if ( rEntry.pParent ) |
| pParent = new DirEntry( *rEntry.pParent ); |
| else |
| pParent = NULL; |
| |
| if ( pOldParent ) |
| delete pOldParent; |
| return *this; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::operator+() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry DirEntry::operator+( const DirEntry& rEntry ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| #ifdef DBG_UTIL |
| static sal_Bool bTested = sal_False; |
| if ( !bTested ) |
| { |
| bTested = sal_True; |
| FSysTest(); |
| } |
| #endif |
| |
| const DirEntry *pEntryTop = rEntry.ImpGetTopPtr(); |
| const DirEntry *pThisTop = ImpGetTopPtr(); |
| |
| // "." + irgendwas oder irgendwas + "d:irgendwas" |
| /* TPF:org |
| if ( ( eFlag == FSYS_FLAG_RELROOT && !aName ) || |
| ( pEntryTop->aName.Len() && |
| ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT || |
| pEntryTop->eFlag == FSYS_FLAG_RELROOT || |
| pEntryTop->eFlag == FSYS_FLAG_VOLUME ) ) ) |
| return rEntry; |
| */ |
| |
| if ( |
| (eFlag == FSYS_FLAG_RELROOT && !aName.Len()) || |
| ( |
| (pEntryTop->aName.Len() || |
| ((rEntry.Level()>1)?(rEntry[rEntry.Level()-2].aName.CompareIgnoreCaseToAscii(RFS_IDENTIFIER)==COMPARE_EQUAL):sal_False)) |
| && |
| (pEntryTop->eFlag == FSYS_FLAG_ABSROOT || |
| pEntryTop->eFlag == FSYS_FLAG_RELROOT || |
| pEntryTop->eFlag == FSYS_FLAG_VOLUME) |
| ) |
| ) |
| { |
| return rEntry; |
| } |
| |
| // irgendwas + "." (=> pEntryTop == &rEntry) |
| if ( pEntryTop->eFlag == FSYS_FLAG_RELROOT && !pEntryTop->aName.Len() ) |
| { |
| DBG_ASSERT( pEntryTop == &rEntry, "DirEntry::op+ buggy" ); |
| return *this; |
| } |
| |
| // root += ".." (=> unmoeglich) |
| if ( pEntryTop->eFlag == FSYS_FLAG_PARENT && pThisTop == this && |
| ( eFlag == FSYS_FLAG_ABSROOT ) ) |
| return DirEntry( FSYS_FLAG_INVALID ); |
| |
| // irgendwas += abs (=> nur Device uebernehmen falls vorhanden) |
| if ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT ) |
| { |
| ByteString aDevice; |
| if ( pThisTop->eFlag == FSYS_FLAG_ABSROOT ) |
| aDevice = pThisTop->aName; |
| DirEntry aRet = rEntry; |
| if ( aDevice.Len() ) |
| aRet.ImpGetTopPtr()->aName = aDevice; |
| return aRet; |
| } |
| |
| // irgendwas += ".." (=> aufloesen) |
| if ( eFlag == FSYS_FLAG_NORMAL && pEntryTop->eFlag == FSYS_FLAG_PARENT ) |
| { |
| String aConcated( GetFull() ); |
| aConcated += ACCESSDELIM_C(FSYS_STYLE_HOST); |
| aConcated += rEntry.GetFull(); |
| return DirEntry( aConcated ); |
| } |
| |
| // sonst einfach hintereinander haengen |
| DirEntry aRet( rEntry ); |
| DirEntry *pTop = aRet.ImpGetTopPtr(); |
| pTop->pParent = new DirEntry( *this ); |
| |
| return aRet; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::operator+=() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| DirEntry &DirEntry::operator+=( const DirEntry& rEntry ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| return *this = *this + rEntry; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetAccessDelimiter() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 27.05.93 |
| |* Letzte Aenderung MI 10.06.93 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetAccessDelimiter( FSysPathStyle eFormatter ) |
| { |
| return String( ACCESSDELIM_C( GetStyle( eFormatter ) ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::SetExtension() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 02.08.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| void DirEntry::SetExtension( const String& rExtension, char cSep ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // do not set extensions for drives |
| if(eFlag == FSYS_FLAG_ABSROOT) |
| { |
| nError = FSYS_ERR_NOTSUPPORTED; |
| return; |
| } |
| |
| // cSep im Namen suchen |
| const char *p0 = ( aName.GetBuffer() ); |
| const char *p1 = p0 + aName.Len() - 1; |
| while ( p1 >= p0 && *p1 != cSep ) |
| p1--; |
| if ( p1 >= p0 ) |
| { |
| // es wurde ein cSep an der Position p1 gefunden |
| aName.Erase( |
| static_cast< xub_StrLen >( |
| p1 - p0 + 1 - ( rExtension.Len() ? 0 : 1 )) ); |
| aName += ByteString(rExtension, osl_getThreadTextEncoding()); |
| } |
| else if ( rExtension.Len() ) |
| { |
| // es wurde kein cSep gefunden |
| aName += cSep; |
| aName += ByteString(rExtension, osl_getThreadTextEncoding()); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::CutExtension() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 23.07.93 |
| |* Letzte Aenderung MI 23.07.93 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::CutExtension( char cSep ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const char *p0 = ( aName.GetBuffer() ); |
| const char *p1 = p0 + aName.Len() - 1; |
| while ( p1 >= p0 && *p1 != cSep ) |
| p1--; |
| |
| if ( p1 >= p0 ) |
| { |
| // es wurde ein cSep an der Position p1 gefunden |
| aName.Erase( static_cast< xub_StrLen >(p1-p0) ); |
| return String(p1 + 1, osl_getThreadTextEncoding()); |
| } |
| |
| return String(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::SetName() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 04.09.93 |
| |* Letzte Aenderung MI 04.09.93 |
| |* |
| *************************************************************************/ |
| |
| void DirEntry::SetName( const String& rName, FSysPathStyle eFormatter ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( eFormatter == FSYS_STYLE_HOST || eFormatter == FSYS_STYLE_DETECT ) |
| eFormatter = DEFSTYLE; |
| ByteString aAccDelim( ACCESSDELIM_C( eFormatter ) ); |
| |
| if ( (eFlag != FSYS_FLAG_NORMAL) || |
| (aName.Search( ':' ) != STRING_NOTFOUND) || |
| (aName.Search( aAccDelim ) != STRING_NOTFOUND) || |
| (eFormatter == FSYS_STYLE_FAT && (aName.GetTokenCount( '.' ) > 2) ) ) |
| { |
| eFlag = FSYS_FLAG_INVALID; |
| } |
| else |
| { |
| aName = ByteString(rName, osl_getThreadTextEncoding()); |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::Find() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| sal_Bool DirEntry::Find( const String& rPfad, char cDelim ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( ImpGetTopPtr()->eFlag == FSYS_FLAG_ABSROOT ) |
| return sal_True; |
| |
| sal_Bool bWild = aName.Search( '*' ) != STRING_NOTFOUND || |
| aName.Search( '?' ) != STRING_NOTFOUND; |
| if ( !cDelim ) |
| cDelim = SEARCHDELIM(DEFSTYLE)[0]; |
| |
| sal_uInt16 nTokenCount = rPfad.GetTokenCount( cDelim ); |
| sal_uInt16 nIndex = 0; |
| ByteString aThis = ACCESSDELIM(DEFSTYLE); |
| aThis += ByteString(GetFull(), osl_getThreadTextEncoding()); |
| for ( sal_uInt16 nToken = 0; nToken < nTokenCount; ++nToken ) |
| { |
| ByteString aPath = ByteString(rPfad, osl_getThreadTextEncoding()).GetToken( 0, cDelim, nIndex ); |
| |
| if ( aPath.Len() ) |
| { |
| if (aPath.GetChar(aPath.Len()-1)== ACCESSDELIM(DEFSTYLE)[0]) |
| aPath.Erase(aPath.Len()-1); |
| aPath += aThis; |
| DirEntry aEntry( String(aPath, osl_getThreadTextEncoding())); |
| if ( aEntry.ToAbs() && |
| ( ( !bWild && aEntry.Exists() ) || ( bWild && aEntry.First() ) ) ) |
| { |
| (*this) = aEntry; |
| return sal_True; |
| } |
| } |
| } |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpToRel() |
| |* |
| |* Beschreibung |
| |* Ersterstellung MI 17.06.93 |
| |* Letzte Aenderung MI 17.06.93 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::ImpToRel( String aCurStr ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry aThis(*this); |
| aThis.ToAbs(); |
| String aThisStr( aThis.GetFull( FSYS_STYLE_HPFS ) ); |
| |
| // #109512 preserve case of path even if caseinsensitive |
| String aThisCompareStr( aThisStr ), aCurCompareStr( aCurStr ); |
| if ( ! IsCaseSensitive() ) |
| { |
| aThisCompareStr.ToLowerAscii(); |
| aCurCompareStr.ToLowerAscii(); |
| } |
| |
| // "Ubereinstimmung pr"ufen |
| sal_uInt16 nPos = aThisCompareStr.Match( aCurCompareStr ); |
| if ( nPos == STRING_MATCH && aThisStr.Len() != aCurStr.Len() ) |
| nPos = Min( aThisStr.Len(), aCurStr.Len() ); |
| |
| // Sonderfall, die DirEntries sind identisch |
| if ( nPos == STRING_MATCH ) |
| { |
| // dann ist der relative Pfad das aktuelle Verzeichnis |
| *this = DirEntry(); |
| return sal_True; |
| } |
| |
| // Sonderfall, die DirEntries sind total verschieden |
| if ( nPos == 0 ) |
| { |
| // dann ist der relativste Pfad absolut |
| *this = aThis; |
| return sal_False; |
| } |
| |
| // sonst nehmen wir die identischen Einzelteile vorne weg |
| while ( nPos > 0 && aThisStr.GetChar(nPos) != '\\' ) |
| --nPos; |
| aThisStr.Erase( 0, nPos + ( ( aThisStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) ); |
| aCurStr.Erase( 0, nPos + ( ( aCurStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) ); |
| |
| // und fuellen mit dem Level der Directories auf |
| for ( nPos = 0; nPos < aCurStr.Len(); ++nPos ) |
| if ( aCurStr.GetChar(nPos) == '\\' ) |
| aThisStr.Insert( String( "..\\", osl_getThreadTextEncoding() ), 0 ); |
| |
| // das ist dann unser relativer Pfad |
| *this = DirEntry( aThisStr, FSYS_STYLE_HPFS ); |
| return sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::CutRelParents() |
| |* |
| |* Beschreibung |
| |* Ersterstellung MI 01.08.95 |
| |* Letzte Aenderung MI 01.08.95 |
| |* |
| *************************************************************************/ |
| |
| sal_uInt16 DirEntry::CutRelParents() |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // erstes '..' finden |
| DirEntry *pDir = 0; |
| DirEntry *pPar; |
| |
| for ( pPar = this; |
| pPar && pPar->eFlag != FSYS_FLAG_PARENT; |
| pPar = pPar->pParent ) |
| pDir = pPar; |
| |
| // '..' zaehlen |
| sal_uInt16 nParCount = 0; |
| while ( pPar && pPar->eFlag == FSYS_FLAG_PARENT ) |
| { |
| ++nParCount; |
| pPar = pPar->pParent; |
| } |
| |
| // cutten |
| if ( pDir ) |
| DELETEZ(pDir->pParent); |
| else |
| eFlag = FSYS_FLAG_CURRENT; |
| |
| return nParCount; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ToRel() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.06.93 |
| |* Letzte Aenderung MI 17.06.93 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::ToRel() |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry aCur; |
| aCur.ToAbs(); |
| return ImpToRel( aCur.GetFull( FSYS_STYLE_HPFS ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ToRel() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::ToRel( const DirEntry& rStart ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| DirEntry aStart( rStart ); |
| aStart.ToAbs(); |
| return ImpToRel( aStart.GetFull( FSYS_STYLE_HPFS ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetDevice() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| #ifndef UNX |
| |
| DirEntry DirEntry::GetDevice() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const DirEntry *pTop = ImpGetTopPtr(); |
| |
| if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || pTop->eFlag == FSYS_FLAG_RELROOT ) && |
| pTop->aName.Len() ) |
| return DirEntry( pTop->aName, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST ); |
| else |
| return DirEntry( ByteString(), FSYS_FLAG_INVALID, FSYS_STYLE_HOST ); |
| } |
| |
| #endif |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::SetBase() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 23.10.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| void DirEntry::SetBase( const String& rBase, char cSep ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| const char *p0 = ( aName.GetBuffer() ); |
| const char *p1 = p0 + aName.Len() - 1; |
| while ( p1 >= p0 && *p1 != cSep ) |
| p1--; |
| |
| if ( p1 >= p0 ) |
| { |
| // es wurde ein cSep an der Position p1 gefunden |
| aName.Erase( 0, static_cast< xub_StrLen >(p1 - p0) ); |
| aName.Insert( ByteString(rBase, osl_getThreadTextEncoding()), 0 ); |
| } |
| else |
| aName = ByteString(rBase, osl_getThreadTextEncoding()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetSearchDelimiter() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 10.06.93 |
| |* Letzte Aenderung MI 10.06.93 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::GetSearchDelimiter( FSysPathStyle eFormatter ) |
| { |
| return String( ByteString(SEARCHDELIM( GetStyle( eFormatter ) ) ), osl_getThreadTextEncoding()); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::GetMaxNameLen() |
| |* |
| |* Beschreibung Liefert die maximale Anzahl von Zeichen in |
| |* einzelnen Namensteile. Bei FileSystmen mit |
| |* fester Extension (FAT) zaehlt diese nicht mit. |
| |* Bei unbekannten FileSytemen und FSYS_STYLE_URL |
| |* wird USHRT_MAX zurueckgegeben. |
| |* Ersterstellung MI 17.06.97 |
| |* Letzte Aenderung MI 17.06.97 |
| |* |
| *************************************************************************/ |
| |
| sal_uInt16 DirEntry::GetMaxNameLen( FSysPathStyle eFormatter ) |
| { |
| eFormatter = GetStyle( eFormatter ); |
| switch ( eFormatter ) |
| { |
| case FSYS_STYLE_MAC: return 31; |
| |
| case FSYS_STYLE_FAT: return 8; |
| |
| case FSYS_STYLE_VFAT: |
| case FSYS_STYLE_NTFS: |
| case FSYS_STYLE_NWFS: |
| case FSYS_STYLE_HPFS: return 255; |
| |
| |
| case FSYS_STYLE_SYSV: return 14; |
| |
| case FSYS_STYLE_BSD: return 250; |
| |
| default: |
| return USHRT_MAX; |
| } |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::TempName() |
| |* |
| |* Beschreibung FSYS.SDW - Aha, wo? |
| |* Ersterstellung VB 06.09.93 (im SWG) |
| |* Letzte Aenderung MI 06.02.98 |
| |* |
| *************************************************************************/ |
| namespace { struct TempNameBase_Impl : public rtl::Static< DirEntry, TempNameBase_Impl > {}; } |
| |
| const DirEntry& DirEntry::SetTempNameBase( const String &rBase ) |
| { |
| DirEntry aTempDir = DirEntry().TempName().GetPath(); |
| aTempDir += DirEntry( rBase ); |
| #ifdef UNX |
| ByteString aName( aTempDir.GetFull(), osl_getThreadTextEncoding()); |
| if ( access( aName.GetBuffer(), W_OK | X_OK | R_OK ) ) |
| { |
| // Create the directory and only on success give all rights to |
| // everyone. Use mkdir instead of DirEntry::MakeDir because |
| // this returns sal_True even if directory already exists. |
| |
| if ( !mkdir( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO ) ) |
| chmod( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO ); |
| |
| // This will not create a directory but perhaps FileStat called |
| // there modifies the DirEntry |
| |
| aTempDir.MakeDir(); |
| } |
| #else |
| aTempDir.MakeDir(); |
| #endif |
| DirEntry &rEntry = TempNameBase_Impl::get(); |
| rEntry = aTempDir.TempName( FSYS_KIND_DIR ); |
| return rEntry; |
| } |
| |
| DirEntry DirEntry::TempName( DirEntryKind eKind ) const |
| { |
| // ggf. Base-Temp-Dir verwenden (macht Remote keinen Sinn => vorher) |
| const DirEntry &rEntry = TempNameBase_Impl::get(); |
| if ( !pParent && FSYS_FLAG_CURRENT != rEntry.eFlag && FSYS_FLAG_ABSROOT != eFlag ) |
| |
| { |
| DirEntry aFactory( rEntry ); |
| aFactory += GetName(); |
| return aFactory.TempName(); |
| } |
| |
| ByteString aDirName; // hiermit hatte MPW C++ Probleme - immmer noch?? |
| char *ret_val; |
| size_t i; |
| |
| // dertermine Directory, Prefix and Extension |
| char pfx[6]; |
| char ext[5]; |
| const char *dir; |
| const char *pWild = strchr( aName.GetBuffer(), '*' ); |
| if ( !pWild ) |
| pWild = strchr( aName.GetBuffer(), '?' ); |
| |
| if ( pWild ) |
| { |
| if ( pParent ) |
| aDirName = ByteString(pParent->GetFull(), osl_getThreadTextEncoding()); |
| strncpy( pfx, aName.GetBuffer(), Min( (int)5, (int)(pWild-aName.GetBuffer()) ) ); |
| pfx[ pWild-aName.GetBuffer() ] = 0; |
| const char *pExt = strchr( pWild, '.' ); |
| if ( pExt ) |
| { |
| strncpy( ext, pExt, 4 ); |
| ext[4] = 0; |
| } |
| else |
| strcpy( ext, ".tmp" ); |
| } |
| else |
| { |
| aDirName = ByteString(GetFull(), osl_getThreadTextEncoding()); |
| strcpy( pfx, "sv" ); |
| strcpy( ext, ".tmp" ); |
| } |
| dir = aDirName.GetBuffer(); |
| |
| // wurde kein Dir angegeben, dann nehmen wir ein passendes TEMP-Verz. |
| char sBuf[_MAX_PATH]; |
| if ( eFlag == FSYS_FLAG_CURRENT || ( !pParent && pWild ) ) |
| dir = TempDirImpl(sBuf); |
| |
| // ab hier leicht modifizierter Code von VB |
| DirEntry aRet(FSYS_FLAG_INVALID); |
| i = strlen(dir); |
| // need to add ?\\? + prefix + number + pid + .ext + '\0' |
| # define TMPNAME_SIZE ( 1 + 5 + 5 + 10 + 4 + 1 ) |
| ret_val = new char[i + TMPNAME_SIZE ]; |
| if (ret_val) |
| { |
| strcpy(ret_val,dir); |
| |
| /* Make sure directory ends with a separator */ |
| #if defined(WNT) || defined(OS2) |
| if ( i>0 && ret_val[i-1] != '\\' && ret_val[i-1] != '/' && |
| ret_val[i-1] != ':') |
| ret_val[i++] = '\\'; |
| #elif defined UNX |
| if (i>0 && ret_val[i-1] != '/') |
| ret_val[i++] = '/'; |
| #else |
| #error unknown operating system |
| #endif |
| |
| strncpy(ret_val + i, pfx, 5); |
| ret_val[i + 5] = '\0'; /* strncpy doesn't put a 0 if more */ |
| i = strlen(ret_val); /* than 'n' chars. */ |
| |
| /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576 |
| * Welcome to the 21st century, we can have longer filenames now ;) |
| * New format: pfx + "5 char milli/micro second res" + "current pid" + ".tmp" |
| */ |
| #if (defined MSC || defined __MINGW32__) && defined WNT |
| /* Milliseconds !! */ |
| static unsigned long u = GetTickCount(); |
| unsigned long mypid = static_cast<unsigned long>(_getpid()); |
| #else |
| /* Microseconds !! */ |
| static unsigned long u = clock(); |
| unsigned long mypid = static_cast<unsigned long>(getpid()); |
| #endif |
| for ( unsigned long nOld = u; ++u != nOld; ) /* Hae??? */ |
| { |
| u %= 100000; /* on *NIX repeats every 100ms, maybe less if CLOCKS_PER_SEC > 10^6 */ |
| snprintf(ret_val+i, TMPNAME_SIZE, "%05lu%lu", u, mypid); |
| |
| strcat(ret_val,ext); |
| |
| if ( FSYS_KIND_FILE == eKind ) |
| { |
| SvFileStream aStream( String( ret_val, osl_getThreadTextEncoding()), |
| STREAM_WRITE|STREAM_SHARE_DENYALL ); |
| if ( aStream.IsOpen() ) |
| { |
| aStream.Seek( STREAM_SEEK_TO_END ); |
| if ( 0 == aStream.Tell() ) |
| { |
| aRet = DirEntry( String( ret_val, osl_getThreadTextEncoding())); |
| break; |
| } |
| aStream.Close(); |
| } |
| } |
| else |
| { |
| // Redirect |
| String aRetVal(ret_val, osl_getThreadTextEncoding()); |
| String aRedirected (aRetVal); |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aRedirected ); |
| #endif |
| if ( FSYS_KIND_DIR == eKind ) |
| { |
| if ( 0 == _mkdir( ByteString(aRedirected.GetBuffer(), osl_getThreadTextEncoding()).GetBuffer() ) ) |
| { |
| aRet = DirEntry( aRetVal ); |
| break; |
| } |
| } |
| else |
| { |
| #if defined(UNX) || defined(OS2) |
| if( access( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), F_OK ) ) |
| { |
| aRet = DirEntry( aRetVal ); |
| break; |
| } |
| #else |
| struct stat aStat; |
| if ( stat( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), &aStat ) ) |
| { |
| aRet = DirEntry( aRetVal ); |
| break; |
| } |
| #endif |
| } |
| } |
| } |
| |
| delete[] ret_val; |
| ret_val = 0; |
| } |
| |
| return aRet; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::operator[]() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 03.03.92 |
| |* Letzte Aenderung MI 03.03.92 |
| |* |
| *************************************************************************/ |
| |
| const DirEntry &DirEntry::operator[]( sal_uInt16 nParentLevel ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| //TPF: maybe to be implemented (FastFSys) |
| |
| const DirEntry *pRes = this; |
| while ( pRes && nParentLevel-- ) |
| pRes = pRes->pParent; |
| |
| return *pRes; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ImpParseUnixName() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 26.05.93 |
| |* |
| *************************************************************************/ |
| |
| FSysError DirEntry::ImpParseUnixName( const ByteString& rPfad, FSysPathStyle eStyle ) |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // die einzelnen Namen auf einen Stack packen |
| DirEntryStack aStack; |
| ByteString aPfad( rPfad ); |
| do |
| { |
| // den Namen vor dem ersten "/" abspalten, |
| // falls '/' am Anfang, ist der Name '/', |
| // der Rest immer ohne die fuehrenden '/'. |
| // den ersten '/' suchen |
| sal_uInt16 nPos; |
| for ( nPos = 0; |
| nPos < aPfad.Len() && aPfad.GetChar(nPos) != '/'; |
| nPos++ ) |
| /* do nothing */; |
| |
| // ist der Name die Root des aktuellen Drives? |
| if ( nPos == 0 && aPfad.Len() > 0 && ( aPfad.GetChar(0) == '/' ) ) |
| { |
| // Root-Directory des aktuellen Drives |
| aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) ); |
| } |
| else |
| { |
| // den Namen ohne Trenner abspalten |
| aName = aPfad.Copy( 0, nPos ); |
| |
| // stellt der Name die aktuelle Directory dar? |
| if ( aName == "." ) |
| /* do nothing */; |
| |
| #ifdef UNX |
| // stellt der Name das User-Dir dar? |
| else if ( aName == "~" ) |
| { |
| DirEntry aHome( String( (const char *) getenv( "HOME" ), osl_getThreadTextEncoding()) ); |
| for ( sal_uInt16 n = aHome.Level(); n; --n ) |
| aStack.Push( new DirEntry( aHome[ (sal_uInt16) n-1 ] ) ); |
| } |
| #endif |
| |
| // stellt der Name die Parent-Directory dar? |
| else if ( aName == ".." ) |
| { |
| // ist nichts, ein Parent oder eine relative Root |
| // auf dem Stack? |
| if ( ( aStack.Count() == 0 ) || |
| ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) ) |
| // fuehrende Parents kommen auf den Stack |
| aStack.Push( new DirEntry( ByteString(), FSYS_FLAG_PARENT, eStyle ) ); |
| |
| // ist es eine absolute Root |
| else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT ) { |
| // die hat keine Parent-Directory |
| return FSYS_ERR_NOTEXISTS; |
| } |
| else |
| // sonst hebt der Parent den TOS auf |
| delete aStack.Pop(); |
| } |
| else |
| { |
| DirEntry *pNew = NULL; |
| // normalen Entries kommen auf den Stack |
| pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle ); |
| if ( !pNew->IsValid() ) |
| { |
| aName = rPfad; |
| ErrCode eErr = pNew->GetError(); |
| delete pNew; |
| return eErr; |
| } |
| aStack.Push( pNew ); |
| } |
| } |
| |
| // den Restpfad bestimmen |
| aPfad.Erase( 0, nPos + 1 ); |
| while ( aPfad.Len() && ( aPfad.GetChar(0) == '/' ) ) |
| aPfad.Erase( 0, 1 ); |
| } |
| while ( aPfad.Len() ); |
| |
| // Haupt-Entry (selbst) zuweisen |
| if ( aStack.Count() == 0 ) |
| { |
| eFlag = FSYS_FLAG_CURRENT; |
| aName.Erase(); |
| } |
| else |
| { |
| eFlag = aStack.Top()->eFlag; |
| aName = aStack.Top()->aName; |
| delete aStack.Pop(); |
| } |
| |
| // die Parent-Entries vom Stack holen |
| DirEntry** pTemp = &pParent; |
| while ( aStack.Count() ) |
| { |
| *pTemp = aStack.Pop(); |
| pTemp = &( (*pTemp)->pParent ); |
| } |
| |
| return FSYS_ERR_OK; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::MakeShortName() |
| |* |
| |* Beschreibung |
| |* Ersterstellung TLX |
| |* Letzte Aenderung PB 21.08.97 (in CreateEntry_Impl()) |
| |* |
| *************************************************************************/ |
| |
| ErrCode CreateEntry_Impl( const DirEntry &rPath, DirEntryKind eKind ) |
| { |
| // versuchen, anzulegen (ausser bei FSYS_KIND_ALL) |
| ErrCode eErr = ERRCODE_NONE; |
| if ( FSYS_KIND_FILE == eKind ) |
| { |
| SvFileStream aStream( rPath.GetFull(), STREAM_STD_WRITE ); |
| aStream.WriteLine( "" ); |
| eErr = aStream.GetError(); |
| } |
| else if ( FSYS_KIND_ALL != eKind ) |
| eErr = rPath.MakeDir() ? ERRCODE_NONE : ERRCODE_IO_UNKNOWN; |
| |
| // erfolgreich? |
| if ( !rPath.Exists() ) |
| eErr = ERRCODE_IO_UNKNOWN; // Doch was schiefgegangen ? |
| |
| // ggf. wieder l"oschen |
| if ( FSYS_KIND_NONE == eKind ) |
| rPath.Kill(); |
| |
| // Fehlercode zur?ckliefern |
| return eErr; |
| } |
| |
| sal_Bool IsValidEntry_Impl( const DirEntry &rPath, |
| const String &rLongName, |
| DirEntryKind eKind, |
| sal_Bool bIsShortened, |
| sal_Bool bUseDelim ) |
| { |
| // Parameter-Pr"uefung |
| DBG_ASSERT( eKind == FSYS_KIND_NONE || eKind == FSYS_KIND_ALL || |
| eKind == FSYS_KIND_FILE || eKind == FSYS_KIND_DIR, |
| "invalid entry-kind" ); |
| |
| // Alle von MSDOS erreichbaren FSYS_STYLES muessen den |
| // MSDOS Filenamenanforderungen genuegen. Sonst wird probiert, |
| // ob sich eine Datei des gewuenschten Names anlegen laesst. |
| FSysPathStyle eStyle = DirEntry::GetPathStyle( rPath.GetDevice().GetName() ); |
| DirEntry aPath(rPath); |
| DirEntry aName(rLongName, eStyle); |
| if ( !aName.IsValid() || aName.Level() != 1 ) |
| return sal_False; |
| aPath += aName; |
| if ( 1 == aPath.Level() ) |
| return sal_False; |
| if ( eStyle == FSYS_STYLE_FAT || eStyle == FSYS_STYLE_NWFS || |
| eStyle == FSYS_STYLE_UNKNOWN ) |
| { |
| DirEntry aDosEntry( rLongName, FSYS_STYLE_FAT ); |
| if ( !aDosEntry.IsValid() ) |
| return sal_False; |
| } |
| |
| // Pfad-Trenner sind nicht erlaubt (bei ungek"urzten auch nicht FSYS_SHORTNAME_DELIMITER) |
| char cDelim = bUseDelim == 2 ? FSYS_SHORTNAME_DELIMITER : char(0); |
| if ( |
| rLongName.Search(DirEntry::GetAccessDelimiter()) != STRING_NOTFOUND || |
| (!bIsShortened && rLongName.Search(cDelim) != STRING_NOTFOUND) |
| ) |
| { |
| return sal_False; |
| } |
| |
| // MI: Abfrage nach 'CON:' etc. wird jetzt in Exists() mitgemacht |
| if ( aPath.Exists() ) |
| return sal_False; |
| |
| return (ERRCODE_NONE == CreateEntry_Impl( aPath, eKind )); |
| } |
| |
| //------------------------------------------------------------------------- |
| |
| #define MAX_EXT_FAT 3 |
| #define MAX_LEN_FAT 8 |
| #define INVALID_CHARS_FAT "\\/\"':|^<>[]?* " |
| |
| #define MAX_EXT_MAC 16 // nur wegen sinnvoller Namensk"rzung |
| #define MAX_LEN_MAC 31 |
| #define INVALID_CHARS_MAC "\":" |
| |
| #define MAX_EXT_MAX 250 |
| #define MAX_LEN_MAX 255 |
| #define INVALID_CHARS_DEF "\\/\"':|^<>?*" |
| |
| sal_Bool DirEntry::MakeShortName( const String& rLongName, DirEntryKind eKind, |
| sal_Bool bUseDelim, FSysPathStyle eStyle ) |
| { |
| String aLongName(rLongName); |
| |
| // Alle '#' aus den Dateinamen entfernen, weil das INetURLObject |
| // damit Probleme hat. Siehe auch #51246# |
| aLongName.EraseAllChars( '#' ); |
| ByteString bLongName(aLongName, osl_getThreadTextEncoding()); |
| |
| // Auf Novell-Servern (wegen der rottigen Clients) nur 7bit ASCII |
| |
| // HRO: #69627# Weg mit dem Scheiss. Wenn es Client gibt, die so einen |
| // BUG haben, dann muss halt der Client ersetzt werden, aber doch nicht das |
| // Office kastrieren !!! |
| |
| #if 0 |
| if ( FSYS_STYLE_NWFS == GetPathStyle( ImpGetTopPtr()->GetName() ) ) |
| { |
| for ( sal_uInt16 n = aLongName.Len(); n; --n ) |
| { |
| short nChar = aLongName(n-1); |
| if ( nChar < 32 || nChar >= 127 ) |
| aLongName.Erase( n-1, 1 ); |
| } |
| } |
| #endif |
| |
| // bei FSYS_KIND_ALL den alten Namen merken und abh"angen (rename) |
| ByteString aOldName; |
| if ( FSYS_KIND_ALL == eKind ) |
| { |
| aOldName = ByteString(CutName(), osl_getThreadTextEncoding()); |
| aOldName = CMP_LOWER(aOldName); |
| } |
| |
| // ist der Langname direkt verwendbar? |
| if ( IsValidEntry_Impl( *this, aLongName, eKind, sal_False, bUseDelim ) ) |
| { |
| operator+=( DirEntry(aLongName) ); |
| return sal_True; |
| } |
| |
| // max L"angen feststellen |
| sal_uInt16 nMaxExt, nMaxLen; |
| if ( FSYS_STYLE_DETECT == eStyle ) |
| eStyle = DirEntry::GetPathStyle( GetDevice().GetName() ); |
| ByteString aInvalidChars; |
| switch ( eStyle ) |
| { |
| case FSYS_STYLE_FAT: |
| nMaxExt = MAX_EXT_FAT; |
| nMaxLen = MAX_LEN_FAT; |
| aInvalidChars = INVALID_CHARS_FAT; |
| break; |
| |
| case FSYS_STYLE_MAC: |
| nMaxExt = MAX_EXT_MAC; |
| nMaxLen = MAX_LEN_MAC; |
| aInvalidChars = INVALID_CHARS_MAC; |
| break; |
| |
| default: |
| nMaxExt = MAX_EXT_MAX; |
| nMaxLen = MAX_LEN_MAX; |
| aInvalidChars = INVALID_CHARS_DEF; |
| } |
| |
| // Extension abschneiden und kuerzen |
| ByteString aExt; |
| ByteString aFName = bLongName; |
| if ( FSYS_STYLE_MAC != eStyle ) |
| { |
| DirEntry aUnparsed; |
| aUnparsed.aName = bLongName; |
| aExt = ByteString(aUnparsed.CutExtension(), osl_getThreadTextEncoding()); |
| aFName = aUnparsed.aName; |
| if ( aExt.Len() > nMaxExt ) |
| { |
| char c = aExt.GetChar( aExt.Len() - 1 ); |
| aExt.Erase(nMaxExt-1); |
| aExt += c; |
| } |
| } |
| |
| if ( FSYS_STYLE_FAT != eStyle ) |
| { |
| // ausser auf einem FAT-System geh"ort die Extension zur |
| // Maxl"ange. Muss also vorher mit dem Punkt abgezogen werden. |
| nMaxLen -= ( aExt.Len() + 1 ); |
| } |
| |
| // Name k"urzen |
| ByteString aSName; |
| for ( const char *pc = aFName.GetBuffer(); aSName.Len() < nMaxLen && *pc; ++pc ) |
| { |
| if ( STRING_NOTFOUND == aInvalidChars.Search( *pc ) && |
| (unsigned char) *pc >= (unsigned char) 32 && |
| ( !aSName.Len() || *pc != ' ' || aSName.GetChar(aSName.Len()-1) != ' ' ) ) |
| aSName += *pc; |
| } |
| aSName.EraseTrailingChars(); |
| |
| // HRO: #74246# Also cut leading spaces |
| aSName.EraseLeadingChars(); |
| |
| if ( !aSName.Len() ) |
| aSName = "noname"; |
| |
| // kommt dabei der alte Name raus? |
| ByteString aNewName = aSName; |
| if ( aExt.Len() ) |
| ( aNewName += '.' ) += aExt; |
| operator+=( DirEntry(String(aNewName, osl_getThreadTextEncoding())) ); |
| if ( FSYS_KIND_ALL == eKind && CMP_LOWER(aName) == aOldName ) |
| if ( FSYS_KIND_ALL == eKind && CMP_LOWER(ByteString(GetName(), osl_getThreadTextEncoding())) == aOldName ) |
| return sal_True; |
| |
| // kann der gek"urzte Name direkt verwendet werden? |
| if ( !Exists() && (ERRCODE_NONE == CreateEntry_Impl( *this, eKind )) ) |
| return sal_True; |
| |
| // darf '?##' verwendet werden, um eindeutigen Name zu erzeugen? |
| if ( bUseDelim ) |
| { |
| // eindeutigen Namen per '?##' erzeugen |
| aSName.Erase( nMaxLen-3 ); |
| if ( bUseDelim != 2 ) |
| aSName += FSYS_SHORTNAME_DELIMITER; |
| for ( int n = 1; n < 99; ++n ) |
| { |
| // Name zusammensetzen |
| ByteString aTmpStr( aSName ); |
| aTmpStr += ByteString::CreateFromInt32(n); |
| if ( aExt.Len() ) |
| ( aTmpStr += '.' ) += aExt; |
| |
| // noch nicht vorhanden? |
| SetName( String(aTmpStr, osl_getThreadTextEncoding()) ); |
| |
| if ( !Exists() ) |
| { |
| // Fehler setzen !!! |
| nError = CreateEntry_Impl( *this, eKind ); |
| return (ERRCODE_NONE == nError); |
| } |
| } |
| } |
| |
| // keine ## mehr frei / ?## soll nicht verwendet werden |
| nError = ERRCODE_IO_ALREADYEXISTS; |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::CreatePath() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MA 02.12.91 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::MakeDir( sal_Bool bSloppy ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| // Schnellpruefung, ob vorhanden |
| if ( FileStat( *this ).IsKind( FSYS_KIND_DIR ) ) |
| return sal_True; |
| if ( bSloppy && pParent ) |
| if ( FileStat( *pParent ).IsKind( FSYS_KIND_DIR ) ) |
| return sal_True; |
| |
| const DirEntry *pNewDir = bSloppy ? pParent : this; |
| if ( pNewDir ) |
| { |
| // den Path zum Dir erzeugen |
| if ( pNewDir->pParent && !pNewDir->pParent->MakeDir(sal_False) ) |
| return sal_False; |
| |
| // das Dir selbst erzeugen |
| if ( pNewDir->eFlag == FSYS_FLAG_ABSROOT || |
| pNewDir->eFlag == FSYS_FLAG_ABSROOT || |
| pNewDir->eFlag == FSYS_FLAG_VOLUME ) |
| return sal_True; |
| else |
| { |
| //? nError = ??? |
| if ( FileStat( *pNewDir ).IsKind( FSYS_KIND_DIR ) ) |
| return sal_True; |
| else |
| { |
| FSysFailOnErrorImpl(); |
| String aDirName(pNewDir->GetFull()); |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aDirName ); |
| #endif |
| ByteString bDirName( aDirName, osl_getThreadTextEncoding() ); |
| bDirName = GUI2FSYS( bDirName ); |
| |
| #ifdef WIN32 |
| SetLastError(0); |
| #endif |
| sal_Bool bResult = (0 == _mkdir( (char*) bDirName.GetBuffer() )); |
| if ( !bResult ) |
| { |
| // Wer hat diese Methode const gemacht ? |
| #ifdef WIN32 |
| ((DirEntry *)this)->SetError( Sys2SolarError_Impl( GetLastError() ) ); |
| #else |
| ((DirEntry *)this)->SetError( Sys2SolarError_Impl( errno ) ); |
| #endif |
| } |
| |
| return bResult; |
| } |
| } |
| } |
| return sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::CopyTo() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 07.08.96 |
| |* |
| *************************************************************************/ |
| |
| FSysError DirEntry::CopyTo( const DirEntry& rDest, FSysAction nActions ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| if ( FSYS_ACTION_COPYFILE != (nActions & FSYS_ACTION_COPYFILE) ) |
| #ifdef UNX |
| { |
| // Hardlink anlegen |
| HACK(redirection missing) |
| ByteString aThis(GUI2FSYS(GetFull()), osl_getThreadTextEncoding()); |
| ByteString aDest(GUI2FSYS(rDest.GetFull()), osl_getThreadTextEncoding()); |
| if (link( aThis.GetBuffer(), aDest.GetBuffer() ) == -1) |
| return Sys2SolarError_Impl( errno ); |
| else |
| return FSYS_ERR_OK; |
| } |
| #else |
| return FSYS_ERR_NOTSUPPORTED; |
| #endif |
| |
| FileCopier fc(*this, rDest); |
| return fc.Execute(nActions); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::MoveTo() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung HRO 24.03.99 |
| |* |
| *************************************************************************/ |
| |
| #if defined WNT || defined UNX || defined OS2 |
| |
| FSysError DirEntry::MoveTo( const DirEntry& rNewName ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| /* |
| FileStat aSourceStat(*this); |
| if ( !aSourceStat.IsKind(FSYS_KIND_FILE) ) |
| return FSYS_ERR_NOTAFILE; |
| */ |
| |
| DirEntry aDest(rNewName); |
| FileStat aDestStat(rNewName); |
| if ( aDestStat.IsKind(FSYS_KIND_DIR ) ) |
| { |
| aDest += String(aName, osl_getThreadTextEncoding()); |
| } |
| if ( aDest.Exists() ) |
| { |
| return FSYS_ERR_ALREADYEXISTS; |
| } |
| |
| #if defined(OS2) |
| if ( FileStat(*this).IsKind(FSYS_KIND_DIR) && aDest.GetPath() != GetPath() ) |
| { |
| return FSYS_ERR_NOTSUPPORTED; |
| } |
| #endif |
| |
| FSysFailOnErrorImpl(); |
| String aFrom( GetFull() ); |
| |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect(aFrom); |
| #endif |
| |
| String aTo( aDest.GetFull() ); |
| |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect(aTo); |
| #endif |
| |
| ByteString bFrom(aFrom, osl_getThreadTextEncoding()); |
| ByteString bTo(aTo, osl_getThreadTextEncoding()); |
| bFrom = GUI2FSYS(bFrom); |
| bTo = GUI2FSYS(bTo); |
| |
| #ifdef WNT |
| // MoveTo nun atomar |
| SetLastError(0); |
| |
| DirEntry aFromDevice(String(bFrom, osl_getThreadTextEncoding())); |
| DirEntry aToDevice(String(bTo,osl_getThreadTextEncoding())); |
| aFromDevice.ToAbs(); |
| aToDevice.ToAbs(); |
| aFromDevice=aFromDevice.GetDevice(); |
| aToDevice=aToDevice.GetDevice(); |
| |
| //Quelle und Ziel auf gleichem device? |
| if (aFromDevice==aToDevice) |
| { |
| // ja, also intra-device-move mit MoveFile |
| MoveFile( bFrom.GetBuffer(), bTo.GetBuffer() ); |
| // MoveFile ist buggy bei cross-device operationen. |
| // Der R?ckgabewert ist auch dann sal_True, wenn nur ein Teil der Operation geklappt hat. |
| // Zudem zeigt MoveFile unterschiedliches Verhalten bei unterschiedlichen NT-Versionen. |
| return Sys2SolarError_Impl( GetLastError() ); |
| } |
| else |
| { |
| //nein, also inter-device-move mit copy/delete |
| FSysError nCopyError = CopyTo(rNewName, FSYS_ACTION_COPYFILE); |
| |
| DirEntry aKill(String(bTo, osl_getThreadTextEncoding())); |
| FileStat aKillStat(String(bTo, osl_getThreadTextEncoding())); |
| if ( aKillStat.IsKind(FSYS_KIND_DIR ) ) |
| { |
| aKill += String(aName, osl_getThreadTextEncoding()); |
| } |
| |
| if (nCopyError==FSYS_ERR_OK) |
| { |
| if (Kill()==FSYS_ERR_OK) |
| { |
| return FSYS_ERR_OK; |
| } |
| else |
| { |
| aKill.Kill(); |
| return FSYS_ERR_ACCESSDENIED; |
| } |
| } |
| else |
| { |
| aKill.Kill(); |
| return nCopyError; |
| } |
| } |
| #else |
| // #68639# |
| // on some nfs connections rename with from == to |
| // leads to destruction of file |
| if ( ( aFrom != aTo ) && ( 0 != rename( bFrom.GetBuffer(), bTo.GetBuffer() ) ) ) |
| #if !defined(UNX) && !defined(OS2) |
| return Sys2SolarError_Impl( GetLastError() ); |
| #else |
| { |
| if( errno == EXDEV ) |
| // cross device geht latuernich nicht mit rename |
| { |
| FILE *fpIN = fopen( bFrom.GetBuffer(), "r" ); |
| FILE *fpOUT = fopen( bTo.GetBuffer(), "w" ); |
| if( fpIN && fpOUT ) |
| { |
| char pBuf[ 16384 ]; |
| int nBytes, nWritten, nErr = 0; |
| errno = 0; |
| while( ( nBytes = fread( pBuf, 1, sizeof(pBuf), fpIN ) ) && ! nErr ) |
| { |
| nWritten = fwrite( pBuf, 1, nBytes, fpOUT ); |
| // Fehler im fwrite ? |
| if( nWritten < nBytes ) |
| { |
| nErr = errno; |
| break; |
| } |
| } |
| fclose( fpIN ); |
| fclose( fpOUT ); |
| if ( nErr ) |
| { |
| unlink( bTo.GetBuffer() ); |
| return Sys2SolarError_Impl( nErr ); |
| } |
| else |
| { |
| unlink( bFrom.GetBuffer() ); |
| } |
| } |
| else |
| { |
| return Sys2SolarError_Impl( EXDEV ); |
| } |
| } |
| else |
| { |
| return Sys2SolarError_Impl( errno ); |
| } |
| } |
| #endif |
| #endif |
| return ERRCODE_NONE; |
| } |
| |
| #endif |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::Kill() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 26.04.91 |
| |* Letzte Aenderung MI 07.08.96 |
| |* |
| *************************************************************************/ |
| |
| FSysError DirEntry::Kill( FSysAction nActions ) const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| FSysError eError = FSYS_ERR_OK; |
| FSysFailOnErrorImpl(); |
| |
| // Name als doppelt 0-terminierter String |
| String aTmpName( GetFull() ); |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aTmpName ); |
| #endif |
| ByteString bTmpName( aTmpName, osl_getThreadTextEncoding()); |
| bTmpName = GUI2FSYS(bTmpName); |
| |
| char *pName = new char[bTmpName.Len()+2]; |
| strcpy( pName, bTmpName.GetBuffer() ); |
| pName[bTmpName.Len()+1] = (char) 0; |
| |
| //read-only files sollen auch geloescht werden koennen |
| sal_Bool isReadOnly = FileStat::GetReadOnlyFlag(*this); |
| if (isReadOnly) |
| { |
| FileStat::SetReadOnlyFlag(*this, sal_False); |
| } |
| |
| // directory? |
| if ( FileStat( *this ).IsKind(FSYS_KIND_DIR) ) |
| { |
| // Inhalte recursiv loeschen? |
| if ( FSYS_ACTION_RECURSIVE == (nActions & FSYS_ACTION_RECURSIVE) ) |
| { |
| Dir aDir( *this, FSYS_KIND_DIR|FSYS_KIND_FILE ); |
| for ( sal_uInt16 n = 0; eError == FSYS_ERR_OK && n < aDir.Count(); ++n ) |
| { |
| const DirEntry &rSubDir = aDir[n]; |
| DirEntryFlag flag = rSubDir.GetFlag(); |
| if ( flag != FSYS_FLAG_CURRENT && flag != FSYS_FLAG_PARENT ) |
| eError = rSubDir.Kill(nActions); |
| } |
| } |
| |
| // das Dir selbst loeschen |
| #ifdef WIN32 |
| SetLastError(0); |
| #endif |
| if ( eError == FSYS_ERR_OK && 0 != _rmdir( (char*) pName ) ) |
| // |
| { |
| // falls L"oschen nicht ging, CWD umsetzen |
| #ifdef WIN32 |
| eError = Sys2SolarError_Impl( GetLastError() ); |
| #else |
| eError = Sys2SolarError_Impl( errno ); |
| #endif |
| if ( eError ) |
| { |
| GetPath().SetCWD(); |
| #ifdef WIN32 |
| SetLastError(0); |
| #endif |
| if (_rmdir( (char*) pName) != 0) |
| { |
| #ifdef WIN32 |
| eError = Sys2SolarError_Impl( GetLastError() ); |
| #else |
| eError = Sys2SolarError_Impl( errno ); |
| #endif |
| } |
| else |
| { |
| eError = FSYS_ERR_OK; |
| } |
| } |
| } |
| } |
| else |
| { |
| if ( FSYS_ACTION_USERECYCLEBIN == (nActions & FSYS_ACTION_USERECYCLEBIN) ) |
| { |
| #ifdef OS2 |
| eError = ApiRet2ToSolarError_Impl( DosDelete( (PSZ) pName ) ); |
| #elif defined(WNT) |
| SHFILEOPSTRUCT aOp; |
| aOp.hwnd = 0; |
| aOp.wFunc = FO_DELETE; |
| aOp.pFrom = pName; |
| aOp.pTo = 0; |
| aOp.fFlags = FOF_ALLOWUNDO|FOF_SILENT|FOF_NOCONFIRMATION; |
| aOp.hNameMappings = 0; |
| aOp.lpszProgressTitle = 0; |
| eError = Sys2SolarError_Impl( SHFileOperation( &aOp ) ); |
| #else |
| eError = ERRCODE_IO_NOTSUPPORTED; |
| #endif |
| } |
| else |
| { |
| #ifdef WIN32 |
| SetLastError(0); |
| #endif |
| if ( 0 != _unlink( (char*) pName ) ) |
| { |
| #ifdef WIN32 |
| eError = Sys2SolarError_Impl( GetLastError() ); |
| #else |
| eError = Sys2SolarError_Impl( errno ); |
| #endif |
| } |
| else |
| { |
| eError = ERRCODE_NONE; |
| } |
| } |
| } |
| |
| //falls Fehler, originales read-only flag wieder herstellen |
| if ( isReadOnly && (eError!=ERRCODE_NONE) ) |
| { |
| FileStat::SetReadOnlyFlag(*this, isReadOnly); |
| } |
| |
| delete[] pName; |
| return eError; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::Contains() |
| |* |
| |* Beschreibung ob rSubEntry direkt oder indirect in *this liegt |
| |* Ersterstellung MI 20.03.97 |
| |* Letzte Aenderung MI 20.03.97 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::Contains( const DirEntry &rSubEntry ) const |
| { |
| DBG_ASSERT( IsAbs() && rSubEntry.IsAbs(), "must be absolute entries" ); |
| |
| sal_uInt16 nThisLevel = Level(); |
| sal_uInt16 nSubLevel = rSubEntry.Level(); |
| if ( nThisLevel < nSubLevel ) |
| { |
| for ( ; nThisLevel; --nThisLevel, --nSubLevel ) |
| if ( (*this)[nThisLevel-1] != rSubEntry[nSubLevel-1] ) |
| return sal_False; |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::Level() |
| |* |
| |* Beschreibung FSYS.SDW |
| |* Ersterstellung MI 03.03.92 |
| |* Letzte Aenderung MI 03.03.92 |
| |* |
| *************************************************************************/ |
| |
| sal_uInt16 DirEntry::Level() const |
| { |
| DBG_CHKTHIS( DirEntry, ImpCheckDirEntry ); |
| |
| sal_uInt16 nLevel = 0; |
| const DirEntry *pRes = this; |
| while ( pRes ) |
| { |
| pRes = pRes->pParent; |
| nLevel++; |
| } |
| |
| return nLevel; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ConvertNameToSystem() |
| |* |
| |* Beschreibung |
| |* Ersterstellung DV 29.03.96 |
| |* Letzte Aenderung DV 29.03.96 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::ConvertNameToSystem( const String &rName ) |
| { |
| return rName; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::ConvertSystemToName() |
| |* |
| |* Beschreibung |
| |* Ersterstellung DV 29.03.96 |
| |* Letzte Aenderung DV 29.03.96 |
| |* |
| *************************************************************************/ |
| |
| String DirEntry::ConvertSystemToName( const String &rName ) |
| { |
| return rName; |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::IsValid() |
| |* |
| |* Beschreibung |
| |* Ersterstellung MI 18.09.93 |
| |* Letzte Aenderung TPF 18.09.98 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::IsValid() const |
| { |
| return (nError == FSYS_ERR_OK); |
| } |
| |
| /************************************************************************* |
| |* |
| |* DirEntry::IsRFSAvailable() |
| |* |
| |* Beschreibung |
| |* Ersterstellung TPF 21.10.98 |
| |* Letzte Aenderung TPF 21.10.98 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::IsRFSAvailable() |
| { |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* IsLongNameOnFAT() |
| |* |
| |* Beschreibung ?berpr?ft , ob das DirEntry einen langen |
| |* Filenamen auf einer FAT-Partition enth?lt (EAs). |
| |* (eigentlich nur f?r OS2 interessant) |
| |* Ersterstellung TPF 02.10.98 |
| |* Letzte Aenderung TPF 01.03.1999 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool DirEntry::IsLongNameOnFAT() const |
| { |
| // FAT-System? |
| DirEntry aTempDirEntry(*this); |
| aTempDirEntry.ToAbs(); |
| if (DirEntry::GetPathStyle(aTempDirEntry.GetDevice().GetName().GetChar(0)) != FSYS_STYLE_FAT) |
| { |
| return sal_False; // nein, also false |
| } |
| |
| // DirEntry-Kette auf lange Dateinamen pr?fen |
| for( sal_uInt16 iLevel = this->Level(); iLevel > 0; iLevel-- ) |
| { |
| const DirEntry& rEntry = (const DirEntry&) (*this)[iLevel-1]; |
| String aBase( rEntry.GetBase() ); |
| String aExtension( rEntry.GetExtension() ); |
| |
| if (aBase.Len()>8) // Name > 8? |
| { |
| return sal_True; |
| } |
| |
| if (aExtension.Len()>3) // Extension > 3? |
| { |
| return sal_True; |
| } |
| } |
| return sal_False; |
| } |
| |
| //======================================================================== |
| |
| #if defined(DBG_UTIL) |
| |
| void FSysTest() |
| { |
| } |
| |
| #endif |
| |