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 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 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 117 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 137 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 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 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 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 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