xref: /trunk/main/tools/source/fsys/dirent.cxx (revision 73fec56a)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_tools.hxx"
24 
25 #if !defined UNX
26 #include <io.h>
27 #include <process.h>
28 #endif
29 
30 #if defined(UNX) || defined(OS2)
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #endif
35 
36 #include <ctype.h>
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <tools/debug.hxx>
42 #include <tools/list.hxx>
43 #include "comdep.hxx"
44 #include <tools/fsys.hxx>
45 #define _TOOLS_HXX
46 #include <tools/urlobj.hxx>
47 
48 #ifdef UNX
49 #define _MAX_PATH 260
50 #endif
51 #include <tools/stream.hxx>
52 
53 #ifndef _VOS_MUTEX_HXX
54 #include <vos/mutex.hxx>
55 #endif
56 
57 #include <osl/file.hxx>
58 #include <rtl/instance.hxx>
59 
60 
61 using namespace osl;
62 using namespace rtl;
63 
64 int ApiRet2ToSolarError_Impl( int nApiRet );
65 
66 //--------------------------------------------------------------------
Sys2SolarError_Impl(int nSysErr)67 int Sys2SolarError_Impl( int nSysErr )
68 {
69     switch ( nSysErr )
70     {
71 #ifdef WNT
72                 case NO_ERROR:                                  return ERRCODE_NONE;
73                 case ERROR_INVALID_FUNCTION:    return ERRCODE_IO_GENERAL;
74                 case ERROR_FILE_NOT_FOUND:              return ERRCODE_IO_NOTEXISTS;
75                 case ERROR_PATH_NOT_FOUND:              return ERRCODE_IO_NOTEXISTSPATH;
76                 case ERROR_TOO_MANY_OPEN_FILES: return ERRCODE_IO_TOOMANYOPENFILES;
77                 case ERROR_ACCESS_DENIED:               return ERRCODE_IO_ACCESSDENIED;
78                 case ERROR_INVALID_HANDLE:              return ERRCODE_IO_GENERAL;
79                 case ERROR_NOT_ENOUGH_MEMORY:   return ERRCODE_IO_OUTOFMEMORY;
80                 case ERROR_INVALID_BLOCK:               return ERRCODE_IO_GENERAL;
81 //              case ERROR_BAD_ENVIRONMENT:     return ERRCODE_IO_;
82                 case ERROR_BAD_FORMAT:                  return ERRCODE_IO_WRONGFORMAT;
83                 case ERROR_INVALID_ACCESS:              return ERRCODE_IO_ACCESSDENIED;
84 //              case ERROR_INVALID_DATA:                return ERRCODE_IO_;
85                 case ERROR_INVALID_DRIVE:               return ERRCODE_IO_INVALIDDEVICE;
86                 case ERROR_CURRENT_DIRECTORY:   return ERRCODE_IO_CURRENTDIR;
87                 case ERROR_NOT_SAME_DEVICE:     return ERRCODE_IO_NOTSAMEDEVICE;
88 //              case ERROR_NO_MORE_FILES:               return ERRCODE_IO_;
89                 case ERROR_WRITE_PROTECT:               return ERRCODE_IO_CANTWRITE;
90                 case ERROR_BAD_UNIT:                    return ERRCODE_IO_INVALIDDEVICE;
91                 case ERROR_NOT_READY:                   return ERRCODE_IO_DEVICENOTREADY;
92                 case ERROR_BAD_COMMAND:                 return ERRCODE_IO_GENERAL;
93                 case ERROR_CRC:                                 return ERRCODE_IO_BADCRC;
94                 case ERROR_BAD_LENGTH:                  return ERRCODE_IO_INVALIDLENGTH;
95                 case ERROR_SEEK:                                return ERRCODE_IO_CANTSEEK;
96                 case ERROR_NOT_DOS_DISK:                return ERRCODE_IO_WRONGFORMAT;
97                 case ERROR_SECTOR_NOT_FOUND:    return ERRCODE_IO_GENERAL;
98                 case ERROR_WRITE_FAULT:                 return ERRCODE_IO_CANTWRITE;
99                 case ERROR_READ_FAULT:                  return ERRCODE_IO_CANTREAD;
100                 case ERROR_GEN_FAILURE:                 return ERRCODE_IO_GENERAL;
101                 case ERROR_SHARING_VIOLATION:   return ERRCODE_IO_LOCKVIOLATION;
102                 case ERROR_LOCK_VIOLATION:              return ERRCODE_IO_LOCKVIOLATION;
103                 case ERROR_WRONG_DISK:                  return ERRCODE_IO_INVALIDDEVICE;
104                 case ERROR_NOT_SUPPORTED:               return ERRCODE_IO_NOTSUPPORTED;
105 #else
106         case 0:         return ERRCODE_NONE;
107         case ENOENT:    return ERRCODE_IO_NOTEXISTS;
108         case EACCES:    return ERRCODE_IO_ACCESSDENIED;
109         case EEXIST:    return ERRCODE_IO_ALREADYEXISTS;
110         case EINVAL:    return ERRCODE_IO_INVALIDPARAMETER;
111         case EMFILE:    return ERRCODE_IO_TOOMANYOPENFILES;
112         case ENOMEM:    return ERRCODE_IO_OUTOFMEMORY;
113         case ENOSPC:    return ERRCODE_IO_OUTOFSPACE;
114 #endif
115     }
116 
117     DBG_TRACE1( "FSys: unknown system error %d occurred", nSysErr );
118     return FSYS_ERR_UNKNOWN;
119 }
120 
121 //--------------------------------------------------------------------
122 
123 #ifndef BOOTSTRAP
124 
125 FSysRedirector* FSysRedirector::_pRedirector = 0;
126 sal_Bool FSysRedirector::_bEnabled = sal_True;
127 #ifdef UNX
128 sal_Bool bInRedirection = sal_True;
129 #else
130 sal_Bool bInRedirection = sal_False;
131 #endif
132 static vos:: OMutex * pRedirectMutex = 0;
133 
134 //------------------------------------------------------------------------
Register(FSysRedirector * pRedirector)135 void FSysRedirector::Register( FSysRedirector *pRedirector )
136 {
137         if ( pRedirector )
138                 pRedirectMutex = new vos:: OMutex ;
139         else
140                 DELETEZ( pRedirectMutex );
141         _pRedirector = pRedirector;
142 }
143 
144 //------------------------------------------------------------------------
145 
DoRedirect(String & rPath)146 void FSysRedirector::DoRedirect( String &rPath )
147 {
148         String aURL(rPath);
149 
150         // if redirection is disabled or not even registered do nothing
151         if ( !_bEnabled || !pRedirectMutex )
152                 return;
153 
154         // redirect only removable or remote volumes
155         if ( !IsRedirectable_Impl( ByteString( aURL, osl_getThreadTextEncoding() ) ) )
156                 return;
157 
158         // Redirection is accessible only by one thread per time
159         // don't move the guard behind the bInRedirection check!!!
160         // think of nested calls (when called from callback)
161         vos:: OGuard  aGuard( pRedirectMutex );
162 
163         // if already in redirection, don't redirect
164         if ( bInRedirection )
165                 return;
166 
167         // don't redirect on nested calls
168         bInRedirection = sal_True;
169 
170         // convert to URL
171 #ifndef UNX
172         for ( sal_Unicode *p = (sal_Unicode*)aURL.GetBuffer(); *p; ++p )
173                 if ( '\\' == *p ) *p = '/';
174                 else if ( ':' == *p ) *p = '|';
175 #endif
176 
177         aURL.Insert( String("file:///", osl_getThreadTextEncoding()), 0 );
178 
179         // do redirection
180         Redirector();
181 
182         bInRedirection = sal_False;
183         return;
184 }
185 
186 //------------------------------------------------------------------------
187 
Redirector()188 FSysRedirector* FSysRedirector::Redirector()
189 {
190         if ( !_pRedirector )
191                 Register( new FSysRedirector );
192         return _pRedirector;
193 }
194 
195 #endif // BOOTSTRAP
196 
197 //--------------------------------------------------------------------
198 
199 class DirEntryStack: public List
200 {
201 public:
DirEntryStack()202                         DirEntryStack() {};
203                         ~DirEntryStack();
204 
205     inline  void        Push( DirEntry *pEntry );
206     inline  DirEntry*   Pop();
207     inline  DirEntry*   Top();
208     inline  DirEntry*   Bottom();
209 };
210 
Push(DirEntry * pEntry)211 inline void DirEntryStack::Push( DirEntry *pEntry )
212 {
213     List::Insert( pEntry, LIST_APPEND );
214 }
215 
Pop()216 inline DirEntry* DirEntryStack::Pop()
217 {
218     return (DirEntry*) List::Remove( Count() - 1 );
219 }
220 
Top()221 inline DirEntry* DirEntryStack::Top()
222 {
223     return (DirEntry*) List::GetObject( Count() - 1 );
224 }
225 
Bottom()226 inline DirEntry* DirEntryStack::Bottom()
227 {
228     return (DirEntry*) List::GetObject( 0 );
229 }
230 
231 //--------------------------------------------------------------------
232 
233 DBG_NAME( DirEntry );
234 
235 /*************************************************************************
236 |*
237 |*    DirEntry::~DirEntryStack()
238 |*
239 |*    Beschreibung      FSYS.SDW
240 |*    Ersterstellung    MI 26.04.91
241 |*    Letzte Aenderung  MI 04.07.91
242 |*
243 *************************************************************************/
244 
~DirEntryStack()245 DirEntryStack::~DirEntryStack()
246 {
247     while ( Count() )
248         delete Pop();
249 }
250 
251 /*************************************************************************
252 |*
253 |*    ImpCheckDirEntry()
254 |*
255 |*    Beschreibung      Pruefung eines DirEntry fuer DBG_UTIL
256 |*    Parameter         void* p     Zeiger auf den DirEntry
257 |*    Return-Wert       char*       Fehlermeldungs-TExtension oder NULL
258 |*    Ersterstellung    MI 16.07.91
259 |*    Letzte Aenderung  MI 26.05.93
260 |*
261 *************************************************************************/
262 
263 #ifdef DBG_UTIL
ImpCheckDirEntry(const void * p)264 const char* ImpCheckDirEntry( const void* p )
265 {
266     DirEntry* p0 = (DirEntry*)p;
267 
268     if ( p0->pParent )
269         DBG_CHKOBJ( p0->pParent, DirEntry, ImpCheckDirEntry );
270 
271     return NULL;
272 }
273 #endif
274 
275 /*************************************************************************
276 |*
277 |*    ImplCutPath()
278 |*
279 |*    Beschreibung      Fuegt ... ein, damit maximal nMaxChars lang
280 |*    Ersterstellung    MI 06.04.94
281 |*    Letzte Aenderung  DV 24.06.96
282 |*
283 *************************************************************************/
284 
ImplCutPath(const ByteString & rStr,sal_uInt16 nMax,char cAccDel)285 ByteString ImplCutPath( const ByteString& rStr, sal_uInt16 nMax, char cAccDel )
286 {
287     sal_uInt16  nMaxPathLen = nMax;
288     ByteString  aCutPath( rStr );
289     sal_Bool    bInsertPrefix = sal_False;
290     sal_uInt16  nBegin = aCutPath.Search( cAccDel );
291 
292     if( nBegin == STRING_NOTFOUND )
293         nBegin = 0;
294     else
295         nMaxPathLen += 2;   // fuer Prefix <Laufwerk>:
296 
297     while( aCutPath.Len() > nMaxPathLen )
298     {
299         sal_uInt16 nEnd = aCutPath.Search( cAccDel, nBegin + 1 );
300         sal_uInt16 nCount;
301 
302         if ( nEnd != STRING_NOTFOUND )
303         {
304             nCount = nEnd - nBegin;
305             aCutPath.Erase( nBegin, nCount );
306             bInsertPrefix = sal_True;
307         }
308         else
309             break;
310     }
311 
312     if ( aCutPath.Len() > nMaxPathLen )
313     {
314         for ( sal_uInt16 n = nMaxPathLen; n > nMaxPathLen/2; --n )
315             if ( !ByteString(aCutPath.GetChar(n)).IsAlphaNumericAscii() )
316             {
317                 aCutPath.Erase( n );
318                 aCutPath += "...";
319                 break;
320             }
321     }
322 
323     if ( bInsertPrefix )
324     {
325         ByteString aIns( cAccDel );
326         aIns += "...";
327         aCutPath.Insert( aIns, nBegin );
328     }
329 
330     return aCutPath;
331 }
332 
333 /*************************************************************************
334 |*
335 |*    DirEntry::ImpParseOs2Name()
336 |*
337 |*    Beschreibung      FSYS.SDW
338 |*    Ersterstellung    MI 26.04.91
339 |*    Letzte Aenderung  MI 23.06.95
340 |*
341 *************************************************************************/
342 
ImpParseOs2Name(const ByteString & rPfad,FSysPathStyle eStyle)343 FSysError DirEntry::ImpParseOs2Name( const ByteString& rPfad, FSysPathStyle eStyle  )
344 {
345     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
346 
347     // die einzelnen Namen auf einen Stack packen
348     String       aPfad( rPfad, osl_getThreadTextEncoding() );
349     DirEntryStack   aStack;
350 
351     do
352     {
353         // den Namen vor dem ersten "\\" abspalten,
354         // falls '\\' am Anfang, ist der Name '\\',
355         // der Rest immer ohne die fuehrenden '\\'.
356         // ein ":" trennt ebenfalls, gehoert aber zum Namen
357         // den ersten '\\', '/' oder ':' suchen
358         sal_uInt16 nPos;
359         for ( nPos = 0;
360               nPos < aPfad.Len() &&                             //?O
361                   aPfad.GetChar(nPos) != '\\' && aPfad.GetChar(nPos) != '/' &&      //?O
362                   aPfad.GetChar(nPos) != ':';                               //?O
363               nPos++ )
364             /* do nothing */;
365 
366         // ist der Name ein UNC Pathname?
367         if ( nPos == 0 && aPfad.Len() > 1 &&
368              ( ( aPfad.GetChar(0) == '\\' && aPfad.GetChar(1) == '\\' ) ||
369                ( aPfad.GetChar(0) == '/' && aPfad.GetChar(1) == '/' ) ) )
370         {
371             for ( nPos = 2; aPfad.Len() > nPos; ++nPos )
372                 if ( aPfad.GetChar(nPos) == '\\' || aPfad.GetChar(nPos) == '/' )
373                     break;
374             aName = ByteString( aPfad.Copy( 2, nPos-2 ), osl_getThreadTextEncoding() );
375             aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) );
376         }
377         // ist der Name die Root des aktuellen Drives?
378         else if ( nPos == 0 && aPfad.Len() > 0 &&
379                   ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
380         {
381             // Root-Directory des aktuellen Drives
382             aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
383         }
384         else
385         {
386             // ist der Name ein Drive?
387             if ( nPos < aPfad.Len() && aPfad.GetChar(nPos) == ':' )
388             {
389                 aName = ByteString( aPfad.Copy( 0, nPos + 1 ), osl_getThreadTextEncoding() );
390 
391                 // ist der Name die Root des Drives
392                 if ( (nPos + 1) < aPfad.Len() &&
393                      ( aPfad.GetChar(nPos+1) == '\\' || aPfad.GetChar(nPos+1) == '/' ) )
394                 {
395                     // schon was auf dem Stack?
396                     // oder Novell-Format? (not supported wegen URLs)
397                         if ( aStack.Count() || aName.Len() > 2 )
398                         {
399                             aName = rPfad;
400                             return FSYS_ERR_MISPLACEDCHAR;
401                         }
402                     // Root-Directory des Drive
403                     aStack.Push( new DirEntry( aName, FSYS_FLAG_ABSROOT, eStyle ) );
404                 }
405                 else
406                 {
407                     // liegt ein anderes Drive auf dem Stack?
408                     if ( aStack.Count() &&
409                          COMPARE_EQUAL != aStack.Bottom()->aName.CompareIgnoreCaseToAscii(aName) )
410                         aStack.Clear();
411 
412                     // liegt jetzt nichts mehr auf dem Stack?
413                     if ( !aStack.Count() )
414                         aStack.Push( new DirEntry( aName, FSYS_FLAG_RELROOT, eStyle ) );
415                 }
416             }
417 
418             // es ist kein Drive
419             else
420             {
421                 // den Namen ohne Trenner abspalten
422                 aName = ByteString( aPfad.Copy( 0, nPos ), osl_getThreadTextEncoding() );
423 
424                 // stellt der Name die aktuelle Directory dar?
425                 if ( aName == "." )
426                     /* do nothing */;
427 
428                 // stellt der Name die Parent-Directory dar?
429                 else if ( aName == ".." )
430                 {
431                     // ist nichts, ein Parent oder eine relative Root
432                     // auf dem Stack?
433                     if ( ( aStack.Count() == 0 ) ||
434                          ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) ||
435                          ( aStack.Top()->eFlag == FSYS_FLAG_RELROOT ) )
436                         // fuehrende Parents kommen auf den Stack
437                         aStack.Push( new DirEntry( FSYS_FLAG_PARENT ) );
438 
439                     // ist es eine absolute Root
440                     else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT )
441                     {
442                         // die hat keine Parent-Directory
443                         aName = rPfad;
444                         return FSYS_ERR_NOTEXISTS;
445                     }
446                     else
447                         // sonst hebt der Parent den TOS auf
448                         delete aStack.Pop();
449                 }
450 
451                 else
452                 {
453                     if ( eStyle == FSYS_STYLE_FAT )
454                     {
455                         // ist der Name grundsaetzlich ungueltig?
456                         int         nPunkte = 0;
457                         const char *pChar;
458                         for ( pChar = aName.GetBuffer();
459                               nPunkte < 2 && *pChar != 0;
460                               pChar++ )
461                         {
462                             if ( *pChar == ';' )
463                                 nPunkte = 0;
464                             else
465                                 nPunkte += ( *pChar == '.' ) ? 1 : 0;
466                         }
467                         if ( nPunkte > 1 )
468                         {
469                             aName = rPfad;
470                             return FSYS_ERR_MISPLACEDCHAR;
471                         }
472                     }
473 
474                     // normalen Entries kommen auf den Stack
475                                         DirEntry *pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle );
476                                         if ( !pNew->IsValid() )
477                                         {
478                                                 aName = rPfad;
479                                                 ErrCode eErr = pNew->GetError();
480                                                 delete pNew;
481                                                 return eErr;
482                                         }
483                     aStack.Push( pNew );
484                 }
485             }
486         }
487 
488         // den Restpfad bestimmen
489         aPfad.Erase( 0, nPos + 1 );
490         while ( aPfad.Len() && ( aPfad.GetChar(0) == '\\' || aPfad.GetChar(0) == '/' ) )
491             aPfad.Erase( 0, 1 );
492     }
493     while ( aPfad.Len() );
494 
495     sal_uIntPtr nErr = ERRCODE_NONE;
496     // Haupt-Entry (selbst) zuweisen
497     if ( aStack.Count() == 0 )
498     {
499         eFlag = FSYS_FLAG_CURRENT;
500         aName.Erase();
501     }
502     else
503     {
504         eFlag = aStack.Top()->eFlag;
505         aName = aStack.Top()->aName;
506         nErr = aStack.Top()->nError;
507         delete aStack.Pop();
508     }
509 
510     // die Parent-Entries vom Stack holen
511     DirEntry** pTemp = &pParent; // Zeiger auf den Member pParent setzen
512     while ( aStack.Count() )
513     {
514         *pTemp = aStack.Pop();
515 
516         // Zeiger auf den Member pParent des eigenen Parent setzen
517         pTemp = &( (*pTemp)->pParent );
518     }
519 
520     // wird damit ein Volume beschrieben?
521     if ( !pParent && eFlag == FSYS_FLAG_RELROOT && aName.Len() )
522         eFlag = FSYS_FLAG_VOLUME;
523 
524     // bei gesetztem ErrorCode den Namen komplett "ubernehmen
525     if ( nErr )
526         aName = rPfad;
527     return nErr;
528 }
529 
530 /*************************************************************************
531 |*
532 |*    DirEntry::ImpParseName()
533 |*
534 |*    Beschreibung      FSYS.SDW
535 |*    Ersterstellung    MI 26.08.91
536 |*    Letzte Aenderung  MI 26.05.93
537 |*
538 *************************************************************************/
539 
ImpParseName(const ByteString & rbInitName,FSysPathStyle eStyle)540 FSysError DirEntry::ImpParseName( const ByteString& rbInitName,
541                                   FSysPathStyle eStyle )
542 {
543 	String	rInitName( rbInitName, osl_getThreadTextEncoding() );
544     if ( eStyle == FSYS_STYLE_HOST )
545         eStyle = DEFSTYLE;
546 
547     // KI-Division of FSys
548     if ( eStyle == FSYS_STYLE_DETECT )
549     {
550         sal_Unicode cFirst = rInitName.GetChar(0);
551         if ( rInitName.Len() == 2 && rInitName.GetChar(1) == ':' &&
552              ((cFirst >= 'A' && cFirst <= 'Z') ||
553               (cFirst >= 'a' && cFirst <= 'z')))
554            eStyle = FSYS_STYLE_HPFS;
555         else if ( rInitName.Len() > 2 && rInitName.GetChar(1) == ':' )
556         {
557             if ( rInitName.Search( ':', 2 ) == STRING_NOTFOUND )
558                 eStyle = FSYS_STYLE_HPFS;
559             else
560                 eStyle = FSYS_STYLE_MAC;
561         }
562         else if ( rInitName.Search( '/' ) != STRING_NOTFOUND )
563             eStyle = FSYS_STYLE_BSD;
564         else if ( rInitName.Search( '\\' ) != STRING_NOTFOUND )
565             eStyle = FSYS_STYLE_HPFS;
566         else if ( rInitName.Search( ':' ) != STRING_NOTFOUND )
567             eStyle = FSYS_STYLE_MAC;
568         else
569             eStyle = FSYS_STYLE_HPFS;
570     }
571 
572     switch ( eStyle )
573     {
574         case FSYS_STYLE_FAT:
575         case FSYS_STYLE_VFAT:
576         case FSYS_STYLE_HPFS:
577         case FSYS_STYLE_NTFS:
578         case FSYS_STYLE_NWFS:
579             return ImpParseOs2Name( rbInitName, eStyle );
580 
581         case FSYS_STYLE_BSD:
582         case FSYS_STYLE_SYSV:
583             return ImpParseUnixName( rbInitName, eStyle );
584 
585         case FSYS_STYLE_MAC:
586             return FSYS_ERR_OK;
587 
588         default:
589             return FSYS_ERR_UNKNOWN;
590     }
591 }
592 
593 /*************************************************************************
594 |*
595 |*    GetStyle()
596 |*
597 |*    Beschreibung      FSYS.SDW
598 |*    Ersterstellung    MI 15.11.91
599 |*    Letzte Aenderung  MI 15.11.91
600 |*
601 *************************************************************************/
602 
GetStyle(FSysPathStyle eStyle)603 static FSysPathStyle GetStyle( FSysPathStyle eStyle )
604 {
605     if ( eStyle == FSYS_STYLE_HOST || eStyle == FSYS_STYLE_DETECT )
606         return DEFSTYLE;
607     else
608         return eStyle;
609 }
610 
611 /*************************************************************************
612 |*
613 |*    DirEntry::ImpTrim()
614 |*
615 |*    Beschreibung      bringt den Namen auf Betriebssystem-Norm
616 |*                      z.B. 8.3 lower beim MS-DOS Formatter
617 |*                      wirkt nicht rekursiv
618 |*    Ersterstellung    MI 12.08.91
619 |*    Letzte Aenderung  MI 21.05.92
620 |*
621 *************************************************************************/
622 
ImpTrim(FSysPathStyle eStyle)623 void DirEntry::ImpTrim( FSysPathStyle eStyle )
624 {
625     // Wildcards werden nicht geclipt
626     if ( ( aName.Search( '*' ) != STRING_NOTFOUND ) ||
627          ( aName.Search( '?' ) != STRING_NOTFOUND ) ||
628          ( aName.Search( ';' ) != STRING_NOTFOUND ) )
629         return;
630 
631     switch ( eStyle )
632     {
633         case FSYS_STYLE_FAT:
634         {
635             sal_uInt16 nPunktPos = aName.Search( '.' );
636             if ( nPunktPos == STRING_NOTFOUND )
637             {
638                 if ( aName.Len() > 8 )
639                 {
640                     nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
641                     aName.Erase( 8 );
642                 }
643             }
644             else
645             {
646                 if ( nPunktPos > 8 )
647                 {
648                     nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
649                     aName.Erase( 8, nPunktPos - 8 );
650                     nPunktPos = 8;
651                 }
652                 if ( aName.Len() > nPunktPos + 3 )
653                 {
654                     if ( aName.Len() - nPunktPos > 4 )
655                     {
656                         nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
657                         aName.Erase( nPunktPos + 4 );
658                     }
659                 }
660             }
661             aName.ToLowerAscii();
662             break;
663         }
664 
665         case FSYS_STYLE_VFAT:
666         case FSYS_STYLE_HPFS:
667         case FSYS_STYLE_NTFS:
668         case FSYS_STYLE_NWFS:
669             if ( aName.Len() > 254 )
670             {
671                 nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
672                 aName.Erase( 254 );
673             }
674 
675             if ( eStyle == FSYS_STYLE_HPFS &&
676                  ( eFlag == FSYS_FLAG_ABSROOT || eFlag == FSYS_FLAG_RELROOT ) )
677                 aName.ToUpperAscii();
678             break;
679 
680         case FSYS_STYLE_SYSV:
681             if ( aName.Len() > 14 )
682             {
683                 nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
684                 aName.Erase( 14 );
685             }
686             break;
687 
688         case FSYS_STYLE_BSD:
689             if ( aName.Len() > 250 )
690             {
691                 nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
692                 aName.Erase( 250 );
693             }
694             break;
695 
696         case FSYS_STYLE_MAC:
697             if ( eFlag & ( FSYS_FLAG_ABSROOT | FSYS_FLAG_VOLUME ) )
698             {
699                 if ( aName.Len() > 27 )
700                 {
701                     nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
702                     aName.Erase( 27 );
703                 }
704             }
705             else
706             {
707                 if ( aName.Len() > 31 )
708                 {
709                     nError = ERRCODE_IO_MISPLACEDCHAR|ERRCODE_WARNING_MASK;
710                     aName.Erase( 31 );
711                 }
712             }
713             break;
714 
715         default:
716             /* kann nicht sein */;
717     }
718 }
719 
720 /*************************************************************************
721 |*
722 |*    DirEntry::DirEntry()
723 |*
724 |*    Beschreibung      FSYS.SDW
725 |*    Ersterstellung    MI 26.04.91
726 |*    Letzte Aenderung  MA 02.12.91
727 |*
728 *************************************************************************/
729 
DirEntry(const ByteString & rName,DirEntryFlag eDirFlag,FSysPathStyle eStyle)730 DirEntry::DirEntry( const ByteString& rName, DirEntryFlag eDirFlag,
731                     FSysPathStyle eStyle ) :
732 #ifdef FEAT_FSYS_DOUBLESPEED
733             pStat( 0 ),
734 #endif
735             aName( rName )
736 {
737     DBG_CTOR( DirEntry, ImpCheckDirEntry );
738 
739     pParent         = NULL;
740     eFlag           = eDirFlag;
741     nError          = FSYS_ERR_OK;
742 
743     ImpTrim( eStyle );
744 }
745 
746 /*************************************************************************
747 |*
748 |*    DirEntry::DirEntry()
749 |*
750 |*    Beschreibung      FSYS.SDW
751 |*    Ersterstellung    MI 26.04.91
752 |*    Letzte Aenderung  MA 02.12.91
753 |*
754 *************************************************************************/
755 
DirEntry(const DirEntry & rOrig)756 DirEntry::DirEntry( const DirEntry& rOrig ) :
757 #ifdef FEAT_FSYS_DOUBLESPEED
758             pStat( rOrig.pStat ? new FileStat(*rOrig.pStat) : 0 ),
759 #endif
760             aName( rOrig.aName )
761 {
762     DBG_CTOR( DirEntry, ImpCheckDirEntry );
763 
764     eFlag           = rOrig.eFlag;
765     nError          = rOrig.nError;
766 
767     if ( rOrig.pParent )
768     {
769         pParent = new DirEntry( *rOrig.pParent );
770     }
771     else
772     {
773         pParent = NULL;
774     }
775 }
776 
777 /*************************************************************************
778 |*
779 |*    DirEntry::DirEntry()
780 |*
781 |*    Beschreibung      FSYS.SDW
782 |*    Ersterstellung    MI 26.04.91
783 |*    Letzte Aenderung  MA 02.12.91
784 |*
785 *************************************************************************/
786 
DirEntry(const String & rInitName,FSysPathStyle eStyle)787 DirEntry::DirEntry( const String& rInitName, FSysPathStyle eStyle )
788 #ifdef FEAT_FSYS_DOUBLESPEED
789             : pStat( 0 )
790 #endif
791 {
792     DBG_CTOR( DirEntry, ImpCheckDirEntry );
793 
794     pParent         = NULL;
795 
796     // schnelle Loesung fuer Leerstring
797     if ( !rInitName.Len())
798     {
799         eFlag                   = FSYS_FLAG_CURRENT;
800         nError                  = FSYS_ERR_OK;
801         return;
802     }
803 
804     ByteString aTmpName(rInitName, osl_getThreadTextEncoding());
805     if( eStyle == FSYS_STYLE_URL || aTmpName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL )
806     {
807 #ifndef BOOTSTRAP
808         DBG_WARNING( "File URLs are not permitted but accepted" );
809         aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding());
810                 eStyle = FSYS_STYLE_HOST;
811 #endif // BOOTSTRAP
812     }
813     else
814     {
815         ::rtl::OUString aTmp;
816         ::rtl::OUString aOInitName;
817         if ( FileBase::getFileURLFromSystemPath( OUString( rInitName ), aTmp ) == FileBase::E_None )
818         {
819 			aOInitName = OUString( rInitName );
820             aTmpName = ByteString( String(aOInitName), osl_getThreadTextEncoding() );
821         }
822 
823 #ifdef DBG_UTIL
824         // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
825         if( eStyle == FSYS_STYLE_HOST &&
826             aTmpName.Search( "://" ) != STRING_NOTFOUND )
827         {
828             ByteString aErr = "DirEntries akzeptieren nur File URLS: ";
829             aErr += aTmpName;
830             DBG_WARNING( aErr.GetBuffer() );
831         }
832 #endif
833     }
834 
835     nError  = ImpParseName( aTmpName, eStyle );
836 
837     if ( nError != FSYS_ERR_OK )
838         eFlag = FSYS_FLAG_INVALID;
839 }
840 
841 /*************************************************************************/
842 
DirEntry(const ByteString & rInitName,FSysPathStyle eStyle)843 DirEntry::DirEntry( const ByteString& rInitName, FSysPathStyle eStyle )
844 #ifdef FEAT_FSYS_DOUBLESPEED
845             : pStat( 0 )
846 #endif
847 {
848     DBG_CTOR( DirEntry, ImpCheckDirEntry );
849 
850     pParent         = NULL;
851 
852     // schnelle Loesung fuer Leerstring
853     if ( !rInitName.Len() )
854     {
855         eFlag                   = FSYS_FLAG_CURRENT;
856         nError                  = FSYS_ERR_OK;
857         return;
858     }
859 
860     ByteString aTmpName( rInitName );
861 	if( eStyle == FSYS_STYLE_URL || rInitName.CompareIgnoreCaseToAscii("file:",5 ) == COMPARE_EQUAL )
862     {
863 #ifndef BOOTSTRAP
864         DBG_WARNING( "File URLs are not permitted but accepted" );
865         aTmpName = ByteString(String(INetURLObject( rInitName ).PathToFileName()), osl_getThreadTextEncoding());
866 		eStyle = FSYS_STYLE_HOST;
867 #endif
868     }
869 #ifdef DBG_UTIL
870     else
871         // ASF nur bei Default eStyle, nicht z.B. aus MakeShortName()
872         if( eStyle == FSYS_STYLE_HOST &&
873             rInitName.Search( "://" ) != STRING_NOTFOUND )
874         {
875             ByteString aErr = "DirEntries akzeptieren nur File URLS: ";
876             aErr += rInitName;
877             DBG_WARNING( aErr.GetBuffer() );
878         }
879 #endif
880 
881     nError  = ImpParseName( aTmpName, eStyle );
882 
883     if ( nError != FSYS_ERR_OK )
884         eFlag = FSYS_FLAG_INVALID;
885 }
886 
887 /*************************************************************************
888 |*
889 |*    DirEntry::DirEntry()
890 |*
891 |*    Beschreibung      FSYS.SDW
892 |*    Ersterstellung    MI 26.04.91
893 |*    Letzte Aenderung  MA 02.12.91
894 |*
895 *************************************************************************/
896 
DirEntry(DirEntryFlag eDirFlag)897 DirEntry::DirEntry( DirEntryFlag eDirFlag )
898 #ifdef FEAT_FSYS_DOUBLESPEED
899             : pStat( 0 )
900 #endif
901 {
902     DBG_CTOR( DirEntry, ImpCheckDirEntry );
903 
904     eFlag           = eDirFlag;
905     nError          = ( eFlag == FSYS_FLAG_INVALID ) ? FSYS_ERR_UNKNOWN : FSYS_ERR_OK;
906     pParent         = NULL;
907 }
908 
909 /*************************************************************************
910 |*
911 |*    DirEntry::~DirEntry()
912 |*
913 |*    Beschreibung      FSYS.SDW
914 |*    Ersterstellung    MI 26.04.91
915 |*    Letzte Aenderung  MA 02.12.91
916 |*
917 *************************************************************************/
918 
~DirEntry()919 DirEntry::~DirEntry()
920 {
921     DBG_DTOR( DirEntry, ImpCheckDirEntry );
922 
923     delete pParent;
924 #ifdef FEAT_FSYS_DOUBLESPEED
925     delete pStat;
926 #endif
927 
928 }
929 
930 /*************************************************************************
931 |*
932 |*    DirEntry::ImpGetTopPtr() const
933 |*
934 |*    Beschreibung      FSYS.SDW
935 |*    Ersterstellung    MI 26.04.91
936 |*    Letzte Aenderung  MA 02.12.91
937 |*
938 *************************************************************************/
939 
ImpGetTopPtr() const940 const DirEntry* DirEntry::ImpGetTopPtr() const
941 {
942     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
943 
944     const DirEntry *pTemp = this;
945     while ( pTemp->pParent )
946         pTemp = pTemp->pParent;
947 
948     return pTemp;
949 }
950 
951 /*************************************************************************
952 |*
953 |*    DirEntry::ImpGetTopPtr()
954 |*
955 |*    Beschreibung      FSYS.SDW
956 |*    Ersterstellung    MI 13.11.91
957 |*    Letzte Aenderung  MA 02.12.91
958 |*
959 *************************************************************************/
960 
ImpGetTopPtr()961 DirEntry* DirEntry::ImpGetTopPtr()
962 {
963     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
964 
965     DirEntry *pTemp = this;
966     while ( pTemp->pParent )
967         pTemp = pTemp->pParent;
968 
969     return pTemp;
970 }
971 
972 /*************************************************************************
973 |*
974 |*    DirEntry::ImpGetPreTopPtr()
975 |*
976 |*    Beschreibung      liefert einen Pointer auf den vorletzten Entry
977 |*    Ersterstellung    MI 01.11.91
978 |*    Letzte Aenderung  MA 02.12.91
979 |*
980 *************************************************************************/
981 
ImpGetPreTopPtr()982 DirEntry* DirEntry::ImpGetPreTopPtr()
983 {
984     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
985 
986     DirEntry *pTemp = this;
987     if ( pTemp->pParent )
988     {
989         while ( pTemp->pParent->pParent )
990             pTemp = pTemp->pParent;
991     }
992 
993     return pTemp;
994 }
995 
996 /*************************************************************************
997 |*
998 |*    DirEntry::ImpChangeParent()
999 |*
1000 |*    Beschreibung      FSYS.SDW
1001 |*    Ersterstellung    MI 26.04.91
1002 |*    Letzte Aenderung  MI 21.05.92
1003 |*
1004 *************************************************************************/
1005 
ImpChangeParent(DirEntry * pNewParent,sal_Bool bNormalize)1006 DirEntry* DirEntry::ImpChangeParent( DirEntry* pNewParent, sal_Bool bNormalize )
1007 {
1008     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1009 
1010     DirEntry *pTemp = pParent;
1011     if ( bNormalize && pNewParent &&
1012          pNewParent->eFlag == FSYS_FLAG_RELROOT && !pNewParent->aName.Len() )
1013     {
1014         pParent = 0;
1015         delete pNewParent;
1016     }
1017     else
1018         pParent = pNewParent;
1019 
1020     return pTemp;
1021 }
1022 
1023 /*************************************************************************
1024 |*
1025 |*    DirEntry::Exists()
1026 |*
1027 |*    Beschreibung      FSYS.SDW
1028 |*    Ersterstellung    MI 26.04.91
1029 |*    Letzte Aenderung  MI 24.09.91
1030 |*
1031 *************************************************************************/
1032 
Exists(FSysAccess nAccess) const1033 sal_Bool DirEntry::Exists( FSysAccess nAccess ) const
1034 {
1035 #ifndef BOOTSTRAP
1036 	static vos::OMutex aLocalMutex;
1037 	vos::OGuard aGuard( aLocalMutex );
1038 #endif
1039         if ( !IsValid() )
1040                 return sal_False;
1041 
1042 #if defined WNT || defined OS2
1043     // spezielle Filenamen sind vom System da
1044     if ( ( aName.CompareIgnoreCaseToAscii("CLOCK$") == COMPARE_EQUAL ||
1045            aName.CompareIgnoreCaseToAscii("CON") == COMPARE_EQUAL ||
1046            aName.CompareIgnoreCaseToAscii("AUX") == COMPARE_EQUAL ||
1047            aName.CompareIgnoreCaseToAscii("COM1") == COMPARE_EQUAL ||
1048            aName.CompareIgnoreCaseToAscii("COM2") == COMPARE_EQUAL ||
1049            aName.CompareIgnoreCaseToAscii("COM3") == COMPARE_EQUAL ||
1050            aName.CompareIgnoreCaseToAscii("COM4") == COMPARE_EQUAL ||
1051            aName.CompareIgnoreCaseToAscii("LPT1") == COMPARE_EQUAL ||
1052            aName.CompareIgnoreCaseToAscii("LPT2") == COMPARE_EQUAL ||
1053            aName.CompareIgnoreCaseToAscii("LPT3") == COMPARE_EQUAL ||
1054            aName.CompareIgnoreCaseToAscii("NUL") == COMPARE_EQUAL ||
1055            aName.CompareIgnoreCaseToAscii("PRN") == COMPARE_EQUAL ) )
1056         return sal_True;
1057 #endif
1058 
1059         FSysFailOnErrorImpl();
1060         DirEntryKind eKind = FileStat( *this, nAccess ).GetKind();
1061         if ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) )
1062         {
1063                 return sal_True;
1064         }
1065 
1066 #if defined WNT || defined OS2
1067         if ( 0 != ( eKind & FSYS_KIND_DEV ) )
1068         {
1069                 return DRIVE_EXISTS( ImpGetTopPtr()->aName.GetChar(0) );
1070         }
1071 #endif
1072 
1073         return 0 != ( eKind & ( FSYS_KIND_FILE | FSYS_KIND_DIR ) );
1074 }
1075 
1076 /*************************************************************************
1077 |*
1078 |*    DirEntry::First()
1079 |*
1080 |*    Beschreibung      FSYS.SDW
1081 |*    Ersterstellung    MI 26.04.91
1082 |*    Letzte Aenderung  MA 15.01.92
1083 |*
1084 *************************************************************************/
1085 
First()1086 sal_Bool DirEntry::First()
1087 {
1088     FSysFailOnErrorImpl();
1089 
1090         String    aUniPathName( GetPath().GetFull() );
1091 #ifndef BOOTSTRAP
1092         FSysRedirector::DoRedirect( aUniPathName );
1093 		ByteString aPathName(aUniPathName, osl_getThreadTextEncoding());
1094 #else
1095 		ByteString aPathName(aUniPathName, gsl_getSystemTextEncoding());
1096 #endif
1097         aPathName = GUI2FSYS( aPathName );
1098 
1099         DIR      *pDir = opendir( (char*) aPathName.GetBuffer() );
1100         if ( pDir )
1101         {
1102 #ifndef BOOTSTRAP
1103                 WildCard aWildeKarte( String(CMP_LOWER( aName ), osl_getThreadTextEncoding()) );
1104 #else
1105                 WildCard aWildeKarte( String(CMP_LOWER( aName ), gsl_getSystemTextEncoding()) );
1106 #endif
1107                 for ( dirent* pEntry = readdir( pDir );
1108                           pEntry;
1109                           pEntry = readdir( pDir ) )
1110                 {
1111                         ByteString aFound( FSYS2GUI( ByteString( pEntry->d_name ) ) );
1112                         if ( aWildeKarte.Matches( String(CMP_LOWER( aFound ), osl_getThreadTextEncoding())))
1113                         {
1114                                 aName = aFound;
1115                                 closedir( pDir );
1116                                 return sal_True;
1117                         }
1118                 }
1119                 closedir( pDir );
1120         }
1121         return sal_False;
1122 }
1123 
1124 /*************************************************************************
1125 |*
1126 |*    DirEntry::GetFull()
1127 |*
1128 |*    Beschreibung      FSYS.SDW
1129 |*    Ersterstellung    MI 26.04.91
1130 |*    Letzte Aenderung  MA 02.12.91
1131 |*
1132 *************************************************************************/
1133 
GetFull(FSysPathStyle eStyle,sal_Bool bWithDelimiter,sal_uInt16 nMaxChars) const1134 String DirEntry::GetFull( FSysPathStyle eStyle, sal_Bool bWithDelimiter,
1135                           sal_uInt16 nMaxChars ) const
1136 {
1137     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1138 
1139     ByteString aRet;
1140     eStyle = GetStyle( eStyle );
1141     if ( pParent )
1142     {
1143         if ( ( pParent->eFlag == FSYS_FLAG_ABSROOT ||
1144                pParent->eFlag == FSYS_FLAG_RELROOT ||
1145                pParent->eFlag == FSYS_FLAG_VOLUME ) )
1146         {
1147             aRet  = ByteString(pParent->GetName( eStyle ), osl_getThreadTextEncoding());
1148             aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
1149         }
1150         else
1151         {
1152             aRet  = ByteString(pParent->GetFull( eStyle ), osl_getThreadTextEncoding());
1153             aRet += ACCESSDELIM_C(eStyle);
1154             aRet += ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
1155         }
1156     }
1157     else
1158     {
1159         aRet = ByteString(GetName( eStyle ), osl_getThreadTextEncoding());
1160     }
1161 
1162     if ( ( eStyle == FSYS_STYLE_MAC ) &&
1163          ( ImpGetTopPtr()->eFlag != FSYS_FLAG_VOLUME )  &&
1164          ( ImpGetTopPtr()->eFlag != FSYS_FLAG_ABSROOT ) &&
1165          ( aRet.GetChar(0) != ':' ) )
1166         aRet.Insert( ACCESSDELIM_C(eStyle), 0 );
1167 
1168     //! Hack
1169     if ( bWithDelimiter )
1170         if ( aRet.GetChar( aRet.Len()-1 ) != ACCESSDELIM_C(eStyle) )
1171             aRet += ACCESSDELIM_C(eStyle);
1172 
1173     //! noch ein Hack
1174     if ( nMaxChars < STRING_MAXLEN )
1175         aRet = ImplCutPath( aRet, nMaxChars, ACCESSDELIM_C(eStyle) );
1176 
1177     return String(aRet, osl_getThreadTextEncoding());
1178 }
1179 
1180 /*************************************************************************
1181 |*
1182 |*    DirEntry::GetPath()
1183 |*
1184 |*    Beschreibung      FSYS.SDW
1185 |*    Ersterstellung    MI 26.04.91
1186 |*    Letzte Aenderung  MA 02.12.91
1187 |*
1188 *************************************************************************/
1189 
GetPath() const1190 DirEntry DirEntry::GetPath() const
1191 {
1192     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1193 
1194     if ( pParent )
1195         return DirEntry( *pParent );
1196 
1197     return DirEntry();
1198 }
1199 
1200 /*************************************************************************
1201 |*
1202 |*    DirEntry::GetExtension()
1203 |*
1204 |*    Beschreibung      FSYS.SDW
1205 |*    Ersterstellung    MI 26.04.91
1206 |*    Letzte Aenderung  MA 02.12.91
1207 |*
1208 *************************************************************************/
1209 
GetExtension(char cSep) const1210 String DirEntry::GetExtension( char cSep ) const
1211 {
1212     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1213 
1214     const char *p0 = ( aName.GetBuffer() );
1215     const char *p1 = p0 + aName.Len() - 1;
1216     while ( p1 >= p0 && *p1 != cSep )
1217     p1--;
1218 
1219     if ( p1 >= p0 )
1220         // es wurde ein cSep an der Position p1 gefunden
1221         return String(
1222             aName.Copy( static_cast< xub_StrLen >(p1 - p0 + 1) ),
1223             osl_getThreadTextEncoding());
1224     return String();
1225 }
1226 
1227 /*************************************************************************
1228 |*
1229 |*    DirEntry::GetBase()
1230 |*
1231 |*    Beschreibung      FSYS.SDW
1232 |*    Ersterstellung    MI 26.04.91
1233 |*    Letzte Aenderung  MA 02.12.91
1234 |*
1235 *************************************************************************/
1236 
GetBase(char cSep) const1237 String DirEntry::GetBase( char cSep ) const
1238 {
1239     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1240 
1241     const char *p0 = ( aName.GetBuffer() );
1242     const char *p1 = p0 + aName.Len() - 1;
1243     while ( p1 >= p0 && *p1 != cSep )
1244         p1--;
1245 
1246     if ( p1 >= p0 )
1247         // es wurde ein cSep an der Position p1 gefunden
1248         return String(
1249             aName.Copy( 0, static_cast< xub_StrLen >(p1 - p0) ),
1250             osl_getThreadTextEncoding());
1251 
1252     else
1253         // es wurde kein cSep gefunden
1254         return String(aName, osl_getThreadTextEncoding());
1255 }
1256 
1257 /*************************************************************************
1258 |*
1259 |*    DirEntry::GetName()
1260 |*
1261 |*    Beschreibung      FSYS.SDW
1262 |*    Ersterstellung    MI 26.04.91
1263 |*    Letzte Aenderung  MA 02.12.91 13:47
1264 |*
1265 *************************************************************************/
1266 
GetName(FSysPathStyle eStyle) const1267 String DirEntry::GetName( FSysPathStyle eStyle ) const
1268 {
1269     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1270 
1271     ByteString aRet;
1272     eStyle = GetStyle( eStyle );
1273 
1274     switch( eFlag )
1275     {
1276         case FSYS_FLAG_PARENT:
1277             aRet = ACTPARENT(eStyle);
1278                         break;
1279 
1280         case FSYS_FLAG_ABSROOT:
1281         {
1282             if ( eStyle == FSYS_STYLE_URL )
1283             {
1284                 aRet = "file:///";
1285                 aRet += aName;
1286 
1287 #ifndef UNX
1288                 if ( aName.Len())
1289                 {
1290                     if ( aName.GetChar(aName.Len()-1) == ':' )
1291                     {
1292                         aRet.SetChar(aRet.Len()-1, '|');
1293                     }
1294                     else
1295                     {
1296                         aRet.Insert( '/', 5 );
1297                     }
1298                     aRet += "/";
1299                 }
1300 #endif
1301             }
1302             else if ( eStyle != FSYS_STYLE_MAC &&
1303                                  aName.Len() > 1 && aName.GetChar( 1 ) != ':'  )
1304             {
1305                 // UNC-Pathname
1306                 aRet = ACCESSDELIM_C(eStyle);
1307                 aRet += ACCESSDELIM_C(eStyle);
1308                 aRet += aName ;
1309                 aRet += ACCESSDELIM_C(eStyle);
1310             }
1311             else
1312             {
1313                 aRet = aName;
1314                 aRet += ACCESSDELIM_C(eStyle);
1315             }
1316             break;
1317         }
1318 
1319         case FSYS_FLAG_INVALID:
1320         case FSYS_FLAG_VOLUME:
1321         {
1322             if ( eStyle == FSYS_STYLE_URL )
1323             {
1324                 aRet = "file:///";
1325                 aRet += aName;
1326 #ifndef UNX
1327 				if ( aName.Len() && aName.GetChar(aName.Len()-1) == ':' )
1328 				{
1329 					aRet.SetChar(aRet.Len()-1, '|');
1330 				}
1331 #endif
1332             }
1333             else
1334 			{
1335                 aRet = aName;
1336 			}
1337 
1338             break;
1339         }
1340 
1341         case FSYS_FLAG_RELROOT:
1342             if ( !aName.Len() )
1343             {
1344                 aRet = ACTCURRENT(eStyle);
1345                 break;
1346             }
1347 
1348         default:
1349             aRet = aName;
1350     }
1351 
1352     return String(aRet, osl_getThreadTextEncoding());
1353 }
1354 
1355 /*************************************************************************
1356 |*
1357 |*    DirEntry::IsAbs()
1358 |*
1359 |*    Beschreibung      FSYS.SDW
1360 |*    Ersterstellung    MI 26.04.91
1361 |*    Letzte Aenderung  MA 02.12.91
1362 |*
1363 *************************************************************************/
1364 
IsAbs() const1365 bool DirEntry::IsAbs() const
1366 {
1367     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1368 
1369 #ifdef UNX
1370     return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT );
1371 #else
1372     return ( pParent ? pParent->IsAbs() : eFlag == FSYS_FLAG_ABSROOT && aName.Len() > 0 );
1373 #endif
1374 }
1375 
1376 /*************************************************************************
1377 |*
1378 |*    DirEntry::CutName()
1379 |*
1380 |*    Beschreibung      FSYS.SDW
1381 |*    Ersterstellung    MI 26.04.91
1382 |*    Letzte Aenderung  MA 02.12.91
1383 |*
1384 *************************************************************************/
1385 
CutName(FSysPathStyle eStyle)1386 String DirEntry::CutName( FSysPathStyle eStyle )
1387 {
1388     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1389 
1390     eStyle = GetStyle( eStyle );
1391 
1392     String aOldName( GetName( eStyle ) );
1393 
1394     if ( pParent )
1395     {
1396         DirEntry *pOldParent = pParent;
1397         if ( pOldParent )
1398         {
1399             pParent = pOldParent->pParent;
1400             eFlag = pOldParent->eFlag;
1401             aName = pOldParent->aName;
1402             pOldParent->pParent = NULL;
1403             delete pOldParent;
1404         }
1405         else
1406         {
1407             eFlag = FSYS_FLAG_CURRENT;
1408             aName.Erase();
1409         }
1410     }
1411     else
1412     {
1413         eFlag = FSYS_FLAG_CURRENT;
1414         aName.Erase();
1415         delete pParent;
1416         pParent = NULL;
1417     }
1418 
1419     return aOldName;
1420 }
1421 
1422 /*************************************************************************
1423 |*
1424 |*    DirEntry::NameCompare
1425 |*
1426 |*    Beschreibung      Vergleich nur die Namen (ohne Pfad, aber mit Gross/Klein)
1427 |*    Ersterstellung    MI 26.04.91
1428 |*    Letzte Aenderung  MA 02.12.91
1429 |*
1430 *************************************************************************/
1431 
NameCompare(const DirEntry & rWith) const1432 StringCompare DirEntry::NameCompare( const DirEntry &rWith ) const
1433 {
1434         ByteString aThisName;
1435         ByteString aParameterName;
1436 
1437 #ifdef UNX
1438                 aThisName = aName;
1439                 aParameterName = rWith.aName;
1440 #else
1441                 aThisName = ByteString(aName).ToLowerAscii();
1442                 aParameterName = ByteString(rWith.aName).ToLowerAscii();
1443 #endif
1444 
1445     return aThisName.CompareTo( aParameterName );
1446 }
1447 
1448 
1449 /*************************************************************************
1450 |*
1451 |*    DirEntry::operator==()
1452 |*
1453 |*    Beschreibung      FSYS.SDW
1454 |*    Ersterstellung    MI 26.04.91
1455 |*    Letzte Aenderung  MA 02.12.91
1456 |*
1457 *************************************************************************/
1458 
operator ==(const DirEntry & rEntry) const1459 sal_Bool DirEntry::operator==( const DirEntry& rEntry ) const
1460 {
1461     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1462 
1463     // test whether the contents are textual the same
1464 
1465     if ( nError && ( nError == rEntry.nError ) )
1466         return sal_True;
1467     if ( nError || rEntry.nError ||
1468          ( eFlag == FSYS_FLAG_INVALID ) ||
1469          ( rEntry.eFlag == FSYS_FLAG_INVALID ) )
1470         return sal_False;
1471 
1472 #ifndef OS2
1473     const
1474 #endif
1475 	DirEntry *pThis = (DirEntry *)this;
1476 #ifndef OS2
1477     const
1478 #endif
1479 	DirEntry *pWith = (DirEntry *)&rEntry;
1480     while( pThis && pWith && (pThis->eFlag == pWith->eFlag) )
1481     {
1482         if ( CMP_LOWER(pThis->aName) != CMP_LOWER(pWith->aName) )
1483             break;
1484         pThis = pThis->pParent;
1485         pWith = pWith->pParent;
1486     }
1487 
1488     return ( !pThis && !pWith );
1489 }
1490 
1491 /*************************************************************************
1492 |*
1493 |*    DirEntry::operator=()
1494 |*
1495 |*    Beschreibung      FSYS.SDW
1496 |*    Ersterstellung    MI 26.04.91
1497 |*    Letzte Aenderung  MA 02.12.91
1498 |*
1499 *************************************************************************/
1500 
operator =(const DirEntry & rEntry)1501 DirEntry& DirEntry::operator=( const DirEntry& rEntry )
1502 {
1503     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1504 
1505     if ( this == &rEntry )
1506         return *this;
1507     if ( rEntry.nError != FSYS_ERR_OK ) {
1508 		DBG_ERROR("Zuweisung mit invalidem DirEntry");
1509         nError = rEntry.nError;
1510         return *this;
1511     }
1512 
1513     // Name und Typ uebernehmen, Refs beibehalten
1514     aName                       = rEntry.aName;
1515     eFlag                       = rEntry.eFlag;
1516     nError                      = FSYS_ERR_OK;
1517 
1518     DirEntry *pOldParent = pParent;
1519     if ( rEntry.pParent )
1520         pParent = new DirEntry( *rEntry.pParent );
1521     else
1522         pParent = NULL;
1523 
1524     if ( pOldParent )
1525         delete pOldParent;
1526     return *this;
1527 }
1528 
1529 /*************************************************************************
1530 |*
1531 |*    DirEntry::operator+()
1532 |*
1533 |*    Beschreibung      FSYS.SDW
1534 |*    Ersterstellung    MI 26.04.91
1535 |*    Letzte Aenderung  MA 02.12.91
1536 |*
1537 *************************************************************************/
1538 
operator +(const DirEntry & rEntry) const1539 DirEntry DirEntry::operator+( const DirEntry& rEntry ) const
1540 {
1541     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1542 #ifdef DBG_UTIL
1543         static sal_Bool bTested = sal_False;
1544         if ( !bTested )
1545         {
1546                 bTested = sal_True;
1547                 FSysTest();
1548         }
1549 #endif
1550 
1551         const DirEntry *pEntryTop = rEntry.ImpGetTopPtr();
1552         const DirEntry *pThisTop = ImpGetTopPtr();
1553 
1554         // "." + irgendwas oder irgendwas + "d:irgendwas"
1555 /* TPF:org
1556     if ( ( eFlag == FSYS_FLAG_RELROOT && !aName ) ||
1557                  ( pEntryTop->aName.Len() &&
1558                         ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
1559                       pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
1560                           pEntryTop->eFlag == FSYS_FLAG_VOLUME ) ) )
1561                 return rEntry;
1562 */
1563 
1564     if (
1565         (eFlag == FSYS_FLAG_RELROOT && !aName.Len()) ||
1566         (
1567          (pEntryTop->aName.Len()  ||
1568           ((rEntry.Level()>1)?(rEntry[rEntry.Level()-2].aName.CompareIgnoreCaseToAscii(RFS_IDENTIFIER)==COMPARE_EQUAL):sal_False))
1569           &&
1570          (pEntryTop->eFlag == FSYS_FLAG_ABSROOT ||
1571           pEntryTop->eFlag == FSYS_FLAG_RELROOT ||
1572           pEntryTop->eFlag == FSYS_FLAG_VOLUME)
1573         )
1574        )
1575     {
1576                 return rEntry;
1577     }
1578 
1579     // irgendwas + "." (=> pEntryTop == &rEntry)
1580     if ( pEntryTop->eFlag == FSYS_FLAG_RELROOT && !pEntryTop->aName.Len() )
1581     {
1582                 DBG_ASSERT( pEntryTop == &rEntry, "DirEntry::op+ buggy" );
1583                 return *this;
1584     }
1585 
1586     // root += ".." (=> unmoeglich)
1587         if ( pEntryTop->eFlag == FSYS_FLAG_PARENT && pThisTop == this &&
1588                 ( eFlag == FSYS_FLAG_ABSROOT ) )
1589                 return DirEntry( FSYS_FLAG_INVALID );
1590 
1591         // irgendwas += abs (=> nur Device uebernehmen falls vorhanden)
1592         if ( pEntryTop->eFlag == FSYS_FLAG_ABSROOT )
1593         {
1594                 ByteString aDevice;
1595                 if ( pThisTop->eFlag == FSYS_FLAG_ABSROOT )
1596                         aDevice = pThisTop->aName;
1597                 DirEntry aRet = rEntry;
1598                 if ( aDevice.Len() )
1599                         aRet.ImpGetTopPtr()->aName = aDevice;
1600                 return aRet;
1601         }
1602 
1603         // irgendwas += ".." (=> aufloesen)
1604         if ( eFlag == FSYS_FLAG_NORMAL && pEntryTop->eFlag == FSYS_FLAG_PARENT )
1605         {
1606                 String aConcated( GetFull() );
1607                 aConcated += ACCESSDELIM_C(FSYS_STYLE_HOST);
1608                 aConcated += rEntry.GetFull();
1609                 return DirEntry( aConcated );
1610         }
1611 
1612         // sonst einfach hintereinander haengen
1613         DirEntry aRet( rEntry );
1614         DirEntry *pTop = aRet.ImpGetTopPtr();
1615         pTop->pParent = new DirEntry( *this );
1616 
1617         return aRet;
1618 }
1619 
1620 /*************************************************************************
1621 |*
1622 |*    DirEntry::operator+=()
1623 |*
1624 |*    Beschreibung      FSYS.SDW
1625 |*    Ersterstellung    MI 26.04.91
1626 |*    Letzte Aenderung  MA 02.12.91
1627 |*
1628 *************************************************************************/
1629 
operator +=(const DirEntry & rEntry)1630 DirEntry &DirEntry::operator+=( const DirEntry& rEntry )
1631 {
1632     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1633 
1634     return *this = *this + rEntry;
1635 }
1636 
1637 /*************************************************************************
1638 |*
1639 |*    DirEntry::GetAccessDelimiter()
1640 |*
1641 |*    Beschreibung      FSYS.SDW
1642 |*    Ersterstellung    MI 27.05.93
1643 |*    Letzte Aenderung  MI 10.06.93
1644 |*
1645 *************************************************************************/
1646 
GetAccessDelimiter(FSysPathStyle eFormatter)1647 String DirEntry::GetAccessDelimiter( FSysPathStyle eFormatter )
1648 {
1649         return String( ACCESSDELIM_C( GetStyle( eFormatter ) ) );
1650 }
1651 
1652 /*************************************************************************
1653 |*
1654 |*    DirEntry::SetExtension()
1655 |*
1656 |*    Beschreibung      FSYS.SDW
1657 |*    Ersterstellung    MI 02.08.91
1658 |*    Letzte Aenderung  MA 02.12.91
1659 |*
1660 *************************************************************************/
1661 
SetExtension(const String & rExtension,char cSep)1662 void DirEntry::SetExtension( const String& rExtension, char cSep )
1663 {
1664     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1665 
1666     // do not set extensions for drives
1667     if(eFlag == FSYS_FLAG_ABSROOT)
1668     {
1669         nError = FSYS_ERR_NOTSUPPORTED;
1670         return;
1671     }
1672 
1673     // cSep im Namen suchen
1674     const char *p0 = ( aName.GetBuffer() );
1675     const char *p1 = p0 + aName.Len() - 1;
1676     while ( p1 >= p0 && *p1 != cSep )
1677         p1--;
1678     if ( p1 >= p0 )
1679     {
1680         // es wurde ein cSep an der Position p1 gefunden
1681         aName.Erase(
1682             static_cast< xub_StrLen >(
1683                 p1 - p0 + 1 - ( rExtension.Len() ? 0 : 1 )) );
1684         aName += ByteString(rExtension, osl_getThreadTextEncoding());
1685     }
1686     else if ( rExtension.Len() )
1687     {
1688         // es wurde kein cSep gefunden
1689         aName += cSep;
1690         aName += ByteString(rExtension, osl_getThreadTextEncoding());
1691     }
1692 }
1693 
1694 /*************************************************************************
1695 |*
1696 |*    DirEntry::CutExtension()
1697 |*
1698 |*    Beschreibung      FSYS.SDW
1699 |*    Ersterstellung    MI 23.07.93
1700 |*    Letzte Aenderung  MI 23.07.93
1701 |*
1702 *************************************************************************/
1703 
CutExtension(char cSep)1704 String DirEntry::CutExtension( char cSep )
1705 {
1706     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1707 
1708     const char *p0 = ( aName.GetBuffer() );
1709     const char *p1 = p0 + aName.Len() - 1;
1710     while ( p1 >= p0 && *p1 != cSep )
1711         p1--;
1712 
1713     if ( p1 >= p0 )
1714     {
1715         // es wurde ein cSep an der Position p1 gefunden
1716         aName.Erase( static_cast< xub_StrLen >(p1-p0) );
1717         return String(p1 + 1, osl_getThreadTextEncoding());
1718     }
1719 
1720     return String();
1721 }
1722 
1723 /*************************************************************************
1724 |*
1725 |*    DirEntry::SetName()
1726 |*
1727 |*    Beschreibung      FSYS.SDW
1728 |*    Ersterstellung    MI 04.09.93
1729 |*    Letzte Aenderung  MI 04.09.93
1730 |*
1731 *************************************************************************/
1732 
SetName(const String & rName,FSysPathStyle eFormatter)1733 void DirEntry::SetName( const String& rName, FSysPathStyle eFormatter )
1734 {
1735     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1736 
1737         if ( eFormatter == FSYS_STYLE_HOST || eFormatter == FSYS_STYLE_DETECT )
1738         eFormatter = DEFSTYLE;
1739     ByteString aAccDelim( ACCESSDELIM_C( eFormatter ) );
1740 
1741     if ( (eFlag != FSYS_FLAG_NORMAL) ||
1742          (aName.Search( ':' ) != STRING_NOTFOUND) ||
1743          (aName.Search( aAccDelim ) != STRING_NOTFOUND) ||
1744          (eFormatter == FSYS_STYLE_FAT && (aName.GetTokenCount( '.' ) > 2) ) )
1745     {
1746         eFlag = FSYS_FLAG_INVALID;
1747     }
1748     else
1749         {
1750         aName = ByteString(rName, osl_getThreadTextEncoding());
1751         }
1752 }
1753 
1754 /*************************************************************************
1755 |*
1756 |*    DirEntry::Find()
1757 |*
1758 |*    Beschreibung      FSYS.SDW
1759 |*    Ersterstellung    MI 26.04.91
1760 |*    Letzte Aenderung  MA 02.12.91
1761 |*
1762 *************************************************************************/
Find(const String & rPfad,char cDelim)1763 sal_Bool DirEntry::Find( const String& rPfad, char cDelim )
1764 {
1765     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1766 
1767         if ( ImpGetTopPtr()->eFlag == FSYS_FLAG_ABSROOT )
1768                 return sal_True;
1769 
1770         sal_Bool bWild = aName.Search( '*' ) != STRING_NOTFOUND ||
1771                                  aName.Search( '?' ) != STRING_NOTFOUND;
1772         if ( !cDelim )
1773                 cDelim = SEARCHDELIM(DEFSTYLE)[0];
1774 
1775         sal_uInt16 nTokenCount = rPfad.GetTokenCount( cDelim );
1776         sal_uInt16 nIndex = 0;
1777         ByteString aThis = ACCESSDELIM(DEFSTYLE);
1778         aThis += ByteString(GetFull(), osl_getThreadTextEncoding());
1779         for ( sal_uInt16 nToken = 0; nToken < nTokenCount; ++nToken )
1780         {
1781             ByteString aPath = ByteString(rPfad, osl_getThreadTextEncoding()).GetToken( 0, cDelim, nIndex );
1782 
1783 			if ( aPath.Len() )
1784 			{
1785                 if (aPath.GetChar(aPath.Len()-1)== ACCESSDELIM(DEFSTYLE)[0])
1786                         aPath.Erase(aPath.Len()-1);
1787                 aPath += aThis;
1788                 DirEntry aEntry( String(aPath, osl_getThreadTextEncoding()));
1789                 if ( aEntry.ToAbs() &&
1790                          ( ( !bWild && aEntry.Exists() ) || ( bWild && aEntry.First() ) ) )
1791                 {
1792                         (*this) = aEntry;
1793                         return sal_True;
1794                 }
1795 			}
1796         }
1797         return sal_False;
1798 }
1799 
1800 /*************************************************************************
1801 |*
1802 |*    DirEntry::ImpToRel()
1803 |*
1804 |*    Beschreibung
1805 |*    Ersterstellung    MI 17.06.93
1806 |*    Letzte Aenderung  MI 17.06.93
1807 |*
1808 *************************************************************************/
1809 
ImpToRel(String aCurStr)1810 sal_Bool DirEntry::ImpToRel( String aCurStr )
1811 {
1812     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1813 
1814         DirEntry aThis(*this);
1815     aThis.ToAbs();
1816     String aThisStr( aThis.GetFull( FSYS_STYLE_HPFS ) );
1817 
1818     // #109512 preserve case of path even if caseinsensitive
1819     String aThisCompareStr( aThisStr ), aCurCompareStr( aCurStr );
1820     if ( ! IsCaseSensitive() )
1821     {
1822         aThisCompareStr.ToLowerAscii();
1823         aCurCompareStr.ToLowerAscii();
1824     }
1825 
1826     // "Ubereinstimmung pr"ufen
1827     sal_uInt16 nPos = aThisCompareStr.Match( aCurCompareStr );
1828     if ( nPos == STRING_MATCH && aThisStr.Len() != aCurStr.Len() )
1829         nPos = Min( aThisStr.Len(), aCurStr.Len() );
1830 
1831     // Sonderfall, die DirEntries sind identisch
1832     if ( nPos == STRING_MATCH )
1833     {
1834         // dann ist der relative Pfad das aktuelle Verzeichnis
1835         *this = DirEntry();
1836         return sal_True;
1837     }
1838 
1839     // Sonderfall, die DirEntries sind total verschieden
1840     if ( nPos == 0 )
1841     {
1842         // dann ist der relativste Pfad absolut
1843         *this = aThis;
1844         return sal_False;
1845     }
1846 
1847     // sonst nehmen wir die identischen Einzelteile vorne weg
1848     while ( nPos > 0 && aThisStr.GetChar(nPos) != '\\' )
1849         --nPos;
1850         aThisStr.Erase( 0, nPos + ( ( aThisStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) );
1851     aCurStr.Erase( 0, nPos + ( ( aCurStr.GetChar(nPos) == '\\' ) ? 1 : 0 ) );
1852 
1853     // und fuellen mit dem Level der Directories auf
1854     for ( nPos = 0; nPos < aCurStr.Len(); ++nPos )
1855         if ( aCurStr.GetChar(nPos) == '\\' )
1856             aThisStr.Insert( String( "..\\", osl_getThreadTextEncoding() ), 0 );
1857 
1858     // das ist dann unser relativer Pfad
1859     *this = DirEntry( aThisStr, FSYS_STYLE_HPFS );
1860     return sal_True;
1861 }
1862 
1863 /*************************************************************************
1864 |*
1865 |*    DirEntry::CutRelParents()
1866 |*
1867 |*    Beschreibung
1868 |*    Ersterstellung    MI 01.08.95
1869 |*    Letzte Aenderung  MI 01.08.95
1870 |*
1871 *************************************************************************/
1872 
CutRelParents()1873 sal_uInt16 DirEntry::CutRelParents()
1874 {
1875     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1876 
1877         // erstes '..' finden
1878     DirEntry *pDir = 0;
1879     DirEntry *pPar;
1880 
1881     for (  pPar = this;
1882           pPar && pPar->eFlag != FSYS_FLAG_PARENT;
1883           pPar = pPar->pParent )
1884         pDir = pPar;
1885 
1886     // '..' zaehlen
1887     sal_uInt16 nParCount = 0;
1888     while ( pPar && pPar->eFlag == FSYS_FLAG_PARENT )
1889     {
1890         ++nParCount;
1891         pPar = pPar->pParent;
1892     }
1893 
1894     // cutten
1895     if ( pDir )
1896         DELETEZ(pDir->pParent);
1897     else
1898         eFlag = FSYS_FLAG_CURRENT;
1899 
1900     return nParCount;
1901 }
1902 
1903 /*************************************************************************
1904 |*
1905 |*    DirEntry::ToRel()
1906 |*
1907 |*    Beschreibung      FSYS.SDW
1908 |*    Ersterstellung    MI 26.06.93
1909 |*    Letzte Aenderung  MI 17.06.93
1910 |*
1911 *************************************************************************/
1912 
ToRel()1913 sal_Bool DirEntry::ToRel()
1914 {
1915     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1916 
1917         DirEntry aCur;
1918     aCur.ToAbs();
1919         return ImpToRel( aCur.GetFull( FSYS_STYLE_HPFS ) );
1920 }
1921 
1922 /*************************************************************************
1923 |*
1924 |*    DirEntry::ToRel()
1925 |*
1926 |*    Beschreibung      FSYS.SDW
1927 |*    Ersterstellung    MI 26.04.91
1928 |*    Letzte Aenderung  MA 02.12.91
1929 |*
1930 *************************************************************************/
1931 
ToRel(const DirEntry & rStart)1932 sal_Bool DirEntry::ToRel( const DirEntry& rStart )
1933 {
1934     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1935 
1936         DirEntry aStart( rStart );
1937         aStart.ToAbs();
1938         return ImpToRel( aStart.GetFull( FSYS_STYLE_HPFS ) );
1939 }
1940 
1941 /*************************************************************************
1942 |*
1943 |*    DirEntry::GetDevice()
1944 |*
1945 |*    Beschreibung      FSYS.SDW
1946 |*    Ersterstellung    MI 26.04.91
1947 |*    Letzte Aenderung  MA 02.12.91
1948 |*
1949 *************************************************************************/
1950 
1951 #ifndef UNX
1952 
GetDevice() const1953 DirEntry DirEntry::GetDevice() const
1954 {
1955         DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1956 
1957         const DirEntry *pTop = ImpGetTopPtr();
1958 
1959         if ( ( pTop->eFlag == FSYS_FLAG_ABSROOT || pTop->eFlag == FSYS_FLAG_RELROOT ) &&
1960                  pTop->aName.Len() )
1961                 return DirEntry( pTop->aName, FSYS_FLAG_VOLUME, FSYS_STYLE_HOST );
1962         else
1963                 return DirEntry( ByteString(), FSYS_FLAG_INVALID, FSYS_STYLE_HOST );
1964 }
1965 
1966 #endif
1967 
1968 /*************************************************************************
1969 |*
1970 |*    DirEntry::SetBase()
1971 |*
1972 |*    Beschreibung      FSYS.SDW
1973 |*    Ersterstellung    MI 23.10.91
1974 |*    Letzte Aenderung  MA 02.12.91
1975 |*
1976 *************************************************************************/
1977 
SetBase(const String & rBase,char cSep)1978 void DirEntry::SetBase( const String& rBase, char cSep )
1979 {
1980     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
1981 
1982     const char *p0 = ( aName.GetBuffer() );
1983     const char *p1 = p0 + aName.Len() - 1;
1984     while ( p1 >= p0 && *p1 != cSep )
1985         p1--;
1986 
1987     if ( p1 >= p0 )
1988     {
1989         // es wurde ein cSep an der Position p1 gefunden
1990         aName.Erase( 0, static_cast< xub_StrLen >(p1 - p0) );
1991         aName.Insert( ByteString(rBase, osl_getThreadTextEncoding()), 0 );
1992     }
1993     else
1994         aName = ByteString(rBase, osl_getThreadTextEncoding());
1995 }
1996 
1997 /*************************************************************************
1998 |*
1999 |*    DirEntry::GetSearchDelimiter()
2000 |*
2001 |*    Beschreibung      FSYS.SDW
2002 |*    Ersterstellung    MI 10.06.93
2003 |*    Letzte Aenderung  MI 10.06.93
2004 |*
2005 *************************************************************************/
2006 
GetSearchDelimiter(FSysPathStyle eFormatter)2007 String DirEntry::GetSearchDelimiter( FSysPathStyle eFormatter )
2008 {
2009     return String( ByteString(SEARCHDELIM( GetStyle( eFormatter ) ) ), osl_getThreadTextEncoding());
2010 }
2011 
2012 /*************************************************************************
2013 |*
2014 |*    DirEntry::GetMaxNameLen()
2015 |*
2016 |*    Beschreibung      Liefert die maximale Anzahl von Zeichen in
2017 |*                      einzelnen Namensteile. Bei FileSystmen mit
2018 |*                      fester Extension (FAT) zaehlt diese nicht mit.
2019 |*                      Bei unbekannten FileSytemen und FSYS_STYLE_URL
2020 |*                      wird USHRT_MAX zurueckgegeben.
2021 |*    Ersterstellung    MI 17.06.97
2022 |*    Letzte Aenderung  MI 17.06.97
2023 |*
2024 *************************************************************************/
2025 
GetMaxNameLen(FSysPathStyle eFormatter)2026 sal_uInt16 DirEntry::GetMaxNameLen( FSysPathStyle eFormatter )
2027 {
2028     eFormatter = GetStyle( eFormatter );
2029     switch ( eFormatter )
2030     {
2031         case FSYS_STYLE_MAC:    return  31;
2032 
2033         case FSYS_STYLE_FAT:    return   8;
2034 
2035         case FSYS_STYLE_VFAT:
2036         case FSYS_STYLE_NTFS:
2037         case FSYS_STYLE_NWFS:
2038         case FSYS_STYLE_HPFS:   return 255;
2039 
2040 
2041         case FSYS_STYLE_SYSV:   return  14;
2042 
2043         case FSYS_STYLE_BSD:    return 250;
2044 
2045         default:
2046             return USHRT_MAX;
2047     }
2048 }
2049 
2050 /*************************************************************************
2051 |*
2052 |*    DirEntry::TempName()
2053 |*
2054 |*    Beschreibung      FSYS.SDW - Aha, wo?
2055 |*    Ersterstellung    VB 06.09.93 (im SWG)
2056 |*    Letzte Aenderung  MI 06.02.98
2057 |*
2058 *************************************************************************/
2059 namespace { struct TempNameBase_Impl : public rtl::Static< DirEntry, TempNameBase_Impl > {}; }
2060 
SetTempNameBase(const String & rBase)2061 const DirEntry& DirEntry::SetTempNameBase( const String &rBase )
2062 {
2063         DirEntry aTempDir = DirEntry().TempName().GetPath();
2064         aTempDir += DirEntry( rBase );
2065 #ifdef UNX
2066         ByteString aName( aTempDir.GetFull(), osl_getThreadTextEncoding());
2067         if ( access( aName.GetBuffer(), W_OK | X_OK | R_OK ) )
2068         {
2069 			// Create the directory and only on success give all rights to
2070 			// everyone. Use mkdir instead of DirEntry::MakeDir because
2071 			// this returns sal_True even if directory already exists.
2072 
2073 			if ( !mkdir( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO ) )
2074 				chmod( aName.GetBuffer(), S_IRWXU | S_IRWXG | S_IRWXO );
2075 
2076 			// This will not create a directory but perhaps FileStat called
2077 			// there modifies the DirEntry
2078 
2079 			aTempDir.MakeDir();
2080         }
2081 #else
2082         aTempDir.MakeDir();
2083 #endif
2084         DirEntry &rEntry = TempNameBase_Impl::get();
2085         rEntry = aTempDir.TempName( FSYS_KIND_DIR );
2086         return rEntry;
2087 }
2088 
TempName(DirEntryKind eKind) const2089 DirEntry DirEntry::TempName( DirEntryKind eKind ) const
2090 {
2091         // ggf. Base-Temp-Dir verwenden (macht Remote keinen Sinn => vorher)
2092 	const DirEntry &rEntry = TempNameBase_Impl::get();
2093         if ( !pParent && FSYS_FLAG_CURRENT != rEntry.eFlag && FSYS_FLAG_ABSROOT != eFlag )
2094 
2095         {
2096                 DirEntry aFactory( rEntry );
2097                 aFactory += GetName();
2098                 return aFactory.TempName();
2099         }
2100 
2101         ByteString aDirName; // hiermit hatte MPW C++ Probleme - immmer noch??
2102         char *ret_val;
2103         size_t i;
2104 
2105         // dertermine Directory, Prefix and Extension
2106         char pfx[6];
2107         char ext[5];
2108         const char *dir;
2109         const char *pWild = strchr( aName.GetBuffer(), '*' );
2110         if ( !pWild )
2111             pWild = strchr( aName.GetBuffer(), '?' );
2112 
2113         if ( pWild )
2114         {
2115             if ( pParent )
2116                 aDirName = ByteString(pParent->GetFull(), osl_getThreadTextEncoding());
2117             strncpy( pfx, aName.GetBuffer(), Min( (int)5, (int)(pWild-aName.GetBuffer()) ) );
2118             pfx[ pWild-aName.GetBuffer() ] = 0;
2119             const char *pExt = strchr( pWild, '.' );
2120             if ( pExt )
2121             {
2122                 strncpy( ext, pExt, 4 );
2123                 ext[4] = 0;
2124             }
2125             else
2126                 strcpy( ext, ".tmp" );
2127         }
2128         else
2129         {
2130             aDirName = ByteString(GetFull(), osl_getThreadTextEncoding());
2131             strcpy( pfx, "sv" );
2132             strcpy( ext, ".tmp" );
2133         }
2134         dir = aDirName.GetBuffer();
2135 
2136         // wurde kein Dir angegeben, dann nehmen wir ein passendes TEMP-Verz.
2137         char sBuf[_MAX_PATH];
2138         if ( eFlag == FSYS_FLAG_CURRENT || ( !pParent && pWild ) )
2139             dir = TempDirImpl(sBuf);
2140 
2141         // ab hier leicht modifizierter Code von VB
2142         DirEntry aRet(FSYS_FLAG_INVALID);
2143         i = strlen(dir);
2144         // need to add ?\\? + prefix + number + pid + .ext + '\0'
2145 #       define TMPNAME_SIZE  ( 1 + 5 + 5 + 10 + 4 + 1 )
2146         ret_val = new char[i + TMPNAME_SIZE ];
2147         if (ret_val)
2148         {
2149             strcpy(ret_val,dir);
2150 
2151             /* Make sure directory ends with a separator    */
2152 #if defined(WNT) || defined(OS2)
2153             if ( i>0 && ret_val[i-1] != '\\' && ret_val[i-1] != '/' &&
2154                  ret_val[i-1] != ':')
2155                 ret_val[i++] = '\\';
2156 #elif defined UNX
2157             if (i>0 && ret_val[i-1] != '/')
2158                 ret_val[i++] = '/';
2159 #else
2160 #error unknown operating system
2161 #endif
2162 
2163             strncpy(ret_val + i, pfx, 5);
2164             ret_val[i + 5] = '\0';      /* strncpy doesn't put a 0 if more  */
2165             i = strlen(ret_val);        /* than 'n' chars.          */
2166 
2167             /* Prefix can have 5 chars, leaving 3 for numbers. 26 ** 3 == 17576
2168              * Welcome to the 21st century, we can have longer filenames now ;)
2169              * New format: pfx + "5 char milli/micro second res" + "current pid" + ".tmp"
2170              */
2171 #if (defined MSC || defined __MINGW32__) && defined WNT
2172             /* Milliseconds !! */
2173             static unsigned long u = GetTickCount();
2174             unsigned long mypid = static_cast<unsigned long>(_getpid());
2175 #else
2176             /* Microseconds !! */
2177             static unsigned long u = clock();
2178             unsigned long mypid = static_cast<unsigned long>(getpid());
2179 #endif
2180             for ( unsigned long nOld = u; ++u != nOld; ) /* Hae??? */
2181             {
2182                 u %= 100000;  /* on *NIX repeats every 100ms, maybe less if CLOCKS_PER_SEC > 10^6 */
2183                 snprintf(ret_val+i, TMPNAME_SIZE, "%05lu%lu", u, mypid);
2184 
2185                 strcat(ret_val,ext);
2186 
2187                         if ( FSYS_KIND_FILE == eKind )
2188                         {
2189                                 SvFileStream aStream( String( ret_val, osl_getThreadTextEncoding()),
2190                                                         STREAM_WRITE|STREAM_SHARE_DENYALL );
2191                                 if ( aStream.IsOpen() )
2192                                 {
2193                                         aStream.Seek( STREAM_SEEK_TO_END );
2194                                         if ( 0 == aStream.Tell() )
2195                                         {
2196                                                 aRet = DirEntry( String( ret_val, osl_getThreadTextEncoding()));
2197                                                 break;
2198                                         }
2199                                         aStream.Close();
2200                                 }
2201                         }
2202                         else
2203                         {
2204                                 // Redirect
2205 				String aRetVal(ret_val, osl_getThreadTextEncoding());
2206                                 String aRedirected (aRetVal);
2207 #ifndef BOOTSTRAP
2208                                 FSysRedirector::DoRedirect( aRedirected );
2209 #endif
2210                                 if ( FSYS_KIND_DIR == eKind )
2211                                 {
2212                                                 if ( 0 == _mkdir( ByteString(aRedirected.GetBuffer(), osl_getThreadTextEncoding()).GetBuffer() ) )
2213                                         {
2214                                                 aRet = DirEntry( aRetVal );
2215                                                 break;
2216                                         }
2217                                 }
2218                                 else
2219                                 {
2220 #if defined(UNX) || defined(OS2)
2221 										if( access( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), F_OK ) )
2222                                         {
2223                                                 aRet = DirEntry( aRetVal );
2224                                                 break;
2225                                         }
2226 #else
2227                                         struct stat aStat;
2228                                         if ( stat( ByteString(aRedirected, osl_getThreadTextEncoding()).GetBuffer(), &aStat ) )
2229                                         {
2230 											aRet = DirEntry( aRetVal );
2231 											break;
2232                                         }
2233 #endif
2234                                 }
2235                         }
2236             }
2237 
2238             delete[] ret_val;
2239             ret_val = 0;
2240         }
2241 
2242         return aRet;
2243 }
2244 
2245 /*************************************************************************
2246 |*
2247 |*    DirEntry::operator[]()
2248 |*
2249 |*    Beschreibung      FSYS.SDW
2250 |*    Ersterstellung    MI 03.03.92
2251 |*    Letzte Aenderung  MI 03.03.92
2252 |*
2253 *************************************************************************/
2254 
operator [](sal_uInt16 nParentLevel) const2255 const DirEntry &DirEntry::operator[]( sal_uInt16 nParentLevel ) const
2256 {
2257     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2258 
2259         //TPF: maybe to be implemented (FastFSys)
2260 
2261         const DirEntry *pRes = this;
2262     while ( pRes && nParentLevel-- )
2263         pRes = pRes->pParent;
2264 
2265     return *pRes;
2266 }
2267 
2268 /*************************************************************************
2269 |*
2270 |*    DirEntry::ImpParseUnixName()
2271 |*
2272 |*    Beschreibung      FSYS.SDW
2273 |*    Ersterstellung    MI 26.04.91
2274 |*    Letzte Aenderung  MI 26.05.93
2275 |*
2276 *************************************************************************/
2277 
ImpParseUnixName(const ByteString & rPfad,FSysPathStyle eStyle)2278 FSysError DirEntry::ImpParseUnixName( const ByteString& rPfad, FSysPathStyle eStyle )
2279 {
2280     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2281 
2282     // die einzelnen Namen auf einen Stack packen
2283     DirEntryStack   aStack;
2284     ByteString      aPfad( rPfad );
2285     do
2286     {
2287         // den Namen vor dem ersten "/" abspalten,
2288         // falls '/' am Anfang, ist der Name '/',
2289         // der Rest immer ohne die fuehrenden '/'.
2290         // den ersten '/' suchen
2291         sal_uInt16 nPos;
2292         for ( nPos = 0;
2293               nPos < aPfad.Len() && aPfad.GetChar(nPos) != '/';
2294               nPos++ )
2295             /* do nothing */;
2296 
2297             // ist der Name die Root des aktuellen Drives?
2298         if ( nPos == 0 && aPfad.Len() > 0 && ( aPfad.GetChar(0) == '/' ) )
2299         {
2300             // Root-Directory des aktuellen Drives
2301             aStack.Push( new DirEntry( FSYS_FLAG_ABSROOT ) );
2302         }
2303         else
2304         {
2305             // den Namen ohne Trenner abspalten
2306             aName = aPfad.Copy( 0, nPos );
2307 
2308                         // stellt der Name die aktuelle Directory dar?
2309             if ( aName == "." )
2310                 /* do nothing */;
2311 
2312 #ifdef UNX
2313                         // stellt der Name das User-Dir dar?
2314                         else if ( aName == "~" )
2315                         {
2316                                 DirEntry aHome( String( (const char *) getenv( "HOME" ), osl_getThreadTextEncoding()) );
2317                                 for ( sal_uInt16 n = aHome.Level(); n; --n )
2318                                         aStack.Push( new DirEntry( aHome[ (sal_uInt16) n-1 ] ) );
2319                         }
2320 #endif
2321 
2322                 // stellt der Name die Parent-Directory dar?
2323             else if ( aName == ".." )
2324             {
2325                 // ist nichts, ein Parent oder eine relative Root
2326                 // auf dem Stack?
2327                 if ( ( aStack.Count() == 0 ) ||
2328                      ( aStack.Top()->eFlag == FSYS_FLAG_PARENT ) )
2329                     // fuehrende Parents kommen auf den Stack
2330                     aStack.Push( new DirEntry( ByteString(), FSYS_FLAG_PARENT, eStyle ) );
2331 
2332                 // ist es eine absolute Root
2333                 else if ( aStack.Top()->eFlag == FSYS_FLAG_ABSROOT ) {
2334                     // die hat keine Parent-Directory
2335                     return FSYS_ERR_NOTEXISTS;
2336                 }
2337                 else
2338                     // sonst hebt der Parent den TOS auf
2339                     delete aStack.Pop();
2340             }
2341             else
2342             {
2343                 DirEntry *pNew = NULL;
2344                 // normalen Entries kommen auf den Stack
2345                                 pNew = new DirEntry( aName, FSYS_FLAG_NORMAL, eStyle );
2346                                 if ( !pNew->IsValid() )
2347                                 {
2348                                         aName = rPfad;
2349                                         ErrCode eErr = pNew->GetError();
2350                                         delete pNew;
2351                                         return eErr;
2352                                 }
2353                 aStack.Push( pNew );
2354                         }
2355         }
2356 
2357         // den Restpfad bestimmen
2358         aPfad.Erase( 0, nPos + 1 );
2359         while ( aPfad.Len() && ( aPfad.GetChar(0) == '/' ) )
2360             aPfad.Erase( 0, 1 );
2361     }
2362     while ( aPfad.Len() );
2363 
2364     // Haupt-Entry (selbst) zuweisen
2365     if ( aStack.Count() == 0 )
2366     {
2367         eFlag = FSYS_FLAG_CURRENT;
2368         aName.Erase();
2369     }
2370     else
2371     {
2372         eFlag = aStack.Top()->eFlag;
2373         aName = aStack.Top()->aName;
2374         delete aStack.Pop();
2375     }
2376 
2377     // die Parent-Entries vom Stack holen
2378     DirEntry** pTemp = &pParent;
2379     while ( aStack.Count() )
2380     {
2381         *pTemp = aStack.Pop();
2382         pTemp = &( (*pTemp)->pParent );
2383     }
2384 
2385     return FSYS_ERR_OK;
2386 }
2387 
2388 /*************************************************************************
2389 |*
2390 |*    DirEntry::MakeShortName()
2391 |*
2392 |*    Beschreibung
2393 |*    Ersterstellung    TLX
2394 |*    Letzte Aenderung  PB  21.08.97 (in CreateEntry_Impl())
2395 |*
2396 *************************************************************************/
2397 
CreateEntry_Impl(const DirEntry & rPath,DirEntryKind eKind)2398 ErrCode CreateEntry_Impl( const DirEntry &rPath, DirEntryKind eKind )
2399 {
2400     // versuchen, anzulegen (ausser bei FSYS_KIND_ALL)
2401     ErrCode eErr = ERRCODE_NONE;
2402     if ( FSYS_KIND_FILE == eKind )
2403     {
2404         SvFileStream aStream( rPath.GetFull(), STREAM_STD_WRITE );
2405         aStream.WriteLine( "" );
2406         eErr = aStream.GetError();
2407     }
2408     else if ( FSYS_KIND_ALL != eKind )
2409         eErr = rPath.MakeDir() ? ERRCODE_NONE : ERRCODE_IO_UNKNOWN;
2410 
2411     // erfolgreich?
2412     if ( !rPath.Exists() )
2413         eErr = ERRCODE_IO_UNKNOWN;  // Doch was schiefgegangen ?
2414 
2415     // ggf. wieder l"oschen
2416     if ( FSYS_KIND_NONE == eKind )
2417         rPath.Kill();
2418 
2419     // Fehlercode zur?ckliefern
2420     return eErr;
2421 }
2422 
IsValidEntry_Impl(const DirEntry & rPath,const String & rLongName,DirEntryKind eKind,sal_Bool bIsShortened,sal_Bool bUseDelim)2423 sal_Bool IsValidEntry_Impl( const DirEntry &rPath,
2424                         const String &rLongName,
2425                         DirEntryKind eKind,
2426                         sal_Bool bIsShortened,
2427                         sal_Bool bUseDelim )
2428 {
2429     // Parameter-Pr"uefung
2430     DBG_ASSERT( eKind == FSYS_KIND_NONE || eKind == FSYS_KIND_ALL ||
2431                 eKind == FSYS_KIND_FILE || eKind == FSYS_KIND_DIR,
2432                 "invalid entry-kind" );
2433 
2434     // Alle von MSDOS erreichbaren FSYS_STYLES muessen den
2435     // MSDOS Filenamenanforderungen genuegen. Sonst wird probiert,
2436     // ob sich eine Datei des gewuenschten Names anlegen laesst.
2437     FSysPathStyle eStyle = DirEntry::GetPathStyle( rPath.GetDevice().GetName() );
2438     DirEntry aPath(rPath);
2439     DirEntry aName(rLongName, eStyle);
2440     if ( !aName.IsValid() || aName.Level() != 1 )
2441         return sal_False;
2442     aPath += aName;
2443     if ( 1 == aPath.Level() )
2444         return sal_False;
2445     if ( eStyle == FSYS_STYLE_FAT || eStyle == FSYS_STYLE_NWFS ||
2446          eStyle == FSYS_STYLE_UNKNOWN )
2447     {
2448         DirEntry aDosEntry( rLongName, FSYS_STYLE_FAT );
2449         if ( !aDosEntry.IsValid() )
2450             return sal_False;
2451     }
2452 
2453         // Pfad-Trenner sind nicht erlaubt (bei ungek"urzten auch nicht FSYS_SHORTNAME_DELIMITER)
2454         char cDelim = bUseDelim == 2 ? FSYS_SHORTNAME_DELIMITER : char(0);
2455     if (
2456          rLongName.Search(DirEntry::GetAccessDelimiter()) != STRING_NOTFOUND ||
2457          (!bIsShortened && rLongName.Search(cDelim) != STRING_NOTFOUND)
2458        )
2459     {
2460         return sal_False;
2461     }
2462 
2463     // MI: Abfrage nach 'CON:' etc. wird jetzt in Exists() mitgemacht
2464     if ( aPath.Exists() )
2465         return sal_False;
2466 
2467     return (ERRCODE_NONE == CreateEntry_Impl( aPath, eKind ));
2468 }
2469 
2470 //-------------------------------------------------------------------------
2471 
2472 #define MAX_EXT_FAT         3
2473 #define MAX_LEN_FAT         8
2474 #define INVALID_CHARS_FAT   "\\/\"':|^<>[]?* "
2475 
2476 #define MAX_EXT_MAC        16   // nur wegen sinnvoller Namensk"rzung
2477 #define MAX_LEN_MAC        31
2478 #define INVALID_CHARS_MAC   "\":"
2479 
2480 #define MAX_EXT_MAX       250
2481 #define MAX_LEN_MAX       255
2482 #define INVALID_CHARS_DEF   "\\/\"':|^<>?*"
2483 
MakeShortName(const String & rLongName,DirEntryKind eKind,sal_Bool bUseDelim,FSysPathStyle eStyle)2484 sal_Bool DirEntry::MakeShortName( const String& rLongName, DirEntryKind eKind,
2485                               sal_Bool bUseDelim, FSysPathStyle eStyle )
2486 {
2487 		String aLongName(rLongName);
2488 
2489         // Alle '#' aus den Dateinamen entfernen, weil das INetURLObject
2490         // damit Probleme hat. Siehe auch #51246#
2491         aLongName.EraseAllChars( '#' );
2492         ByteString bLongName(aLongName, osl_getThreadTextEncoding());
2493 
2494         // Auf Novell-Servern (wegen der rottigen Clients) nur 7bit ASCII
2495 
2496 		// HRO: #69627# Weg mit dem Scheiss. Wenn es Client gibt, die so einen
2497 		// BUG haben, dann muss halt der Client ersetzt werden, aber doch nicht das
2498 		// Office kastrieren !!!
2499 
2500 #if 0
2501         if ( FSYS_STYLE_NWFS == GetPathStyle( ImpGetTopPtr()->GetName() ) )
2502         {
2503                 for ( sal_uInt16 n = aLongName.Len(); n; --n )
2504                 {
2505                         short nChar = aLongName(n-1);
2506                         if ( nChar < 32 || nChar >= 127 )
2507                                 aLongName.Erase( n-1, 1 );
2508                 }
2509         }
2510 #endif
2511 
2512         // bei FSYS_KIND_ALL den alten Namen merken und abh"angen (rename)
2513         ByteString aOldName;
2514         if ( FSYS_KIND_ALL == eKind )
2515         {
2516             aOldName = ByteString(CutName(), osl_getThreadTextEncoding());
2517             aOldName = CMP_LOWER(aOldName);
2518         }
2519 
2520         // ist der Langname direkt verwendbar?
2521         if ( IsValidEntry_Impl( *this, aLongName, eKind, sal_False, bUseDelim ) )
2522         {
2523             operator+=( DirEntry(aLongName) );
2524             return sal_True;
2525         }
2526 
2527         // max L"angen feststellen
2528         sal_uInt16 nMaxExt, nMaxLen;
2529         if ( FSYS_STYLE_DETECT == eStyle )
2530             eStyle = DirEntry::GetPathStyle( GetDevice().GetName() );
2531         ByteString aInvalidChars;
2532         switch ( eStyle )
2533         {
2534             case FSYS_STYLE_FAT:
2535                 nMaxExt = MAX_EXT_FAT;
2536                 nMaxLen = MAX_LEN_FAT;
2537                 aInvalidChars = INVALID_CHARS_FAT;
2538                 break;
2539 
2540             case FSYS_STYLE_MAC:
2541                 nMaxExt = MAX_EXT_MAC;
2542                 nMaxLen = MAX_LEN_MAC;
2543                 aInvalidChars = INVALID_CHARS_MAC;
2544                 break;
2545 
2546             default:
2547                 nMaxExt = MAX_EXT_MAX;
2548                 nMaxLen = MAX_LEN_MAX;
2549                 aInvalidChars = INVALID_CHARS_DEF;
2550         }
2551 
2552         // Extension abschneiden und kuerzen
2553         ByteString aExt;
2554         ByteString aFName = bLongName;
2555         if ( FSYS_STYLE_MAC != eStyle )
2556         {
2557             DirEntry aUnparsed;
2558             aUnparsed.aName = bLongName;
2559             aExt = ByteString(aUnparsed.CutExtension(), osl_getThreadTextEncoding());
2560             aFName = aUnparsed.aName;
2561             if ( aExt.Len() > nMaxExt )
2562             {
2563                 char c = aExt.GetChar( aExt.Len() - 1 );
2564                 aExt.Erase(nMaxExt-1);
2565                 aExt += c;
2566             }
2567         }
2568 
2569         if ( FSYS_STYLE_FAT != eStyle )
2570         {
2571                 // ausser auf einem FAT-System geh"ort die Extension zur
2572                 // Maxl"ange. Muss also vorher mit dem Punkt abgezogen werden.
2573                 nMaxLen -= ( aExt.Len() + 1 );
2574         }
2575 
2576         // Name k"urzen
2577         ByteString aSName;
2578         for ( const char *pc = aFName.GetBuffer(); aSName.Len() < nMaxLen && *pc; ++pc )
2579         {
2580             if ( STRING_NOTFOUND == aInvalidChars.Search( *pc ) &&
2581                  (unsigned char) *pc >= (unsigned char) 32 &&
2582                  ( !aSName.Len() || *pc != ' ' || aSName.GetChar(aSName.Len()-1) != ' ' ) )
2583                 aSName += *pc;
2584         }
2585         aSName.EraseTrailingChars();
2586 
2587 		// HRO: #74246# Also cut leading spaces
2588 		aSName.EraseLeadingChars();
2589 
2590         if ( !aSName.Len() )
2591             aSName = "noname";
2592 
2593         // kommt dabei der alte Name raus?
2594         ByteString aNewName = aSName;
2595         if ( aExt.Len() )
2596             ( aNewName += '.' ) += aExt;
2597         operator+=( DirEntry(String(aNewName, osl_getThreadTextEncoding())) );
2598         if ( FSYS_KIND_ALL == eKind && CMP_LOWER(aName) == aOldName )
2599         if ( FSYS_KIND_ALL == eKind && CMP_LOWER(ByteString(GetName(), osl_getThreadTextEncoding())) == aOldName )
2600             return sal_True;
2601 
2602         // kann der gek"urzte Name direkt verwendet werden?
2603         if ( !Exists() && (ERRCODE_NONE == CreateEntry_Impl( *this, eKind )) )
2604             return sal_True;
2605 
2606         // darf '?##' verwendet werden, um eindeutigen Name zu erzeugen?
2607         if ( bUseDelim )
2608         {
2609                 // eindeutigen Namen per '?##' erzeugen
2610             aSName.Erase( nMaxLen-3 );
2611             if ( bUseDelim != 2 )
2612                         aSName += FSYS_SHORTNAME_DELIMITER;
2613             for ( int n = 1; n < 99; ++n )
2614             {
2615                 // Name zusammensetzen
2616                 ByteString aTmpStr( aSName );
2617                 aTmpStr += ByteString::CreateFromInt32(n);
2618                 if ( aExt.Len() )
2619                     ( aTmpStr += '.' ) += aExt;
2620 
2621                 // noch nicht vorhanden?
2622                 SetName( String(aTmpStr, osl_getThreadTextEncoding()) );
2623 
2624                 if ( !Exists() )
2625                 {
2626                     // Fehler setzen !!!
2627                     nError = CreateEntry_Impl( *this, eKind );
2628                     return (ERRCODE_NONE == nError);
2629                 }
2630             }
2631         }
2632 
2633         // keine ## mehr frei / ?## soll nicht verwendet werden
2634         nError = ERRCODE_IO_ALREADYEXISTS;
2635         return sal_False;
2636 }
2637 
2638 /*************************************************************************
2639 |*
2640 |*    DirEntry::CreatePath()
2641 |*
2642 |*    Beschreibung      FSYS.SDW
2643 |*    Ersterstellung    MI 26.04.91
2644 |*    Letzte Aenderung  MA 02.12.91
2645 |*
2646 *************************************************************************/
2647 
MakeDir(sal_Bool bSloppy) const2648 sal_Bool DirEntry::MakeDir( sal_Bool bSloppy ) const
2649 {
2650     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2651 
2652         // Schnellpruefung, ob vorhanden
2653         if ( FileStat( *this ).IsKind( FSYS_KIND_DIR ) )
2654                 return sal_True;
2655         if ( bSloppy && pParent )
2656                  if ( FileStat( *pParent ).IsKind( FSYS_KIND_DIR ) )
2657                           return sal_True;
2658 
2659         const DirEntry *pNewDir = bSloppy ? pParent : this;
2660         if ( pNewDir )
2661         {
2662                 // den Path zum Dir erzeugen
2663                 if ( pNewDir->pParent && !pNewDir->pParent->MakeDir(sal_False) )
2664                         return sal_False;
2665 
2666                 // das Dir selbst erzeugen
2667                 if ( pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
2668                          pNewDir->eFlag == FSYS_FLAG_ABSROOT ||
2669                          pNewDir->eFlag == FSYS_FLAG_VOLUME )
2670                         return sal_True;
2671                 else
2672                 {
2673                         //? nError = ???
2674                         if ( FileStat( *pNewDir ).IsKind( FSYS_KIND_DIR ) )
2675                                 return sal_True;
2676                         else
2677                         {
2678                                 FSysFailOnErrorImpl();
2679 								String aDirName(pNewDir->GetFull());
2680 #ifndef BOOTSTRAP
2681                                 FSysRedirector::DoRedirect( aDirName );
2682 #endif
2683                                 ByteString bDirName( aDirName, osl_getThreadTextEncoding() );
2684                                 bDirName = GUI2FSYS( bDirName );
2685 
2686 #ifdef WIN32
2687 								SetLastError(0);
2688 #endif
2689                                 sal_Bool bResult = (0 == _mkdir( (char*) bDirName.GetBuffer() ));
2690                                 if ( !bResult )
2691                                 {
2692                                     // Wer hat diese Methode const gemacht ?
2693 #ifdef WIN32
2694                                     ((DirEntry *)this)->SetError( Sys2SolarError_Impl(  GetLastError() ) );
2695 #else
2696                                     ((DirEntry *)this)->SetError( Sys2SolarError_Impl(  errno ) );
2697 #endif
2698                                 }
2699 
2700 								return bResult;
2701                         }
2702                 }
2703         }
2704         return sal_True;
2705 }
2706 
2707 /*************************************************************************
2708 |*
2709 |*    DirEntry::CopyTo()
2710 |*
2711 |*    Beschreibung      FSYS.SDW
2712 |*    Ersterstellung    MI 26.04.91
2713 |*    Letzte Aenderung  MI 07.08.96
2714 |*
2715 *************************************************************************/
2716 
CopyTo(const DirEntry & rDest,FSysAction nActions) const2717 FSysError DirEntry::CopyTo( const DirEntry& rDest, FSysAction nActions ) const
2718 {
2719     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2720 
2721         if ( FSYS_ACTION_COPYFILE != (nActions & FSYS_ACTION_COPYFILE) )
2722 #ifdef UNX
2723     {
2724         // Hardlink anlegen
2725                 HACK(redirection missing)
2726 	ByteString aThis(GUI2FSYS(GetFull()), osl_getThreadTextEncoding());
2727 	ByteString aDest(GUI2FSYS(rDest.GetFull()), osl_getThreadTextEncoding());
2728         if (link( aThis.GetBuffer(), aDest.GetBuffer() ) == -1)
2729             return Sys2SolarError_Impl(  errno );
2730         else
2731             return FSYS_ERR_OK;
2732     }
2733 #else
2734         return FSYS_ERR_NOTSUPPORTED;
2735 #endif
2736 
2737         FileCopier fc(*this, rDest);
2738         return fc.Execute(nActions);
2739 }
2740 
2741 /*************************************************************************
2742 |*
2743 |*    DirEntry::MoveTo()
2744 |*
2745 |*    Beschreibung      FSYS.SDW
2746 |*    Ersterstellung    MI 26.04.91
2747 |*    Letzte Aenderung  HRO 24.03.99
2748 |*
2749 *************************************************************************/
2750 
2751 #if defined WNT || defined UNX || defined OS2
2752 
MoveTo(const DirEntry & rNewName) const2753 FSysError DirEntry::MoveTo( const DirEntry& rNewName ) const
2754 {
2755     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2756 
2757 /*
2758     FileStat aSourceStat(*this);
2759     if ( !aSourceStat.IsKind(FSYS_KIND_FILE) )
2760         return FSYS_ERR_NOTAFILE;
2761 */
2762 
2763 	DirEntry aDest(rNewName);
2764 	FileStat aDestStat(rNewName);
2765 	if ( aDestStat.IsKind(FSYS_KIND_DIR ) )
2766 	{
2767 		aDest += String(aName, osl_getThreadTextEncoding());
2768 	}
2769 	if ( aDest.Exists() )
2770 	{
2771 		return FSYS_ERR_ALREADYEXISTS;
2772 	}
2773 
2774 #if defined(OS2)
2775 	if ( FileStat(*this).IsKind(FSYS_KIND_DIR) && aDest.GetPath() != GetPath() )
2776 	{
2777 		return FSYS_ERR_NOTSUPPORTED;
2778 	}
2779 #endif
2780 
2781         FSysFailOnErrorImpl();
2782         String aFrom( GetFull() );
2783 
2784 #ifndef BOOTSTRAP
2785         FSysRedirector::DoRedirect(aFrom);
2786 #endif
2787 
2788         String aTo( aDest.GetFull() );
2789 
2790 #ifndef BOOTSTRAP
2791         FSysRedirector::DoRedirect(aTo);
2792 #endif
2793 
2794 		ByteString bFrom(aFrom, osl_getThreadTextEncoding());
2795 		ByteString bTo(aTo, osl_getThreadTextEncoding());
2796         bFrom = GUI2FSYS(bFrom);
2797         bTo = GUI2FSYS(bTo);
2798 
2799 #ifdef WNT
2800 		// MoveTo nun atomar
2801         SetLastError(0);
2802 
2803 		DirEntry aFromDevice(String(bFrom, osl_getThreadTextEncoding()));
2804 		DirEntry aToDevice(String(bTo,osl_getThreadTextEncoding()));
2805 		aFromDevice.ToAbs();
2806 		aToDevice.ToAbs();
2807 		aFromDevice=aFromDevice.GetDevice();
2808 		aToDevice=aToDevice.GetDevice();
2809 
2810 		//Quelle und Ziel auf gleichem device?
2811 		if (aFromDevice==aToDevice)
2812 		{
2813 			// ja, also intra-device-move mit MoveFile
2814 			MoveFile( bFrom.GetBuffer(), bTo.GetBuffer() );
2815 			// MoveFile ist buggy bei cross-device operationen.
2816 			// Der R?ckgabewert ist auch dann sal_True, wenn nur ein Teil der Operation geklappt hat.
2817 			// Zudem zeigt MoveFile unterschiedliches Verhalten bei unterschiedlichen NT-Versionen.
2818         	return Sys2SolarError_Impl( GetLastError() );
2819         }
2820         else
2821         {
2822         	//nein, also inter-device-move mit copy/delete
2823 	        FSysError nCopyError = CopyTo(rNewName, FSYS_ACTION_COPYFILE);
2824 
2825 			DirEntry aKill(String(bTo, osl_getThreadTextEncoding()));
2826 			FileStat aKillStat(String(bTo, osl_getThreadTextEncoding()));
2827 			if ( aKillStat.IsKind(FSYS_KIND_DIR ) )
2828 			{
2829 				aKill += String(aName, osl_getThreadTextEncoding());
2830 			}
2831 
2832 	        if (nCopyError==FSYS_ERR_OK)
2833 	        {
2834 	            if (Kill()==FSYS_ERR_OK)
2835 	            {
2836 	            	return FSYS_ERR_OK;
2837 	            }
2838 	            else
2839 	            {
2840 	            	aKill.Kill();
2841 					return FSYS_ERR_ACCESSDENIED;
2842 	            }
2843 	        }
2844 	        else
2845 	        {
2846             	aKill.Kill();
2847 	            return nCopyError;
2848 	        }
2849 		}
2850 #else
2851 		// #68639#
2852 		// on some nfs connections rename with from == to
2853 		// leads to destruction of file
2854         if ( ( aFrom != aTo ) && ( 0 != rename( bFrom.GetBuffer(), bTo.GetBuffer() ) ) )
2855 #if !defined(UNX) && !defined(OS2)
2856             return Sys2SolarError_Impl( GetLastError() );
2857 #else
2858         {
2859                 if( errno == EXDEV )
2860 // cross device geht latuernich nicht mit rename
2861                 {
2862                         FILE *fpIN  = fopen( bFrom.GetBuffer(), "r" );
2863                         FILE *fpOUT = fopen( bTo.GetBuffer(), "w" );
2864                         if( fpIN && fpOUT )
2865                         {
2866                                 char pBuf[ 16384 ];
2867                                 int nBytes, nWritten, nErr = 0;
2868                                 errno = 0;
2869                                 while( ( nBytes = fread( pBuf, 1, sizeof(pBuf), fpIN ) ) && ! nErr )
2870                                 {
2871 									nWritten = fwrite( pBuf, 1, nBytes, fpOUT );
2872 									// Fehler im fwrite     ?
2873 									if( nWritten < nBytes )
2874 									{
2875 										nErr = errno;
2876 										break;
2877 									}
2878                                 }
2879                                 fclose( fpIN );
2880                                 fclose( fpOUT );
2881                                 if ( nErr )
2882 								{
2883 									unlink( bTo.GetBuffer() );
2884 									return Sys2SolarError_Impl( nErr );
2885 								}
2886 								else
2887 								{
2888 									unlink( bFrom.GetBuffer() );
2889 								}
2890                         }
2891                         else
2892 						{
2893 							return Sys2SolarError_Impl( EXDEV );
2894 						}
2895                 }
2896                 else
2897 				{
2898 					return Sys2SolarError_Impl( errno );
2899 				}
2900         }
2901 #endif
2902 #endif
2903         return ERRCODE_NONE;
2904 }
2905 
2906 #endif
2907 
2908 /*************************************************************************
2909 |*
2910 |*    DirEntry::Kill()
2911 |*
2912 |*    Beschreibung      FSYS.SDW
2913 |*    Ersterstellung    MI 26.04.91
2914 |*    Letzte Aenderung  MI 07.08.96
2915 |*
2916 *************************************************************************/
2917 
Kill(FSysAction nActions) const2918 FSysError DirEntry::Kill(  FSysAction nActions ) const
2919 {
2920     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
2921 
2922         FSysError eError = FSYS_ERR_OK;
2923         FSysFailOnErrorImpl();
2924 
2925         // Name als doppelt 0-terminierter String
2926         String aTmpName( GetFull() );
2927 #ifndef BOOTSTRAP
2928         FSysRedirector::DoRedirect( aTmpName );
2929 #endif
2930 		ByteString bTmpName( aTmpName, osl_getThreadTextEncoding());
2931         bTmpName = GUI2FSYS(bTmpName);
2932 
2933         char *pName = new char[bTmpName.Len()+2];
2934         strcpy( pName, bTmpName.GetBuffer() );
2935         pName[bTmpName.Len()+1] = (char) 0;
2936 
2937 		//read-only files sollen auch geloescht werden koennen
2938 		sal_Bool isReadOnly = FileStat::GetReadOnlyFlag(*this);
2939 		if (isReadOnly)
2940 		{
2941 			FileStat::SetReadOnlyFlag(*this, sal_False);
2942 		}
2943 
2944         // directory?
2945         if ( FileStat( *this ).IsKind(FSYS_KIND_DIR) )
2946         {
2947                 // Inhalte recursiv loeschen?
2948                 if ( FSYS_ACTION_RECURSIVE == (nActions & FSYS_ACTION_RECURSIVE) )
2949                 {
2950                         Dir aDir( *this, FSYS_KIND_DIR|FSYS_KIND_FILE );
2951                         for ( sal_uInt16 n = 0; eError == FSYS_ERR_OK && n < aDir.Count(); ++n )
2952                         {
2953                                 const DirEntry &rSubDir = aDir[n];
2954                                 DirEntryFlag flag = rSubDir.GetFlag();
2955                                 if ( flag != FSYS_FLAG_CURRENT && flag != FSYS_FLAG_PARENT )
2956                                         eError = rSubDir.Kill(nActions);
2957                         }
2958                 }
2959 
2960                 // das Dir selbst loeschen
2961 #ifdef WIN32
2962 				SetLastError(0);
2963 #endif
2964                 if ( eError == FSYS_ERR_OK && 0 != _rmdir( (char*) pName ) )
2965 				//
2966                 {
2967                         // falls L"oschen nicht ging, CWD umsetzen
2968 #ifdef WIN32
2969 					eError = Sys2SolarError_Impl( GetLastError() );
2970 #else
2971 					eError = Sys2SolarError_Impl( errno );
2972 #endif
2973                         if ( eError )
2974                         {
2975                                 GetPath().SetCWD();
2976 #ifdef WIN32
2977 								SetLastError(0);
2978 #endif
2979 								if (_rmdir( (char*) pName) != 0)
2980 								{
2981 #ifdef WIN32
2982 									eError = Sys2SolarError_Impl( GetLastError() );
2983 #else
2984 									eError = Sys2SolarError_Impl( errno );
2985 #endif
2986 								}
2987 								else
2988 								{
2989 									eError = FSYS_ERR_OK;
2990 								}
2991                         }
2992                 }
2993         }
2994         else
2995         {
2996                 if ( FSYS_ACTION_USERECYCLEBIN == (nActions & FSYS_ACTION_USERECYCLEBIN) )
2997                 {
2998 #ifdef OS2
2999                         eError = ApiRet2ToSolarError_Impl( DosDelete( (PSZ) pName ) );
3000 #elif defined(WNT)
3001                         SHFILEOPSTRUCT aOp;
3002                         aOp.hwnd = 0;
3003                         aOp.wFunc = FO_DELETE;
3004                         aOp.pFrom = pName;
3005                         aOp.pTo = 0;
3006                         aOp.fFlags = FOF_ALLOWUNDO|FOF_SILENT|FOF_NOCONFIRMATION;
3007                         aOp.hNameMappings = 0;
3008                         aOp.lpszProgressTitle = 0;
3009                         eError = Sys2SolarError_Impl( SHFileOperation( &aOp ) );
3010 #else
3011                         eError = ERRCODE_IO_NOTSUPPORTED;
3012 #endif
3013                 }
3014                 else
3015                 {
3016 #ifdef WIN32
3017 					SetLastError(0);
3018 #endif
3019 					if ( 0 != _unlink( (char*) pName ) )
3020 					{
3021 #ifdef WIN32
3022 						eError = Sys2SolarError_Impl( GetLastError() );
3023 #else
3024 						eError = Sys2SolarError_Impl( errno );
3025 #endif
3026 					}
3027 					else
3028 					{
3029 						eError = ERRCODE_NONE;
3030 					}
3031                 }
3032         }
3033 
3034 		//falls Fehler, originales read-only flag wieder herstellen
3035 		if ( isReadOnly && (eError!=ERRCODE_NONE) )
3036 		{
3037 			FileStat::SetReadOnlyFlag(*this, isReadOnly);
3038 		}
3039 
3040 		delete[] pName;
3041         return eError;
3042 }
3043 
3044 /*************************************************************************
3045 |*
3046 |*    DirEntry::Contains()
3047 |*
3048 |*    Beschreibung      ob rSubEntry direkt oder indirect in *this liegt
3049 |*    Ersterstellung    MI 20.03.97
3050 |*    Letzte Aenderung  MI 20.03.97
3051 |*
3052 *************************************************************************/
3053 
Contains(const DirEntry & rSubEntry) const3054 sal_Bool DirEntry::Contains( const DirEntry &rSubEntry ) const
3055 {
3056     DBG_ASSERT( IsAbs() && rSubEntry.IsAbs(), "must be absolute entries" );
3057 
3058         sal_uInt16 nThisLevel = Level();
3059     sal_uInt16 nSubLevel = rSubEntry.Level();
3060     if ( nThisLevel < nSubLevel )
3061     {
3062         for ( ; nThisLevel; --nThisLevel, --nSubLevel )
3063             if ( (*this)[nThisLevel-1] != rSubEntry[nSubLevel-1] )
3064                 return sal_False;
3065         return sal_True;
3066     }
3067     return sal_False;
3068 }
3069 
3070 /*************************************************************************
3071 |*
3072 |*    DirEntry::Level()
3073 |*
3074 |*    Beschreibung      FSYS.SDW
3075 |*    Ersterstellung    MI 03.03.92
3076 |*    Letzte Aenderung  MI 03.03.92
3077 |*
3078 *************************************************************************/
3079 
Level() const3080 sal_uInt16 DirEntry::Level() const
3081 {
3082     DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
3083 
3084     sal_uInt16 nLevel = 0;
3085     const DirEntry *pRes = this;
3086     while ( pRes )
3087     {
3088         pRes = pRes->pParent;
3089         nLevel++;
3090     }
3091 
3092     return nLevel;
3093 }
3094 
3095 /*************************************************************************
3096 |*
3097 |*    DirEntry::ConvertNameToSystem()
3098 |*
3099 |*    Beschreibung
3100 |*    Ersterstellung    DV 29.03.96
3101 |*    Letzte Aenderung  DV 29.03.96
3102 |*
3103 *************************************************************************/
3104 
ConvertNameToSystem(const String & rName)3105 String DirEntry::ConvertNameToSystem( const String &rName )
3106 {
3107     return rName;
3108 }
3109 
3110 /*************************************************************************
3111 |*
3112 |*    DirEntry::ConvertSystemToName()
3113 |*
3114 |*    Beschreibung
3115 |*    Ersterstellung    DV 29.03.96
3116 |*    Letzte Aenderung  DV 29.03.96
3117 |*
3118 *************************************************************************/
3119 
ConvertSystemToName(const String & rName)3120 String DirEntry::ConvertSystemToName( const String &rName )
3121 {
3122     return rName;
3123 }
3124 
3125 /*************************************************************************
3126 |*
3127 |*    DirEntry::IsValid()
3128 |*
3129 |*    Beschreibung
3130 |*    Ersterstellung    MI  18.09.93
3131 |*    Letzte Aenderung  TPF 18.09.98
3132 |*
3133 *************************************************************************/
3134 
IsValid() const3135 sal_Bool DirEntry::IsValid() const
3136 {
3137         return (nError == FSYS_ERR_OK);
3138 }
3139 
3140 /*************************************************************************
3141 |*
3142 |*    DirEntry::IsRFSAvailable()
3143 |*
3144 |*    Beschreibung
3145 |*    Ersterstellung    TPF 21.10.98
3146 |*    Letzte Aenderung  TPF 21.10.98
3147 |*
3148 *************************************************************************/
3149 
IsRFSAvailable()3150 sal_Bool DirEntry::IsRFSAvailable()
3151 {
3152     return sal_False;
3153 }
3154 
3155 /*************************************************************************
3156 |*
3157 |*    IsLongNameOnFAT()
3158 |*
3159 |*    Beschreibung      ?berpr?ft , ob das DirEntry einen langen
3160 |*                      Filenamen auf einer FAT-Partition enth?lt (EAs).
3161 |*                      (eigentlich nur f?r OS2 interessant)
3162 |*    Ersterstellung    TPF 02.10.98
3163 |*    Letzte Aenderung  TPF 01.03.1999
3164 |*
3165 *************************************************************************/
3166 
IsLongNameOnFAT() const3167 sal_Bool DirEntry::IsLongNameOnFAT() const
3168 {
3169         // FAT-System?
3170         DirEntry aTempDirEntry(*this);
3171         aTempDirEntry.ToAbs();
3172         if (DirEntry::GetPathStyle(aTempDirEntry.GetDevice().GetName().GetChar(0)) != FSYS_STYLE_FAT)
3173         {
3174             return sal_False;       // nein, also false
3175         }
3176 
3177         // DirEntry-Kette auf lange Dateinamen pr?fen
3178         for( sal_uInt16 iLevel = this->Level(); iLevel > 0; iLevel-- )
3179         {
3180             const DirEntry& rEntry = (const DirEntry&) (*this)[iLevel-1];
3181             String  aBase( rEntry.GetBase() );
3182             String  aExtension( rEntry.GetExtension() );
3183 
3184             if (aBase.Len()>8)  // Name > 8?
3185             {
3186                 return sal_True;
3187             }
3188 
3189             if (aExtension.Len()>3) // Extension > 3?
3190             {
3191                 return sal_True;
3192             }
3193         }
3194         return sal_False;
3195 }
3196 
3197 //========================================================================
3198 
3199 #if defined(DBG_UTIL)
3200 
FSysTest()3201 void FSysTest()
3202 {
3203 }
3204 
3205 #endif
3206 
3207 /* vim: set noet sw=4 ts=4: */
3208