xref: /AOO41X/main/tools/source/fsys/fstat.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_tools.hxx"
26 
27 #ifdef UNX
28 #include <errno.h>
29 #endif
30 
31 #include <limits.h>
32 #include <string.h>
33 
34 #include "comdep.hxx"
35 #include <tools/fsys.hxx>
36 
37 /*************************************************************************
38 |*
39 |*    FileStat::FileStat()
40 |*
41 |*    Beschreibung      FSYS.SDW
42 |*    Ersterstellung    MI 11.06.91
43 |*    Letzte Aenderung  MI 11.06.91
44 |*
45 *************************************************************************/
46 
FileStat()47 FileStat::FileStat()
48 :   // don't use Default-Ctors!
49     aDateCreated( sal_uIntPtr(0) ),
50     aTimeCreated( sal_uIntPtr(0) ),
51     aDateModified( sal_uIntPtr(0) ),
52     aTimeModified( sal_uIntPtr(0) ),
53     aDateAccessed( sal_uIntPtr(0) ),
54     aTimeAccessed( sal_uIntPtr(0) )
55 {
56     nSize = 0;
57     nKindFlags = FSYS_KIND_UNKNOWN;
58     nError = FSYS_ERR_OK;
59 }
60 
61 /*************************************************************************
62 |*
63 |*    FileStat::FileStat()
64 |*
65 |*    Beschreibung      FSYS.SDW
66 |*    Ersterstellung    MI 11.06.91
67 |*    Letzte Aenderung  MI 11.06.91
68 |*
69 *************************************************************************/
70 
FileStat(const DirEntry & rDirEntry,FSysAccess nAccess)71 FileStat::FileStat( const DirEntry& rDirEntry, FSysAccess nAccess )
72 :   // don't use Default-Ctors!
73     aDateCreated( sal_uIntPtr(0) ),
74     aTimeCreated( sal_uIntPtr(0) ),
75     aDateModified( sal_uIntPtr(0) ),
76     aTimeModified( sal_uIntPtr(0) ),
77     aDateAccessed( sal_uIntPtr(0) ),
78     aTimeAccessed( sal_uIntPtr(0) )
79 {
80     sal_Bool bCached = FSYS_ACCESS_CACHED == (nAccess & FSYS_ACCESS_CACHED);
81     sal_Bool bFloppy = FSYS_ACCESS_FLOPPY == (nAccess & FSYS_ACCESS_FLOPPY);
82 
83 #ifdef FEAT_FSYS_DOUBLESPEED
84     const FileStat *pStatFromDir = bCached ? rDirEntry.ImpGetStat() : 0;
85     if ( pStatFromDir )
86     {
87         nError = pStatFromDir->nError;
88         nKindFlags = pStatFromDir->nKindFlags;
89         nSize = pStatFromDir->nSize;
90         aCreator = pStatFromDir->aCreator;
91         aType = pStatFromDir->aType;
92         aDateCreated = pStatFromDir->aDateCreated;
93         aTimeCreated = pStatFromDir->aTimeCreated;
94         aDateModified = pStatFromDir->aDateModified;
95         aTimeModified = pStatFromDir->aTimeModified;
96         aDateAccessed = pStatFromDir->aDateAccessed;
97         aTimeAccessed = pStatFromDir->aTimeAccessed;
98     }
99     else
100 #endif
101         Update( rDirEntry, bFloppy );
102 }
103 
104 /*************************************************************************
105 |*
106 |*    FileStat::IsYounger()
107 |*
108 |*    Beschreibung      FSYS.SDW
109 |*    Ersterstellung    MA 11.11.91
110 |*    Letzte Aenderung  MA 11.11.91
111 |*
112 *************************************************************************/
113 
114 // sal_True  wenn die Instanz j"unger als rIsOlder ist.
115 // sal_False wenn die Instanz "alter oder gleich alt wie rIsOlder ist.
116 
IsYounger(const FileStat & rIsOlder) const117 sal_Bool FileStat::IsYounger( const FileStat& rIsOlder ) const
118 {
119     if ( aDateModified > rIsOlder.aDateModified )
120         return sal_True;
121     if ( ( aDateModified == rIsOlder.aDateModified ) &&
122          ( aTimeModified > rIsOlder.aTimeModified ) )
123         return sal_True;
124 
125     return sal_False;
126 }
127 
128 /*************************************************************************
129 |*
130 |*    FileStat::IsKind()
131 |*
132 |*    Ersterstellung    MA 11.11.91 (?)
133 |*    Letzte Aenderung  KH 16.01.95
134 |*
135 *************************************************************************/
136 
IsKind(DirEntryKind nKind) const137 sal_Bool FileStat::IsKind( DirEntryKind nKind ) const
138 {
139     sal_Bool bRet = ( ( nKind == FSYS_KIND_UNKNOWN ) &&
140                   ( nKindFlags == FSYS_KIND_UNKNOWN ) ) ||
141                 ( ( nKindFlags & nKind ) == nKind );
142     return bRet;
143 }
144 
145 /*************************************************************************
146 |*
147 |*    FileStat::HasReadOnlyFlag()
148 |*
149 |*    Ersterstellung    MI 06.03.97
150 |*    Letzte Aenderung  UT 01.07.98
151 |*
152 *************************************************************************/
153 
HasReadOnlyFlag()154 sal_Bool FileStat::HasReadOnlyFlag()
155 {
156 #if defined WNT || defined UNX || defined OS2
157     return sal_True;
158 #else
159     return sal_False;
160 #endif
161 }
162 
163 /*************************************************************************
164 |*
165 |*    FileStat::GetReadOnlyFlag()
166 |*
167 |*    Ersterstellung    MI 06.03.97
168 |*    Letzte Aenderung  UT 02.07.98
169 |*
170 *************************************************************************/
171 
GetReadOnlyFlag(const DirEntry & rEntry)172 sal_Bool FileStat::GetReadOnlyFlag( const DirEntry &rEntry )
173 {
174 
175     ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
176 #if defined WNT
177     DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
178     return ULONG_MAX != nRes &&
179            ( FILE_ATTRIBUTE_READONLY & nRes ) == FILE_ATTRIBUTE_READONLY;
180 #elif defined OS2
181     FILESTATUS3 aFileStat;
182     APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
183     switch ( nRet )
184     {
185         case NO_ERROR:
186             return FILE_READONLY == ( aFileStat.attrFile & FILE_READONLY );
187         default:
188             return sal_False;
189     }
190 #elif defined UNX
191     /* could we stat the object? */
192     struct stat aBuf;
193     if (stat(aFPath.GetBuffer(), &aBuf))
194         return sal_False;
195     /* jupp, is writable for user? */
196     return((aBuf.st_mode & S_IWUSR) != S_IWUSR);
197 #else
198     return sal_False;
199 #endif
200 }
201 
202 /*************************************************************************
203 |*
204 |*    FileStat::SetReadOnlyFlag()
205 |*
206 |*    Ersterstellung    MI 06.03.97
207 |*    Letzte Aenderung  UT 01.07.98
208 |*
209 *************************************************************************/
210 
SetReadOnlyFlag(const DirEntry & rEntry,sal_Bool bRO)211 sal_uIntPtr FileStat::SetReadOnlyFlag( const DirEntry &rEntry, sal_Bool bRO )
212 {
213 
214     ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
215 
216 #if defined WNT
217     DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
218     if ( ULONG_MAX != nRes )
219         nRes = SetFileAttributes( (LPCTSTR) aFPath.GetBuffer(),
220                     ( nRes & ~FILE_ATTRIBUTE_READONLY ) |
221                     ( bRO ? FILE_ATTRIBUTE_READONLY : 0 ) );
222     return ( ULONG_MAX == nRes ) ? ERRCODE_IO_UNKNOWN : 0;
223 #elif defined OS2
224     FILESTATUS3 aFileStat;
225     APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
226     if ( !nRet )
227     {
228         aFileStat.attrFile = ( aFileStat.attrFile & ~FILE_READONLY ) |
229                              ( bRO ? FILE_READONLY : 0 );
230         nRet = DosSetPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat), 0 );
231     }
232     switch ( nRet )
233     {
234         case NO_ERROR:
235             return ERRCODE_NONE;
236 
237         case ERROR_SHARING_VIOLATION:
238             return ERRCODE_IO_LOCKVIOLATION;
239 
240         default:
241             return ERRCODE_IO_NOTEXISTS;
242     }
243 #elif defined UNX
244     /* first, stat the object to get permissions */
245     struct stat aBuf;
246     if (stat(aFPath.GetBuffer(), &aBuf))
247         return ERRCODE_IO_NOTEXISTS;
248     /* set or clear write bit for user */
249     mode_t nMode;
250     if (bRO)
251     {
252         nMode = aBuf.st_mode & ~S_IWUSR;
253         nMode = aBuf.st_mode & ~S_IWGRP;
254         nMode = aBuf.st_mode & ~S_IWOTH;
255     }
256     else
257         nMode = aBuf.st_mode | S_IWUSR;
258     /* change it on fs */
259     if (chmod(aFPath.GetBuffer(), nMode))
260     {
261         switch (errno)
262         {
263             case EPERM :
264             case EROFS :
265                 return ERRCODE_IO_ACCESSDENIED;
266             default    :
267                 return ERRCODE_IO_NOTEXISTS;
268         }
269     }
270     else
271         return ERRCODE_NONE;
272 #else
273     return ERRCODE_IO_NOTSUPPORTED;
274 #endif
275 }
276 
277 /*************************************************************************
278 |*
279 |*    FileStat::SetDateTime
280 |*
281 |*    Ersterstellung    PB  27.06.97
282 |*    Letzte Aenderung
283 |*
284 *************************************************************************/
285 #if defined WNT || defined OS2
286 
SetDateTime(const String & rFileName,const DateTime & rNewDateTime)287 void FileStat::SetDateTime( const String& rFileName,
288                             const DateTime& rNewDateTime )
289 {
290     ByteString aFileName(rFileName, osl_getThreadTextEncoding());
291 
292     Date aNewDate = rNewDateTime;
293     Time aNewTime = rNewDateTime;
294 
295 #if defined WNT
296     TIME_ZONE_INFORMATION aTZI;
297     DWORD dwTZI = GetTimeZoneInformation( &aTZI );
298 
299     if ( dwTZI != (DWORD)-1 && dwTZI != TIME_ZONE_ID_UNKNOWN )
300     {
301         // 1. Korrektur der Zeitzone
302         LONG nDiff = aTZI.Bias;
303         Time aOldTime = aNewTime; // alte Zeit merken
304 
305         // 2. evt. Korrektur Sommer-/Winterzeit
306         if ( dwTZI == TIME_ZONE_ID_DAYLIGHT )
307             nDiff += aTZI.DaylightBias;
308 
309         Time aDiff( abs( nDiff / 60 /*Min -> Std*/ ), 0 );
310 
311         if ( nDiff > 0 )
312         {
313             aNewTime += aDiff;                  // Stundenkorrektur
314 
315             // bei "Uberlauf korrigieren
316             if ( aNewTime >= Time( 24, 0 ) )
317                 aNewTime -= Time( 24, 0 );
318 
319             // Tages"uberlauf?
320             if ( aOldTime == Time( 0, 0 ) ||    // 00:00 -> 01:00
321                  aNewTime < aOldTime )          // 23:00 -> 00:00 | 01:00 ...
322                 aNewDate++;
323         }
324         else if ( nDiff < 0 )
325         {
326             aNewTime -= aDiff;                  // Stundenkorrektur
327 
328             // negative Zeit (-1:00) korrigieren: 23:00
329             if (aNewTime < Time( 0, 0 ) )
330                 aNewTime += Time( 24, 0 );
331 
332             // Tagesunterlauf ?
333             if ( aOldTime == Time( 0, 0 ) ||    // 00:00 -> 23:00
334                  aNewTime > aOldTime )          // 01:00 -> 23:00 | 22:00 ...
335                 aNewDate--;
336         }
337     }
338 
339 
340     SYSTEMTIME aTime;
341     aTime.wYear = aNewDate.GetYear();
342     aTime.wMonth = aNewDate.GetMonth();
343     aTime.wDayOfWeek = 0;
344     aTime.wDay = aNewDate.GetDay();
345     aTime.wHour = aNewTime.GetHour();
346     aTime.wMinute = aNewTime.GetMin();
347     aTime.wSecond = aNewTime.GetSec();
348     aTime.wMilliseconds = 0;
349     FILETIME aFileTime;
350     SystemTimeToFileTime( &aTime, &aFileTime );
351 
352     HANDLE hFile = CreateFile( aFileName.GetBuffer(), GENERIC_WRITE, 0, 0,
353                                OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
354 
355     if ( hFile != INVALID_HANDLE_VALUE )
356     {
357         SetFileTime( hFile, &aFileTime, &aFileTime, &aFileTime );
358         CloseHandle( hFile );
359     }
360 #elif defined OS2
361 
362     // open file
363     ULONG nAction = FILE_EXISTED;
364     HFILE hFile = 0;
365     ULONG nFlags = OPEN_FLAGS_WRITE_THROUGH |
366                    OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE   |
367                    OPEN_FLAGS_RANDOM        | OPEN_FLAGS_NOINHERIT  |
368                    OPEN_SHARE_DENYNONE      | OPEN_ACCESS_READWRITE;
369 
370     APIRET nRet = DosOpen((PSZ)aFileName.GetBuffer(), &hFile, (PULONG)&nAction,
371                           0/*size*/, FILE_NORMAL,
372                           OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
373                           nFlags, 0/*ea*/);
374 
375     if ( nRet == 0 )
376     {
377         FILESTATUS3 FileInfoBuffer;
378 
379         nRet = DosQueryFileInfo(
380             hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
381 
382         if ( nRet == 0 )
383         {
384             FDATE aNewDate;
385             FTIME aNewTime;
386 
387              // create date and time words
388             aNewDate.day     = rNewDateTime.GetDay();
389             aNewDate.month   = rNewDateTime.GetMonth();
390             aNewDate.year    = rNewDateTime.GetYear() - 1980;
391             aNewTime.twosecs = rNewDateTime.GetSec() / 2;
392             aNewTime.minutes = rNewDateTime.GetMin();
393             aNewTime.hours   = rNewDateTime.GetHour();
394 
395             // set file date and time
396             FileInfoBuffer.fdateCreation   = aNewDate;
397             FileInfoBuffer.ftimeCreation   = aNewTime;
398             FileInfoBuffer.fdateLastAccess = aNewDate;
399             FileInfoBuffer.ftimeLastAccess = aNewTime;
400             FileInfoBuffer.fdateLastWrite  = aNewDate;
401             FileInfoBuffer.ftimeLastWrite  = aNewTime;
402 
403             DosSetFileInfo(hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
404         }
405         DosClose(hFile);
406     }
407 #endif
408 
409 }
410 #endif
411