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