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