xref: /aoo4110/main/tools/source/fsys/fstat.cxx (revision b1cdbd2c)
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