Update ooo320-m1
[ooovba.git] / tools / source / fsys / fstat.cxx
blob94e76542302d6b83815dcd65039379987ad2a9a1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fstat.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
34 #if defined( WIN)
35 #include <stdio.h>
36 #include <dos.h>
37 #endif
39 #ifdef UNX
40 #include <errno.h>
41 #endif
43 #include <limits.h>
44 #include <string.h>
46 #include "comdep.hxx"
47 #include <tools/fsys.hxx>
49 /*************************************************************************
51 |* FileStat::FileStat()
53 |* Beschreibung FSYS.SDW
54 |* Ersterstellung MI 11.06.91
55 |* Letzte Aenderung MI 11.06.91
57 *************************************************************************/
59 FileStat::FileStat()
60 : // don't use Default-Ctors!
61 aDateCreated( ULONG(0) ),
62 aTimeCreated( ULONG(0) ),
63 aDateModified( ULONG(0) ),
64 aTimeModified( ULONG(0) ),
65 aDateAccessed( ULONG(0) ),
66 aTimeAccessed( ULONG(0) )
68 nSize = 0;
69 nKindFlags = FSYS_KIND_UNKNOWN;
70 nError = FSYS_ERR_OK;
73 /*************************************************************************
75 |* FileStat::FileStat()
77 |* Beschreibung FSYS.SDW
78 |* Ersterstellung MI 11.06.91
79 |* Letzte Aenderung MI 11.06.91
81 *************************************************************************/
83 FileStat::FileStat( const DirEntry& rDirEntry, FSysAccess nAccess )
84 : // don't use Default-Ctors!
85 aDateCreated( ULONG(0) ),
86 aTimeCreated( ULONG(0) ),
87 aDateModified( ULONG(0) ),
88 aTimeModified( ULONG(0) ),
89 aDateAccessed( ULONG(0) ),
90 aTimeAccessed( ULONG(0) )
92 BOOL bCached = FSYS_ACCESS_CACHED == (nAccess & FSYS_ACCESS_CACHED);
93 BOOL bFloppy = FSYS_ACCESS_FLOPPY == (nAccess & FSYS_ACCESS_FLOPPY);
95 #ifdef FEAT_FSYS_DOUBLESPEED
96 const FileStat *pStatFromDir = bCached ? rDirEntry.ImpGetStat() : 0;
97 if ( pStatFromDir )
99 nError = pStatFromDir->nError;
100 nKindFlags = pStatFromDir->nKindFlags;
101 nSize = pStatFromDir->nSize;
102 aCreator = pStatFromDir->aCreator;
103 aType = pStatFromDir->aType;
104 aDateCreated = pStatFromDir->aDateCreated;
105 aTimeCreated = pStatFromDir->aTimeCreated;
106 aDateModified = pStatFromDir->aDateModified;
107 aTimeModified = pStatFromDir->aTimeModified;
108 aDateAccessed = pStatFromDir->aDateAccessed;
109 aTimeAccessed = pStatFromDir->aTimeAccessed;
111 else
112 #endif
113 Update( rDirEntry, bFloppy );
116 /*************************************************************************
118 |* FileStat::IsYounger()
120 |* Beschreibung FSYS.SDW
121 |* Ersterstellung MA 11.11.91
122 |* Letzte Aenderung MA 11.11.91
124 *************************************************************************/
126 // TRUE wenn die Instanz j"unger als rIsOlder ist.
127 // FALSE wenn die Instanz "alter oder gleich alt wie rIsOlder ist.
129 BOOL FileStat::IsYounger( const FileStat& rIsOlder ) const
131 if ( aDateModified > rIsOlder.aDateModified )
132 return TRUE;
133 if ( ( aDateModified == rIsOlder.aDateModified ) &&
134 ( aTimeModified > rIsOlder.aTimeModified ) )
135 return TRUE;
137 return FALSE;
140 /*************************************************************************
142 |* FileStat::IsKind()
144 |* Ersterstellung MA 11.11.91 (?)
145 |* Letzte Aenderung KH 16.01.95
147 *************************************************************************/
149 BOOL FileStat::IsKind( DirEntryKind nKind ) const
151 BOOL bRet = ( ( nKind == FSYS_KIND_UNKNOWN ) &&
152 ( nKindFlags == FSYS_KIND_UNKNOWN ) ) ||
153 ( ( nKindFlags & nKind ) == nKind );
154 return bRet;
157 /*************************************************************************
159 |* FileStat::HasReadOnlyFlag()
161 |* Ersterstellung MI 06.03.97
162 |* Letzte Aenderung UT 01.07.98
164 *************************************************************************/
166 BOOL FileStat::HasReadOnlyFlag()
168 #if defined WNT || defined UNX || defined OS2
169 return TRUE;
170 #else
171 return FALSE;
172 #endif
175 /*************************************************************************
177 |* FileStat::GetReadOnlyFlag()
179 |* Ersterstellung MI 06.03.97
180 |* Letzte Aenderung UT 02.07.98
182 *************************************************************************/
184 BOOL FileStat::GetReadOnlyFlag( const DirEntry &rEntry )
187 ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
188 #if defined WNT
189 DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
190 return ULONG_MAX != nRes &&
191 ( FILE_ATTRIBUTE_READONLY & nRes ) == FILE_ATTRIBUTE_READONLY;
192 #elif defined OS2
193 FILESTATUS3 aFileStat;
194 APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
195 switch ( nRet )
197 case NO_ERROR:
198 return FILE_READONLY == ( aFileStat.attrFile & FILE_READONLY );
199 default:
200 return FALSE;
202 #elif defined UNX
203 /* could we stat the object? */
204 struct stat aBuf;
205 if (stat(aFPath.GetBuffer(), &aBuf))
206 return FALSE;
207 /* jupp, is writable for user? */
208 return((aBuf.st_mode & S_IWUSR) != S_IWUSR);
209 #else
210 return FALSE;
211 #endif
214 /*************************************************************************
216 |* FileStat::SetReadOnlyFlag()
218 |* Ersterstellung MI 06.03.97
219 |* Letzte Aenderung UT 01.07.98
221 *************************************************************************/
223 ULONG FileStat::SetReadOnlyFlag( const DirEntry &rEntry, BOOL bRO )
226 ByteString aFPath(rEntry.GetFull(), osl_getThreadTextEncoding());
228 #if defined WNT
229 DWORD nRes = GetFileAttributes( (LPCTSTR) aFPath.GetBuffer() );
230 if ( ULONG_MAX != nRes )
231 nRes = SetFileAttributes( (LPCTSTR) aFPath.GetBuffer(),
232 ( nRes & ~FILE_ATTRIBUTE_READONLY ) |
233 ( bRO ? FILE_ATTRIBUTE_READONLY : 0 ) );
234 return ( ULONG_MAX == nRes ) ? ERRCODE_IO_UNKNOWN : 0;
235 #elif defined OS2
236 FILESTATUS3 aFileStat;
237 APIRET nRet = DosQueryPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat) );
238 if ( !nRet )
240 aFileStat.attrFile = ( aFileStat.attrFile & ~FILE_READONLY ) |
241 ( bRO ? FILE_READONLY : 0 );
242 nRet = DosSetPathInfo( (PSZ)aFPath.GetBuffer(), 1, &aFileStat, sizeof(aFileStat), 0 );
244 switch ( nRet )
246 case NO_ERROR:
247 return ERRCODE_NONE;
249 case ERROR_SHARING_VIOLATION:
250 return ERRCODE_IO_LOCKVIOLATION;
252 default:
253 return ERRCODE_IO_NOTEXISTS;
255 #elif defined UNX
256 /* first, stat the object to get permissions */
257 struct stat aBuf;
258 if (stat(aFPath.GetBuffer(), &aBuf))
259 return ERRCODE_IO_NOTEXISTS;
260 /* set or clear write bit for user */
261 mode_t nMode;
262 if (bRO)
264 nMode = aBuf.st_mode & ~S_IWUSR;
265 nMode = aBuf.st_mode & ~S_IWGRP;
266 nMode = aBuf.st_mode & ~S_IWOTH;
268 else
269 nMode = aBuf.st_mode | S_IWUSR;
270 /* change it on fs */
271 if (chmod(aFPath.GetBuffer(), nMode))
273 switch (errno)
275 case EPERM :
276 case EROFS :
277 return ERRCODE_IO_ACCESSDENIED;
278 default :
279 return ERRCODE_IO_NOTEXISTS;
282 else
283 return ERRCODE_NONE;
284 #else
285 return ERRCODE_IO_NOTSUPPORTED;
286 #endif
289 /*************************************************************************
291 |* FileStat::SetDateTime
293 |* Ersterstellung PB 27.06.97
294 |* Letzte Aenderung
296 *************************************************************************/
297 #if defined WNT || defined OS2
299 void FileStat::SetDateTime( const String& rFileName,
300 const DateTime& rNewDateTime )
302 ByteString aFileName(rFileName, osl_getThreadTextEncoding());
304 Date aNewDate = rNewDateTime;
305 Time aNewTime = rNewDateTime;
307 #if defined WNT
308 TIME_ZONE_INFORMATION aTZI;
309 DWORD dwTZI = GetTimeZoneInformation( &aTZI );
311 if ( dwTZI != (DWORD)-1 && dwTZI != TIME_ZONE_ID_UNKNOWN )
313 // 1. Korrektur der Zeitzone
314 LONG nDiff = aTZI.Bias;
315 Time aOldTime = aNewTime; // alte Zeit merken
317 // 2. evt. Korrektur Sommer-/Winterzeit
318 if ( dwTZI == TIME_ZONE_ID_DAYLIGHT )
319 nDiff += aTZI.DaylightBias;
321 Time aDiff( abs( nDiff / 60 /*Min -> Std*/ ), 0 );
323 if ( nDiff > 0 )
325 aNewTime += aDiff; // Stundenkorrektur
327 // bei "Uberlauf korrigieren
328 if ( aNewTime >= Time( 24, 0 ) )
329 aNewTime -= Time( 24, 0 );
331 // Tages"uberlauf?
332 if ( aOldTime == Time( 0, 0 ) || // 00:00 -> 01:00
333 aNewTime < aOldTime ) // 23:00 -> 00:00 | 01:00 ...
334 aNewDate++;
336 else if ( nDiff < 0 )
338 aNewTime -= aDiff; // Stundenkorrektur
340 // negative Zeit (-1:00) korrigieren: 23:00
341 if (aNewTime < Time( 0, 0 ) )
342 aNewTime += Time( 24, 0 );
344 // Tagesunterlauf ?
345 if ( aOldTime == Time( 0, 0 ) || // 00:00 -> 23:00
346 aNewTime > aOldTime ) // 01:00 -> 23:00 | 22:00 ...
347 aNewDate--;
352 SYSTEMTIME aTime;
353 aTime.wYear = aNewDate.GetYear();
354 aTime.wMonth = aNewDate.GetMonth();
355 aTime.wDayOfWeek = 0;
356 aTime.wDay = aNewDate.GetDay();
357 aTime.wHour = aNewTime.GetHour();
358 aTime.wMinute = aNewTime.GetMin();
359 aTime.wSecond = aNewTime.GetSec();
360 aTime.wMilliseconds = 0;
361 FILETIME aFileTime;
362 SystemTimeToFileTime( &aTime, &aFileTime );
364 HANDLE hFile = CreateFile( aFileName.GetBuffer(), GENERIC_WRITE, 0, 0,
365 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
367 if ( hFile != INVALID_HANDLE_VALUE )
369 SetFileTime( hFile, &aFileTime, &aFileTime, &aFileTime );
370 CloseHandle( hFile );
372 #elif defined OS2
374 // open file
375 ULONG nAction = FILE_EXISTED;
376 HFILE hFile = 0;
377 ULONG nFlags = OPEN_FLAGS_WRITE_THROUGH |
378 OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE |
379 OPEN_FLAGS_RANDOM | OPEN_FLAGS_NOINHERIT |
380 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE;
382 APIRET nRet = DosOpen((PSZ)aFileName.GetBuffer(), &hFile, (PULONG)&nAction,
383 0/*size*/, FILE_NORMAL,
384 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
385 nFlags, 0/*ea*/);
387 if ( nRet == 0 )
389 FILESTATUS3 FileInfoBuffer;
391 nRet = DosQueryFileInfo(
392 hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
394 if ( nRet == 0 )
396 FDATE aNewDate;
397 FTIME aNewTime;
399 // create date and time words
400 aNewDate.day = rNewDateTime.GetDay();
401 aNewDate.month = rNewDateTime.GetMonth();
402 aNewDate.year = rNewDateTime.GetYear() - 1980;
403 aNewTime.twosecs = rNewDateTime.GetSec() / 2;
404 aNewTime.minutes = rNewDateTime.GetMin();
405 aNewTime.hours = rNewDateTime.GetHour();
407 // set file date and time
408 FileInfoBuffer.fdateCreation = aNewDate;
409 FileInfoBuffer.ftimeCreation = aNewTime;
410 FileInfoBuffer.fdateLastAccess = aNewDate;
411 FileInfoBuffer.ftimeLastAccess = aNewTime;
412 FileInfoBuffer.fdateLastWrite = aNewDate;
413 FileInfoBuffer.ftimeLastWrite = aNewTime;
415 DosSetFileInfo(hFile, 1, &FileInfoBuffer, sizeof(FileInfoBuffer));
417 DosClose(hFile);
419 #endif
422 #endif